Compare commits
61 Commits
version/20
...
version/20
| Author | SHA1 | Date | |
|---|---|---|---|
| 276d8fe5cf | |||
| 92ce5f0931 | |||
| 7fea20375f | |||
| d4d4034d2c | |||
| f0db408699 | |||
| 5e200655d9 | |||
| d5d1f2a645 | |||
| cc5cc43baa | |||
| e512f085db | |||
| f323c01bd8 | |||
| f56cacb406 | |||
| eaecd31e9f | |||
| 36989d82e1 | |||
| 50777d9022 | |||
| a15571bd3e | |||
| 26fd66d831 | |||
| 0be873025a | |||
| 28ada49910 | |||
| 4fc8e61f8c | |||
| 7d26ea1a9c | |||
| 3a58dc62e1 | |||
| 71fe7bc827 | |||
| 933336c38b | |||
| 371feb9a31 | |||
| 95a2fd3c9e | |||
| 17cb76c334 | |||
| 88f0dfc8cc | |||
| f82aada23b | |||
| ecaee92634 | |||
| 89252ec47b | |||
| f0f25ab291 | |||
| e4d0fec15a | |||
| 6b10baf086 | |||
| f148b5d341 | |||
| 1471ff8940 | |||
| d9a6ec2ac0 | |||
| 5745ffa0a8 | |||
| b26202db35 | |||
| 6318577a51 | |||
| 6a2cd45847 | |||
| ef5cea2c01 | |||
| 69f4d54bae | |||
| b1eec5a7d2 | |||
| 1b8271d767 | |||
| 3e9f5ec5ef | |||
| 63f57b6a77 | |||
| a016f99450 | |||
| adc18b2991 | |||
| e37a326b95 | |||
| 048467e97d | |||
| cc2cd6919f | |||
| 0c6e781e5b | |||
| 7294d8fca5 | |||
| 16ec5680b4 | |||
| 87920fb1d7 | |||
| 523b96a6d2 | |||
| 45731d8069 | |||
| e872371970 | |||
| 08e8cf850a | |||
| b1ed2154ac | |||
| 7ef2aa3eb9 |
@ -1,5 +1,5 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 2021.8.3
|
current_version = 2021.8.4
|
||||||
tag = True
|
tag = True
|
||||||
commit = True
|
commit = True
|
||||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*)
|
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*)
|
||||||
@ -23,7 +23,7 @@ values =
|
|||||||
|
|
||||||
[bumpversion:file:schema.yml]
|
[bumpversion:file:schema.yml]
|
||||||
|
|
||||||
[bumpversion:file:.github/workflows/release.yml]
|
[bumpversion:file:.github/workflows/release-publish.yml]
|
||||||
|
|
||||||
[bumpversion:file:authentik/__init__.py]
|
[bumpversion:file:authentik/__init__.py]
|
||||||
|
|
||||||
|
|||||||
240
.github/workflows/ci-main.yml
vendored
Normal file
240
.github/workflows/ci-main.yml
vendored
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
name: authentik-ci-main
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- website
|
||||||
|
|
||||||
|
env:
|
||||||
|
POSTGRES_DB: authentik
|
||||||
|
POSTGRES_USER: authentik
|
||||||
|
POSTGRES_PASSWORD: "EK-5jnKfjrGRm<77"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-pylint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- name: run pylint
|
||||||
|
run: pipenv run pylint authentik tests lifecycle
|
||||||
|
lint-black:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- name: run black
|
||||||
|
run: pipenv run black --check authentik tests lifecycle
|
||||||
|
lint-isort:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- name: run isort
|
||||||
|
run: pipenv run isort --check authentik tests lifecycle
|
||||||
|
lint-bandit:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- name: run bandit
|
||||||
|
run: pipenv run bandit -r authentik tests lifecycle
|
||||||
|
lint-pyright:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
- name: prepare
|
||||||
|
run: |
|
||||||
|
scripts/ci_prepare.sh
|
||||||
|
npm install -g pyright@1.1.136
|
||||||
|
- name: run bandit
|
||||||
|
run: pipenv run pyright e2e lifecycle
|
||||||
|
test-migrations:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- name: run migrations
|
||||||
|
run: pipenv run python -m lifecycle.migrate
|
||||||
|
test-migrations-from-stable:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: checkout stable
|
||||||
|
run: |
|
||||||
|
# Copy current, latest config to local
|
||||||
|
cp authentik/lib/default.yml local.env.yml
|
||||||
|
git checkout $(git describe --abbrev=0 --match 'version/*')
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- name: run migrations to stable
|
||||||
|
run: pipenv run python -m lifecycle.migrate
|
||||||
|
- name: checkout current code
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
git checkout $GITHUB_REF
|
||||||
|
pipenv sync --dev
|
||||||
|
- name: migrate to latest
|
||||||
|
run: pipenv run python -m lifecycle.migrate
|
||||||
|
test-unittest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- uses: testspace-com/setup-testspace@v1
|
||||||
|
with:
|
||||||
|
domain: ${{github.repository_owner}}
|
||||||
|
- name: run unittest
|
||||||
|
run: |
|
||||||
|
pipenv run make test
|
||||||
|
pipenv run coverage xml
|
||||||
|
- name: run testspace
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
testspace unittest.xml ?add
|
||||||
|
- if: ${{ always() }}
|
||||||
|
uses: codecov/codecov-action@v2
|
||||||
|
test-integration:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- name: prepare
|
||||||
|
run: scripts/ci_prepare.sh
|
||||||
|
- uses: testspace-com/setup-testspace@v1
|
||||||
|
with:
|
||||||
|
domain: ${{github.repository_owner}}
|
||||||
|
- name: prepare k3d
|
||||||
|
run: |
|
||||||
|
wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
|
||||||
|
- name: run integration
|
||||||
|
run: |
|
||||||
|
pipenv run make test-integration
|
||||||
|
pipenv run coverage xml
|
||||||
|
- name: run testspace
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
testspace unittest.xml ?add
|
||||||
|
- if: ${{ always() }}
|
||||||
|
uses: codecov/codecov-action@v2
|
||||||
|
test-e2e:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: web/package-lock.json
|
||||||
|
- uses: testspace-com/setup-testspace@v1
|
||||||
|
with:
|
||||||
|
domain: ${{github.repository_owner}}
|
||||||
|
- name: prepare
|
||||||
|
run: |
|
||||||
|
scripts/ci_prepare.sh
|
||||||
|
docker-compose -f tests/e2e/ci.docker-compose.yml up -d
|
||||||
|
- name: prepare web ui
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
npm i
|
||||||
|
npm run build
|
||||||
|
- name: run e2e
|
||||||
|
run: |
|
||||||
|
pipenv run make test-e2e
|
||||||
|
pipenv run coverage xml
|
||||||
|
- name: run testspace
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
testspace unittest.xml ?add
|
||||||
|
- if: ${{ always() }}
|
||||||
|
uses: codecov/codecov-action@v2
|
||||||
|
report:
|
||||||
|
if: ${{ always() }}
|
||||||
|
needs:
|
||||||
|
- test-unittest
|
||||||
|
- test-integration
|
||||||
|
- test-e2e
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: testspace-com/setup-testspace@v1
|
||||||
|
with:
|
||||||
|
domain: ${{github.repository_owner}}
|
||||||
|
- name: finish testspace
|
||||||
|
run: |
|
||||||
|
testspace ?finish
|
||||||
|
build:
|
||||||
|
needs:
|
||||||
|
- lint-pylint
|
||||||
|
- lint-black
|
||||||
|
- lint-isort
|
||||||
|
- lint-bandit
|
||||||
|
- lint-pyright
|
||||||
|
- test-migrations
|
||||||
|
- test-migrations-from-stable
|
||||||
|
- test-unittest
|
||||||
|
- test-integration
|
||||||
|
- test-e2e
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
- name: prepare variables
|
||||||
|
id: ev
|
||||||
|
run: |
|
||||||
|
python ./scripts/gh_do_set_branch.py
|
||||||
|
- name: Login to Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||||
|
with:
|
||||||
|
registry: beryju.org
|
||||||
|
username: ${{ secrets.HARBOR_USERNAME }}
|
||||||
|
password: ${{ secrets.HARBOR_PASSWORD }}
|
||||||
|
- name: Building Docker Image
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
push: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||||
|
tags: |
|
||||||
|
beryju.org/authentik/server:gh-${{ steps.ev.outputs.branchName }}
|
||||||
|
beryju.org/authentik/server:gh-${{ steps.ev.outputs.branchName }}-${{ steps.ev.outputs.timestamp }}
|
||||||
|
build-args: |
|
||||||
|
GIT_BUILD_HASH=${{ steps.ev.outputs.sha }}
|
||||||
66
.github/workflows/ci-outpost.yml
vendored
Normal file
66
.github/workflows/ci-outpost.yml
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
name: authentik-ci-outpost
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-golint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '^1.16.3'
|
||||||
|
- name: Generate API
|
||||||
|
run: |
|
||||||
|
make gen-outpost
|
||||||
|
- name: Run linter
|
||||||
|
run: |
|
||||||
|
# Create folder structure for go embeds
|
||||||
|
mkdir -p web/dist
|
||||||
|
mkdir -p website/help
|
||||||
|
touch web/dist/test website/help/test
|
||||||
|
docker run \
|
||||||
|
--rm \
|
||||||
|
-v $(pwd):/app \
|
||||||
|
-w /app \
|
||||||
|
golangci/golangci-lint:v1.39.0 \
|
||||||
|
golangci-lint run -v --timeout 200s
|
||||||
|
build:
|
||||||
|
needs:
|
||||||
|
- lint-golint
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
type:
|
||||||
|
- proxy
|
||||||
|
- ldap
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1.2.0
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
- name: prepare variables
|
||||||
|
id: ev
|
||||||
|
run: |
|
||||||
|
python ./scripts/gh_do_set_branch.py
|
||||||
|
- name: Login to Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||||
|
with:
|
||||||
|
registry: beryju.org
|
||||||
|
username: ${{ secrets.HARBOR_USERNAME }}
|
||||||
|
password: ${{ secrets.HARBOR_PASSWORD }}
|
||||||
|
- name: Building Docker Image
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
push: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||||
|
tags: |
|
||||||
|
beryju.org/authentik/outpost-${{ matrix.type }}:gh-${{ steps.ev.outputs.branchName }}
|
||||||
|
beryju.org/authentik/outpost-${{ matrix.type }}:gh-${{ steps.ev.outputs.branchName }}-${{ steps.ev.outputs.timestamp }}
|
||||||
|
beryju.org/authentik/outpost-${{ matrix.type }}:gh-${{ steps.ev.outputs.sha }}
|
||||||
|
file: ${{ matrix.type }}.Dockerfile
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
build-args: |
|
||||||
|
GIT_BUILD_HASH=${{ steps.ev.outputs.sha }}
|
||||||
82
.github/workflows/ci-web.yml
vendored
Normal file
82
.github/workflows/ci-web.yml
vendored
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
name: authentik-ci-web
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint-eslint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: web/package-lock.json
|
||||||
|
- run: |
|
||||||
|
cd web
|
||||||
|
npm install
|
||||||
|
- name: Generate API
|
||||||
|
run: make gen-web
|
||||||
|
- name: Eslint
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
npm run lint
|
||||||
|
lint-prettier:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: web/package-lock.json
|
||||||
|
- run: |
|
||||||
|
cd web
|
||||||
|
npm install
|
||||||
|
- name: Generate API
|
||||||
|
run: make gen-web
|
||||||
|
- name: prettier
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
npm run prettier-check
|
||||||
|
lint-lit-analyse:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: web/package-lock.json
|
||||||
|
- run: |
|
||||||
|
cd web
|
||||||
|
npm install
|
||||||
|
- name: Generate API
|
||||||
|
run: make gen-web
|
||||||
|
- name: prettier
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
npm run lit-analyse
|
||||||
|
build:
|
||||||
|
needs:
|
||||||
|
- lint-eslint
|
||||||
|
- lint-prettier
|
||||||
|
- lint-lit-analyse
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: '16'
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: web/package-lock.json
|
||||||
|
- run: |
|
||||||
|
cd web
|
||||||
|
npm install
|
||||||
|
- name: Generate API
|
||||||
|
run: make gen-web
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
npm run build
|
||||||
@ -33,14 +33,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
push: ${{ github.event_name == 'release' }}
|
push: ${{ github.event_name == 'release' }}
|
||||||
tags: |
|
tags: |
|
||||||
beryju/authentik:2021.8.3,
|
beryju/authentik:2021.8.4,
|
||||||
beryju/authentik:latest,
|
beryju/authentik:latest,
|
||||||
ghcr.io/goauthentik/server:2021.8.3,
|
ghcr.io/goauthentik/server:2021.8.4,
|
||||||
ghcr.io/goauthentik/server:latest
|
ghcr.io/goauthentik/server:latest
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
context: .
|
context: .
|
||||||
- name: Building Docker Image (stable)
|
- name: Building Docker Image (stable)
|
||||||
if: ${{ github.event_name == 'release' && !contains('2021.8.3', 'rc') }}
|
if: ${{ github.event_name == 'release' && !contains('2021.8.4', 'rc') }}
|
||||||
run: |
|
run: |
|
||||||
docker pull beryju/authentik:latest
|
docker pull beryju/authentik:latest
|
||||||
docker tag beryju/authentik:latest beryju/authentik:stable
|
docker tag beryju/authentik:latest beryju/authentik:stable
|
||||||
@ -75,14 +75,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
push: ${{ github.event_name == 'release' }}
|
push: ${{ github.event_name == 'release' }}
|
||||||
tags: |
|
tags: |
|
||||||
beryju/authentik-proxy:2021.8.3,
|
beryju/authentik-proxy:2021.8.4,
|
||||||
beryju/authentik-proxy:latest,
|
beryju/authentik-proxy:latest,
|
||||||
ghcr.io/goauthentik/proxy:2021.8.3,
|
ghcr.io/goauthentik/proxy:2021.8.4,
|
||||||
ghcr.io/goauthentik/proxy:latest
|
ghcr.io/goauthentik/proxy:latest
|
||||||
file: proxy.Dockerfile
|
file: proxy.Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
- name: Building Docker Image (stable)
|
- name: Building Docker Image (stable)
|
||||||
if: ${{ github.event_name == 'release' && !contains('2021.8.3', 'rc') }}
|
if: ${{ github.event_name == 'release' && !contains('2021.8.4', 'rc') }}
|
||||||
run: |
|
run: |
|
||||||
docker pull beryju/authentik-proxy:latest
|
docker pull beryju/authentik-proxy:latest
|
||||||
docker tag beryju/authentik-proxy:latest beryju/authentik-proxy:stable
|
docker tag beryju/authentik-proxy:latest beryju/authentik-proxy:stable
|
||||||
@ -117,14 +117,14 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
push: ${{ github.event_name == 'release' }}
|
push: ${{ github.event_name == 'release' }}
|
||||||
tags: |
|
tags: |
|
||||||
beryju/authentik-ldap:2021.8.3,
|
beryju/authentik-ldap:2021.8.4,
|
||||||
beryju/authentik-ldap:latest,
|
beryju/authentik-ldap:latest,
|
||||||
ghcr.io/goauthentik/ldap:2021.8.3,
|
ghcr.io/goauthentik/ldap:2021.8.4,
|
||||||
ghcr.io/goauthentik/ldap:latest
|
ghcr.io/goauthentik/ldap:latest
|
||||||
file: ldap.Dockerfile
|
file: ldap.Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
- name: Building Docker Image (stable)
|
- name: Building Docker Image (stable)
|
||||||
if: ${{ github.event_name == 'release' && !contains('2021.8.3', 'rc') }}
|
if: ${{ github.event_name == 'release' && !contains('2021.8.4', 'rc') }}
|
||||||
run: |
|
run: |
|
||||||
docker pull beryju/authentik-ldap:latest
|
docker pull beryju/authentik-ldap:latest
|
||||||
docker tag beryju/authentik-ldap:latest beryju/authentik-ldap:stable
|
docker tag beryju/authentik-ldap:latest beryju/authentik-ldap:stable
|
||||||
@ -175,7 +175,7 @@ jobs:
|
|||||||
SENTRY_PROJECT: authentik
|
SENTRY_PROJECT: authentik
|
||||||
SENTRY_URL: https://sentry.beryju.org
|
SENTRY_URL: https://sentry.beryju.org
|
||||||
with:
|
with:
|
||||||
version: authentik@2021.8.3
|
version: authentik@2021.8.4
|
||||||
environment: beryjuorg-prod
|
environment: beryjuorg-prod
|
||||||
sourcemaps: './web/dist'
|
sourcemaps: './web/dist'
|
||||||
url_prefix: '~/static/dist'
|
url_prefix: '~/static/dist'
|
||||||
156
Pipfile.lock
generated
156
Pipfile.lock
generated
@ -122,19 +122,19 @@
|
|||||||
},
|
},
|
||||||
"boto3": {
|
"boto3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:542336dda9a728c250cf24aea6d87454136d9d6f3d8a84ec5a737a7edba3b932",
|
"sha256:5116e9bdec19adcc5531a9b7b535be77d5314eef092aaf7033ace48a9be65036",
|
||||||
"sha256:9bf2a281a6df9f8948d3d322d532d03a1039f57a049a1aa2b72b4a28c9627013"
|
"sha256:658ddf4ba552f654fd4d48335fa95ff4e3e1a4e82f90021a1a1d3de4a5428ba4"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==1.18.30"
|
"version": "==1.18.34"
|
||||||
},
|
},
|
||||||
"botocore": {
|
"botocore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:26ab09126dd05c968fbbcb894a1d623355e6119ff6d4a2bf5d292e3ad7cdd628",
|
"sha256:1b4999fb0e1a4c050c4d9118ebdaac8d83761ef32c3c0f13a25f9204045998fe",
|
||||||
"sha256:9b0b3dbc144178e2b803097abcc95712a03b8dde5a02e4335ac870bc6c129dd9"
|
"sha256:ec2cdf1c8ed64a7f392f352125d248c76103fa9d137b275b7c76836776cedf56"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.6'",
|
"markers": "python_version >= '3.6'",
|
||||||
"version": "==1.21.30"
|
"version": "==1.21.34"
|
||||||
},
|
},
|
||||||
"cachetools": {
|
"cachetools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -359,11 +359,11 @@
|
|||||||
},
|
},
|
||||||
"django": {
|
"django": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:7f92413529aa0e291f3be78ab19be31aefb1e1c9a52cd59e130f505f27a51f13",
|
"sha256:95b318319d6997bac3595517101ad9cc83fe5672ac498ba48d1a410f47afecd2",
|
||||||
"sha256:f27f8544c9d4c383bbe007c57e3235918e258364577373d4920e9162837be022"
|
"sha256:e93c93565005b37ddebf2396b4dc4b6913c1838baa82efdfb79acedd5816c240"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.2.6"
|
"version": "==3.2.7"
|
||||||
},
|
},
|
||||||
"django-dbbackup": {
|
"django-dbbackup": {
|
||||||
"git": "https://github.com/django-dbbackup/django-dbbackup.git",
|
"git": "https://github.com/django-dbbackup/django-dbbackup.git",
|
||||||
@ -443,19 +443,19 @@
|
|||||||
},
|
},
|
||||||
"docker": {
|
"docker": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:3e8bc47534e0ca9331d72c32f2881bb13b93ded0bcdeab3c833fb7cf61c0a9a5",
|
"sha256:5aafaec0d2a1de0e32010b43b5eac9f6f851c9db99a46ad32b8e44eeeb55616d",
|
||||||
"sha256:fc961d622160e8021c10d1bcabc388c57d55fb1f917175afbe24af442e6879bd"
|
"sha256:b88eef725b33c0ed59c67506631bbb09b480b7ca5a739bbbb948b446443fe914"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==5.0.0"
|
"version": "==5.0.1"
|
||||||
},
|
},
|
||||||
"drf-spectacular": {
|
"drf-spectacular": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:5b1c27de127c86564be5a967a6fa195cfe161b552d98364282ae9e6ed3d75a85",
|
"sha256:98681add6671db9e6dba5f0d3dcf8aab5950cbb978497390507356e593bf082f",
|
||||||
"sha256:8588706c27f44adfbb3405bae9ef9cd6506f4b59d4cbd66c59780dce035602d9"
|
"sha256:a430bab0f4ecfc90786b7b63bbee3f9a56094201fbed9bdfbf952e99e6469104"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==0.18.0"
|
"version": "==0.18.1"
|
||||||
},
|
},
|
||||||
"duo-client": {
|
"duo-client": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -490,11 +490,11 @@
|
|||||||
},
|
},
|
||||||
"google-auth": {
|
"google-auth": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:c012c8be7c442c8309ca8fa0876fef33f5fd977c467be1e1c1c2f721e8ebd73c",
|
"sha256:104475dc4d57bbae49017aea16fffbb763204fa2d6a70f1f3cc79962c1a383a4",
|
||||||
"sha256:ea1af050b3e06eb73e4470f704d23007307bc0e87c13e015f6b90460f1407bd3"
|
"sha256:cde472372e030e1e0bc64dac00fb53e6c095d7ab641f4281e2c995e85e205d8b"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.6'",
|
"markers": "python_version >= '3.6'",
|
||||||
"version": "==2.0.1"
|
"version": "==2.0.2"
|
||||||
},
|
},
|
||||||
"gunicorn": {
|
"gunicorn": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -1151,11 +1151,11 @@
|
|||||||
},
|
},
|
||||||
"typing-extensions": {
|
"typing-extensions": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497",
|
"sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e",
|
||||||
"sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342",
|
"sha256:d8226d10bc02a29bcc81df19a26e56a9647f8b0a6d4a83924139f4a8b01f17b7",
|
||||||
"sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"
|
"sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"
|
||||||
],
|
],
|
||||||
"version": "==3.10.0.0"
|
"version": "==3.10.0.2"
|
||||||
},
|
},
|
||||||
"ua-parser": {
|
"ua-parser": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -1420,11 +1420,11 @@
|
|||||||
},
|
},
|
||||||
"astroid": {
|
"astroid": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:b6c2d75cd7c2982d09e7d41d70213e863b3ba34d3bd4014e08f167cee966e99e",
|
"sha256:3b680ce0419b8a771aba6190139a3998d14b413852506d99aff8dc2bf65ee67c",
|
||||||
"sha256:ecc50f9b3803ebf8ea19aa2c6df5622d8a5c31456a53c741d3be044d96ff0948"
|
"sha256:dc1e8b28427d6bbef6b8842b18765ab58f558c42bb80540bd7648c98412af25e"
|
||||||
],
|
],
|
||||||
"markers": "python_version ~= '3.6'",
|
"markers": "python_version ~= '3.6'",
|
||||||
"version": "==2.7.2"
|
"version": "==2.7.3"
|
||||||
},
|
},
|
||||||
"attrs": {
|
"attrs": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -1582,7 +1582,7 @@
|
|||||||
"sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899",
|
"sha256:9c2ea1e62d871267b78307fe511c0838ba0da28698c5732d54e2790bf3ba9899",
|
||||||
"sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"
|
"sha256:e17d6e2b81095c9db0a03a8025a957f334d6ea30b26f9ec70805411e5c7c81f2"
|
||||||
],
|
],
|
||||||
"markers": "python_version < '4.0' and python_full_version >= '3.6.1'",
|
"markers": "python_version < '4' and python_full_version >= '3.6.1'",
|
||||||
"version": "==5.9.3"
|
"version": "==5.9.3"
|
||||||
},
|
},
|
||||||
"lazy-object-proxy": {
|
"lazy-object-proxy": {
|
||||||
@ -1652,19 +1652,19 @@
|
|||||||
},
|
},
|
||||||
"platformdirs": {
|
"platformdirs": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:4666d822218db6a262bdfdc9c39d21f23b4cfdb08af331a81e92751daf6c866c",
|
"sha256:15b056538719b1c94bdaccb29e5f81879c7f7f0f4a153f46086d155dffcd4f0f",
|
||||||
"sha256:632daad3ab546bd8e6af0537d09805cec458dce201bccfe23012df73332e181e"
|
"sha256:8003ac87717ae2c7ee1ea5a84a1a61e87f3fbd16eb5aadba194ea30a9019f648"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.6'",
|
"markers": "python_version >= '3.6'",
|
||||||
"version": "==2.2.0"
|
"version": "==2.3.0"
|
||||||
},
|
},
|
||||||
"pluggy": {
|
"pluggy": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0",
|
"sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159",
|
||||||
"sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"
|
"sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
|
"markers": "python_version >= '3.6'",
|
||||||
"version": "==0.13.1"
|
"version": "==1.0.0"
|
||||||
},
|
},
|
||||||
"py": {
|
"py": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -1707,11 +1707,11 @@
|
|||||||
},
|
},
|
||||||
"pytest": {
|
"pytest": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b",
|
"sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89",
|
||||||
"sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890"
|
"sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==6.2.4"
|
"version": "==6.2.5"
|
||||||
},
|
},
|
||||||
"pytest-django": {
|
"pytest-django": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@ -1758,49 +1758,49 @@
|
|||||||
},
|
},
|
||||||
"regex": {
|
"regex": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0696eb934dee723e3292056a2c046ddb1e4dd3887685783a9f4af638e85dee76",
|
"sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468",
|
||||||
"sha256:105122fa63da98d8456d5026bc6ac5a1399fd82fa6bad22c6ea641b1572c9142",
|
"sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354",
|
||||||
"sha256:116c277774f84266044e889501fe79cfd293a8b4336b7a5e89b9f20f1e5a9f21",
|
"sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308",
|
||||||
"sha256:12eaf0bbe568bd62e6cade7937e0bf01a2a4cef49a82f4fd204401e78409e158",
|
"sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d",
|
||||||
"sha256:1401cfa4320691cbd91191ec678735c727dee674d0997b0902a5a38ad482faf5",
|
"sha256:1413b5022ed6ac0d504ba425ef02549a57d0f4276de58e3ab7e82437892704fc",
|
||||||
"sha256:19acdb8831a4e3b03b23369db43178d8fee1f17b99c83af6cd907886f76bd9d4",
|
"sha256:1743345e30917e8c574f273f51679c294effba6ad372db1967852f12c76759d8",
|
||||||
"sha256:208851a2f8dd31e468f0b5aa6c94433975bd67a107a4e7da3bdda947c9f85e25",
|
"sha256:28fc475f560d8f67cc8767b94db4c9440210f6958495aeae70fac8faec631797",
|
||||||
"sha256:24d68499a27b2d93831fde4a9b84ea5b19e0ab141425fbc9ab1e5b4dad179df7",
|
"sha256:31a99a4796bf5aefc8351e98507b09e1b09115574f7c9dbb9cf2111f7220d2e2",
|
||||||
"sha256:2778c6cb379d804e429cc8e627392909e60db5152b42c695c37ae5757aae50ae",
|
"sha256:328a1fad67445550b982caa2a2a850da5989fd6595e858f02d04636e7f8b0b13",
|
||||||
"sha256:2a0a5e323cf86760784ce2b91d8ab5ea09d0865d6ef4da0151e03d15d097b24e",
|
"sha256:473858730ef6d6ff7f7d5f19452184cd0caa062a20047f6d6f3e135a4648865d",
|
||||||
"sha256:2d9cbe0c755ab8b6f583169c0783f7278fc6b195e423b09c5a8da6f858025e96",
|
"sha256:4cde065ab33bcaab774d84096fae266d9301d1a2f5519d7bd58fc55274afbf7a",
|
||||||
"sha256:2de1429e4eeab799c168a4f6e6eecdf30fcaa389bba4039cc8a065d6b7aad647",
|
"sha256:5f6a808044faae658f546dd5f525e921de9fa409de7a5570865467f03a626fc0",
|
||||||
"sha256:32753eda8d413ce4f208cfe01dd61171a78068a6f5d5f38ccd751e00585cdf1d",
|
"sha256:610b690b406653c84b7cb6091facb3033500ee81089867ee7d59e675f9ca2b73",
|
||||||
"sha256:3ee8ad16a35c45a5bab098e39020ecb6fec3b0e700a9d88983d35cbabcee79c8",
|
"sha256:66256b6391c057305e5ae9209941ef63c33a476b73772ca967d4a2df70520ec1",
|
||||||
"sha256:4f03fc0a25122cdcbf39136510d4ea7627f732206892db522adf510bc03b8c67",
|
"sha256:6eebf512aa90751d5ef6a7c2ac9d60113f32e86e5687326a50d7686e309f66ed",
|
||||||
"sha256:4f3e36086d6631ceaf468503f96a3be0d247caef0660c9452fb1b0c055783851",
|
"sha256:79aef6b5cd41feff359acaf98e040844613ff5298d0d19c455b3d9ae0bc8c35a",
|
||||||
"sha256:503c1ba0920a46a1844363725215ef44d59fcac2bd2c03ae3c59aa9d08d29bd6",
|
"sha256:808ee5834e06f57978da3e003ad9d6292de69d2bf6263662a1a8ae30788e080b",
|
||||||
"sha256:507861cf3d97a86fbe26ea6cc04660ae028b9e4080b8290e28b99547b4e15d89",
|
"sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f",
|
||||||
"sha256:56ae6e3cf0506ec0c40b466e31f41ee7a7149a2b505ae0ee50edd9043b423d27",
|
"sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256",
|
||||||
"sha256:6530b7b9505123cdea40a2301225183ca65f389bc6129f0c225b9b41680268d8",
|
"sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb",
|
||||||
"sha256:6729914dd73483cd1c8aaace3ac082436fc98b0072743ac136eaea0b3811d42f",
|
"sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2",
|
||||||
"sha256:7406dd2e44c7cfb4680c0a45a03264381802c67890cf506c147288f04c67177d",
|
"sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983",
|
||||||
"sha256:7684016b73938ca12d160d2907d141f06b7597bd17d854e32bb7588be01afa1d",
|
"sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb",
|
||||||
"sha256:7db58ad61f3f6ea393aaf124d774ee0c58806320bc85c06dc9480f5c7219c250",
|
"sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645",
|
||||||
"sha256:83946ca9278b304728b637bc8d8200ab1663a79de85e47724594917aeed0e892",
|
"sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8",
|
||||||
"sha256:84057cfae5676f456b03970eb78b7e182fddc80c2daafd83465a3d6ca9ff8dbf",
|
"sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a",
|
||||||
"sha256:862b6164e9a38b5c495be2c2854e75fd8af12c5be4c61dc9b42d255980d7e907",
|
"sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906",
|
||||||
"sha256:8ddb4f9ce6bb388ecc97b4b3eb37e786f05d7d5815e8822e0d87a3dbd7100649",
|
"sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f",
|
||||||
"sha256:92eb03f47427fea452ff6956d11f5d5a3f22a048c90a0f34fa223e6badab6c85",
|
"sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c",
|
||||||
"sha256:a5f3bc727fea58f21d99c22e6d4fca652dc11dbc2a1e7cfc4838cd53b2e3691f",
|
"sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892",
|
||||||
"sha256:a6180dbf5945b27e9420e1b58c3cacfc79ad5278bdad3ea35109f5680fbe16d1",
|
"sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0",
|
||||||
"sha256:b158f673ae6a6523f13704f70aa7e4ce875f91e379bece4362c89db18db189d5",
|
"sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e",
|
||||||
"sha256:cd45b4542134de63e7b9dd653e0a2d7d47ffed9615e3637c27ca5f6b78ea68bb",
|
"sha256:d5111d4c843d80202e62b4fdbb4920db1dcee4f9366d6b03294f45ed7b18b42e",
|
||||||
"sha256:d2404336fd16788ea757d4218a2580de60adb052d9888031e765320be8884309",
|
"sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed",
|
||||||
"sha256:db888d4fb33a2fd54b57ac55d5015e51fa849f0d8592bd799b4e47f83bd04e00",
|
"sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c",
|
||||||
"sha256:dde0ac721c7c5bfa5f9fc285e811274dec3c392f2c1225f7d07ca98a8187ca84",
|
"sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374",
|
||||||
"sha256:de0d06ccbc06af5bf93bddec10f4f80275c5d74ea6d28b456931f3955f58bc8c",
|
"sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd",
|
||||||
"sha256:e02dad60e3e8442eefd28095e99b2ac98f2b8667167493ac6a2f3aadb5d84a17",
|
"sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791",
|
||||||
"sha256:e960fe211496333b2f7e36badf4c22a919d740386681f79139ee346b403d1ca1",
|
"sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a",
|
||||||
"sha256:e9700c52749cb3e90c98efd72b730c97b7e4962992fca5fbcaf1363be8e3b849",
|
"sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1",
|
||||||
"sha256:ee318974a1fdacba1701bc9e552e9015788d6345416364af6fa987424ff8df53"
|
"sha256:f60667673ff9c249709160529ab39667d1ae9fd38634e006bec95611f632e759"
|
||||||
],
|
],
|
||||||
"version": "==2021.8.27"
|
"version": "==2021.8.28"
|
||||||
},
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|||||||
@ -5,13 +5,14 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
[](https://discord.gg/jg33eMhnj6)
|
[](https://discord.gg/jg33eMhnj6)
|
||||||
[](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=6)
|

|
||||||
[](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=6)
|

|
||||||
|

|
||||||
[](https://codecov.io/gh/goauthentik/authentik)
|
[](https://codecov.io/gh/goauthentik/authentik)
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
[Transifex](https://www.transifex.com/beryjuorg/authentik/)
|
[](https://www.transifex.com/beryjuorg/authentik/)
|
||||||
|
|
||||||
## What is authentik?
|
## What is authentik?
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
"""authentik"""
|
"""authentik"""
|
||||||
__version__ = "2021.8.3"
|
__version__ = "2021.8.4"
|
||||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
"""authentik api urls"""
|
"""authentik api urls"""
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
||||||
from authentik.api.v2.urls import urlpatterns as v2_urls
|
from authentik.api.v3.urls import urlpatterns as v3_urls
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("v2beta/", include(v2_urls)),
|
# Remove in 2022.1
|
||||||
|
path("v2beta/", include(v3_urls)),
|
||||||
|
path("v3/", include(v3_urls)),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -4,16 +4,44 @@ from json import loads
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http.request import HttpRequest
|
from django.http.request import HttpRequest
|
||||||
from django.http.response import HttpResponse
|
from django.http.response import HttpResponse
|
||||||
from django.views.generic.base import View
|
|
||||||
from requests import post
|
from requests import post
|
||||||
from requests.exceptions import RequestException
|
from requests.exceptions import RequestException
|
||||||
|
from rest_framework.authentication import SessionAuthentication
|
||||||
|
from rest_framework.parsers import BaseParser
|
||||||
|
from rest_framework.permissions import AllowAny
|
||||||
|
from rest_framework.request import Request
|
||||||
|
from rest_framework.throttling import AnonRateThrottle
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
from authentik.lib.config import CONFIG
|
from authentik.lib.config import CONFIG
|
||||||
|
|
||||||
|
|
||||||
class SentryTunnelView(View):
|
class PlainTextParser(BaseParser):
|
||||||
|
"""Plain text parser."""
|
||||||
|
|
||||||
|
media_type = "text/plain"
|
||||||
|
|
||||||
|
def parse(self, stream, media_type=None, parser_context=None) -> str:
|
||||||
|
"""Simply return a string representing the body of the request."""
|
||||||
|
return stream.read()
|
||||||
|
|
||||||
|
|
||||||
|
class CsrfExemptSessionAuthentication(SessionAuthentication):
|
||||||
|
"""CSRF-exempt Session authentication"""
|
||||||
|
|
||||||
|
def enforce_csrf(self, request: Request):
|
||||||
|
return # To not perform the csrf check previously happening
|
||||||
|
|
||||||
|
|
||||||
|
class SentryTunnelView(APIView):
|
||||||
"""Sentry tunnel, to prevent ad blockers from blocking sentry"""
|
"""Sentry tunnel, to prevent ad blockers from blocking sentry"""
|
||||||
|
|
||||||
|
serializer_class = None
|
||||||
|
parser_classes = [PlainTextParser]
|
||||||
|
throttle_classes = [AnonRateThrottle]
|
||||||
|
permission_classes = [AllowAny]
|
||||||
|
authentication_classes = [CsrfExemptSessionAuthentication]
|
||||||
|
|
||||||
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||||
"""Sentry tunnel, to prevent ad blockers from blocking sentry"""
|
"""Sentry tunnel, to prevent ad blockers from blocking sentry"""
|
||||||
# Only allow usage of this endpoint when error reporting is enabled
|
# Only allow usage of this endpoint when error reporting is enabled
|
||||||
@ -1,4 +1,4 @@
|
|||||||
"""api v2 urls"""
|
"""api v3 urls"""
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from drf_spectacular.views import SpectacularAPIView
|
from drf_spectacular.views import SpectacularAPIView
|
||||||
@ -10,8 +10,8 @@ from authentik.admin.api.system import SystemView
|
|||||||
from authentik.admin.api.tasks import TaskViewSet
|
from authentik.admin.api.tasks import TaskViewSet
|
||||||
from authentik.admin.api.version import VersionView
|
from authentik.admin.api.version import VersionView
|
||||||
from authentik.admin.api.workers import WorkerView
|
from authentik.admin.api.workers import WorkerView
|
||||||
from authentik.api.v2.config import ConfigView
|
from authentik.api.v3.config import ConfigView
|
||||||
from authentik.api.v2.sentry import SentryTunnelView
|
from authentik.api.v3.sentry import SentryTunnelView
|
||||||
from authentik.api.views import APIBrowserView
|
from authentik.api.views import APIBrowserView
|
||||||
from authentik.core.api.applications import ApplicationViewSet
|
from authentik.core.api.applications import ApplicationViewSet
|
||||||
from authentik.core.api.authenticated_sessions import AuthenticatedSessionViewSet
|
from authentik.core.api.authenticated_sessions import AuthenticatedSessionViewSet
|
||||||
@ -23,7 +23,7 @@ from authentik.managed.api import ManagedSerializer
|
|||||||
class TokenSerializer(ManagedSerializer, ModelSerializer):
|
class TokenSerializer(ManagedSerializer, ModelSerializer):
|
||||||
"""Token Serializer"""
|
"""Token Serializer"""
|
||||||
|
|
||||||
user_obj = UserSerializer(required=False)
|
user_obj = UserSerializer(required=False, source="user")
|
||||||
|
|
||||||
def validate(self, attrs: dict[Any, str]) -> dict[Any, str]:
|
def validate(self, attrs: dict[Any, str]) -> dict[Any, str]:
|
||||||
"""Ensure only API or App password tokens are created."""
|
"""Ensure only API or App password tokens are created."""
|
||||||
|
|||||||
@ -11,6 +11,7 @@ from django.core.cache import cache
|
|||||||
from prometheus_client import Gauge
|
from prometheus_client import Gauge
|
||||||
|
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
|
from authentik.lib.utils.errors import exception_to_string
|
||||||
|
|
||||||
GAUGE_TASKS = Gauge(
|
GAUGE_TASKS = Gauge(
|
||||||
"authentik_system_tasks",
|
"authentik_system_tasks",
|
||||||
@ -174,9 +175,7 @@ class MonitoredTask(Task):
|
|||||||
).save(self.result_timeout_hours)
|
).save(self.result_timeout_hours)
|
||||||
Event.new(
|
Event.new(
|
||||||
EventAction.SYSTEM_TASK_EXCEPTION,
|
EventAction.SYSTEM_TASK_EXCEPTION,
|
||||||
message=(
|
message=(f"Task {self.__name__} encountered an error: {exception_to_string(exc)}"),
|
||||||
f"Task {self.__name__} encountered an error: " "\n".join(self._result.messages)
|
|
||||||
),
|
|
||||||
).save()
|
).save()
|
||||||
return super().on_failure(exc, task_id, args, kwargs, einfo=einfo)
|
return super().on_failure(exc, task_id, args, kwargs, einfo=einfo)
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ class FlowPlanProcess(PROCESS_CLASS): # pragma: no cover
|
|||||||
self.request = RequestFactory().get("/")
|
self.request = RequestFactory().get("/")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
"""Execute 1000 flow plans"""
|
||||||
print(f"Proc {self.index} Running")
|
print(f"Proc {self.index} Running")
|
||||||
|
|
||||||
def test_inner():
|
def test_inner():
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
# Generated by Django 3.2.6 on 2021-08-30 14:49
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_flows", "0023_alter_flow_background"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="flow",
|
||||||
|
name="compatibility_mode",
|
||||||
|
field=models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
help_text="Enable compatibility mode, increases compatibility with password managers on mobile devices.",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -125,7 +125,7 @@ class Flow(SerializerModel, PolicyBindingModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
compatibility_mode = models.BooleanField(
|
compatibility_mode = models.BooleanField(
|
||||||
default=True,
|
default=False,
|
||||||
help_text=_(
|
help_text=_(
|
||||||
"Enable compatibility mode, increases compatibility with "
|
"Enable compatibility mode, increases compatibility with "
|
||||||
"password managers on mobile devices."
|
"password managers on mobile devices."
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
from unittest.mock import MagicMock, PropertyMock, patch
|
from unittest.mock import MagicMock, PropertyMock, patch
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.test import TestCase
|
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -37,7 +37,7 @@ def to_stage_response(request: HttpRequest, source: HttpResponse):
|
|||||||
TO_STAGE_RESPONSE_MOCK = MagicMock(side_effect=to_stage_response)
|
TO_STAGE_RESPONSE_MOCK = MagicMock(side_effect=to_stage_response)
|
||||||
|
|
||||||
|
|
||||||
class TestFlowExecutor(TestCase):
|
class TestFlowExecutor(APITestCase):
|
||||||
"""Test views logic"""
|
"""Test views logic"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
"""flow views tests"""
|
"""flow views tests"""
|
||||||
from django.test import Client, TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from authentik.flows.models import Flow, FlowDesignation
|
from authentik.flows.models import Flow, FlowDesignation
|
||||||
@ -10,9 +10,6 @@ from authentik.flows.views import SESSION_KEY_PLAN
|
|||||||
class TestHelperView(TestCase):
|
class TestHelperView(TestCase):
|
||||||
"""Test helper views logic"""
|
"""Test helper views logic"""
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
def test_default_view(self):
|
def test_default_view(self):
|
||||||
"""Test that ToDefaultFlow returns the expected URL"""
|
"""Test that ToDefaultFlow returns the expected URL"""
|
||||||
flow = Flow.objects.filter(
|
flow = Flow.objects.filter(
|
||||||
|
|||||||
@ -8,8 +8,11 @@ from structlog.stdlib import get_logger
|
|||||||
|
|
||||||
from authentik.policies.models import Policy
|
from authentik.policies.models import Policy
|
||||||
from authentik.policies.types import PolicyRequest, PolicyResult
|
from authentik.policies.types import PolicyRequest, PolicyResult
|
||||||
|
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
RE_LOWER = re.compile("[a-z]")
|
||||||
|
RE_UPPER = re.compile("[A-Z]")
|
||||||
|
|
||||||
|
|
||||||
class PasswordPolicy(Policy):
|
class PasswordPolicy(Policy):
|
||||||
@ -38,31 +41,39 @@ class PasswordPolicy(Policy):
|
|||||||
return "ak-policy-password-form"
|
return "ak-policy-password-form"
|
||||||
|
|
||||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||||
if self.password_field not in request.context:
|
if (
|
||||||
|
self.password_field not in request.context
|
||||||
|
and self.password_field not in request.context.get(PLAN_CONTEXT_PROMPT, {})
|
||||||
|
):
|
||||||
LOGGER.warning(
|
LOGGER.warning(
|
||||||
"Password field not set in Policy Request",
|
"Password field not set in Policy Request",
|
||||||
field=self.password_field,
|
field=self.password_field,
|
||||||
fields=request.context.keys(),
|
fields=request.context.keys(),
|
||||||
|
prompt_fields=request.context.get(PLAN_CONTEXT_PROMPT, {}).keys(),
|
||||||
)
|
)
|
||||||
return PolicyResult(False, _("Password not set in context"))
|
return PolicyResult(False, _("Password not set in context"))
|
||||||
password = request.context[self.password_field]
|
|
||||||
|
|
||||||
filter_regex = []
|
if self.password_field in request.context:
|
||||||
if self.amount_lowercase > 0:
|
password = request.context[self.password_field]
|
||||||
filter_regex.append(r"[a-z]{%d,}" % self.amount_lowercase)
|
else:
|
||||||
if self.amount_uppercase > 0:
|
password = request.context[PLAN_CONTEXT_PROMPT][self.password_field]
|
||||||
filter_regex.append(r"[A-Z]{%d,}" % self.amount_uppercase)
|
|
||||||
if self.amount_symbols > 0:
|
|
||||||
filter_regex.append(r"[%s]{%d,}" % (self.symbol_charset, self.amount_symbols))
|
|
||||||
full_regex = "|".join(filter_regex)
|
|
||||||
LOGGER.debug("Built regex", regexp=full_regex)
|
|
||||||
result = bool(re.compile(full_regex).match(password))
|
|
||||||
|
|
||||||
result = result and len(password) >= self.length_min
|
if len(password) < self.length_min:
|
||||||
|
LOGGER.debug("password failed", reason="length", p=password)
|
||||||
|
return PolicyResult(False, self.error_message)
|
||||||
|
|
||||||
if not result:
|
if self.amount_lowercase > 0 and len(RE_LOWER.findall(password)) < self.amount_lowercase:
|
||||||
return PolicyResult(result, self.error_message)
|
LOGGER.debug("password failed", reason="amount_lowercase", p=password)
|
||||||
return PolicyResult(result)
|
return PolicyResult(False, self.error_message)
|
||||||
|
if self.amount_uppercase > 0 and len(RE_UPPER.findall(password)) < self.amount_lowercase:
|
||||||
|
LOGGER.debug("password failed", reason="amount_uppercase", p=password)
|
||||||
|
return PolicyResult(False, self.error_message)
|
||||||
|
regex = re.compile(r"[%s]" % self.symbol_charset)
|
||||||
|
if self.amount_symbols > 0 and len(regex.findall(password)) < self.amount_symbols:
|
||||||
|
LOGGER.debug("password failed", reason="amount_symbols", p=password)
|
||||||
|
return PolicyResult(False, self.error_message)
|
||||||
|
|
||||||
|
return PolicyResult(True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
|
|||||||
@ -1,57 +0,0 @@
|
|||||||
"""Password Policy tests"""
|
|
||||||
from django.test import TestCase
|
|
||||||
from guardian.shortcuts import get_anonymous_user
|
|
||||||
|
|
||||||
from authentik.policies.password.models import PasswordPolicy
|
|
||||||
from authentik.policies.types import PolicyRequest, PolicyResult
|
|
||||||
|
|
||||||
|
|
||||||
class TestPasswordPolicy(TestCase):
|
|
||||||
"""Test Password Policy"""
|
|
||||||
|
|
||||||
def test_invalid(self):
|
|
||||||
"""Test without password"""
|
|
||||||
policy = PasswordPolicy.objects.create(
|
|
||||||
name="test_invalid",
|
|
||||||
amount_uppercase=1,
|
|
||||||
amount_lowercase=2,
|
|
||||||
amount_symbols=3,
|
|
||||||
length_min=24,
|
|
||||||
error_message="test message",
|
|
||||||
)
|
|
||||||
request = PolicyRequest(get_anonymous_user())
|
|
||||||
result: PolicyResult = policy.passes(request)
|
|
||||||
self.assertFalse(result.passing)
|
|
||||||
self.assertEqual(result.messages[0], "Password not set in context")
|
|
||||||
|
|
||||||
def test_false(self):
|
|
||||||
"""Failing password case"""
|
|
||||||
policy = PasswordPolicy.objects.create(
|
|
||||||
name="test_false",
|
|
||||||
amount_uppercase=1,
|
|
||||||
amount_lowercase=2,
|
|
||||||
amount_symbols=3,
|
|
||||||
length_min=24,
|
|
||||||
error_message="test message",
|
|
||||||
)
|
|
||||||
request = PolicyRequest(get_anonymous_user())
|
|
||||||
request.context["password"] = "test"
|
|
||||||
result: PolicyResult = policy.passes(request)
|
|
||||||
self.assertFalse(result.passing)
|
|
||||||
self.assertEqual(result.messages, ("test message",))
|
|
||||||
|
|
||||||
def test_true(self):
|
|
||||||
"""Positive password case"""
|
|
||||||
policy = PasswordPolicy.objects.create(
|
|
||||||
name="test_true",
|
|
||||||
amount_uppercase=1,
|
|
||||||
amount_lowercase=2,
|
|
||||||
amount_symbols=3,
|
|
||||||
length_min=3,
|
|
||||||
error_message="test message",
|
|
||||||
)
|
|
||||||
request = PolicyRequest(get_anonymous_user())
|
|
||||||
request.context["password"] = "Test()!"
|
|
||||||
result: PolicyResult = policy.passes(request)
|
|
||||||
self.assertTrue(result.passing)
|
|
||||||
self.assertEqual(result.messages, tuple())
|
|
||||||
0
authentik/policies/password/tests/__init__.py
Normal file
0
authentik/policies/password/tests/__init__.py
Normal file
80
authentik/policies/password/tests/test_flows.py
Normal file
80
authentik/policies/password/tests/test_flows.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
"""Password flow tests"""
|
||||||
|
from django.urls.base import reverse
|
||||||
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
|
from authentik.core.models import User
|
||||||
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
|
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||||
|
from authentik.policies.password.models import PasswordPolicy
|
||||||
|
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
|
||||||
|
|
||||||
|
|
||||||
|
class TestPasswordPolicyFlow(APITestCase):
|
||||||
|
"""Test Password Policy"""
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||||
|
|
||||||
|
self.flow = Flow.objects.create(
|
||||||
|
name="test-prompt",
|
||||||
|
slug="test-prompt",
|
||||||
|
designation=FlowDesignation.AUTHENTICATION,
|
||||||
|
)
|
||||||
|
password_prompt = Prompt.objects.create(
|
||||||
|
field_key="password",
|
||||||
|
label="PASSWORD_LABEL",
|
||||||
|
type=FieldTypes.PASSWORD,
|
||||||
|
required=True,
|
||||||
|
placeholder="PASSWORD_PLACEHOLDER",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.policy = PasswordPolicy.objects.create(
|
||||||
|
name="test_true",
|
||||||
|
amount_uppercase=1,
|
||||||
|
amount_lowercase=2,
|
||||||
|
amount_symbols=3,
|
||||||
|
length_min=3,
|
||||||
|
error_message="test message",
|
||||||
|
)
|
||||||
|
stage = PromptStage.objects.create(name="prompt-stage")
|
||||||
|
stage.validation_policies.set([self.policy])
|
||||||
|
stage.fields.set(
|
||||||
|
[
|
||||||
|
password_prompt,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
FlowStageBinding.objects.create(target=self.flow, stage=stage, order=2)
|
||||||
|
|
||||||
|
def test_prompt_data(self):
|
||||||
|
"""Test policy attached to a prompt stage"""
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||||
|
{"password": "akadmin"},
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertJSONEqual(
|
||||||
|
force_str(response.content),
|
||||||
|
{
|
||||||
|
"component": "ak-stage-prompt",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"field_key": "password",
|
||||||
|
"label": "PASSWORD_LABEL",
|
||||||
|
"order": 0,
|
||||||
|
"placeholder": "PASSWORD_PLACEHOLDER",
|
||||||
|
"required": True,
|
||||||
|
"type": "password",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"flow_info": {
|
||||||
|
"background": self.flow.background_url,
|
||||||
|
"cancel_url": reverse("authentik_flows:cancel"),
|
||||||
|
"title": "",
|
||||||
|
},
|
||||||
|
"response_errors": {
|
||||||
|
"non_field_errors": [{"code": "invalid", "string": self.policy.error_message}]
|
||||||
|
},
|
||||||
|
"type": ChallengeTypes.NATIVE.value,
|
||||||
|
},
|
||||||
|
)
|
||||||
68
authentik/policies/password/tests/test_policy.py
Normal file
68
authentik/policies/password/tests/test_policy.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
"""Password Policy tests"""
|
||||||
|
from django.test import TestCase
|
||||||
|
from guardian.shortcuts import get_anonymous_user
|
||||||
|
|
||||||
|
from authentik.lib.generators import generate_key
|
||||||
|
from authentik.policies.password.models import PasswordPolicy
|
||||||
|
from authentik.policies.types import PolicyRequest, PolicyResult
|
||||||
|
|
||||||
|
|
||||||
|
class TestPasswordPolicy(TestCase):
|
||||||
|
"""Test Password Policy"""
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.policy = PasswordPolicy.objects.create(
|
||||||
|
name="test_false",
|
||||||
|
amount_uppercase=1,
|
||||||
|
amount_lowercase=2,
|
||||||
|
amount_symbols=3,
|
||||||
|
length_min=24,
|
||||||
|
error_message="test message",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_invalid(self):
|
||||||
|
"""Test without password"""
|
||||||
|
request = PolicyRequest(get_anonymous_user())
|
||||||
|
result: PolicyResult = self.policy.passes(request)
|
||||||
|
self.assertFalse(result.passing)
|
||||||
|
self.assertEqual(result.messages[0], "Password not set in context")
|
||||||
|
|
||||||
|
def test_failed_length(self):
|
||||||
|
"""Password too short"""
|
||||||
|
request = PolicyRequest(get_anonymous_user())
|
||||||
|
request.context["password"] = "test"
|
||||||
|
result: PolicyResult = self.policy.passes(request)
|
||||||
|
self.assertFalse(result.passing)
|
||||||
|
self.assertEqual(result.messages, ("test message",))
|
||||||
|
|
||||||
|
def test_failed_lowercase(self):
|
||||||
|
"""not enough lowercase"""
|
||||||
|
request = PolicyRequest(get_anonymous_user())
|
||||||
|
request.context["password"] = "TTTTTTTTTTTTTTTTTTTTTTTe"
|
||||||
|
result: PolicyResult = self.policy.passes(request)
|
||||||
|
self.assertFalse(result.passing)
|
||||||
|
self.assertEqual(result.messages, ("test message",))
|
||||||
|
|
||||||
|
def test_failed_uppercase(self):
|
||||||
|
"""not enough uppercase"""
|
||||||
|
request = PolicyRequest(get_anonymous_user())
|
||||||
|
request.context["password"] = "tttttttttttttttttttttttE"
|
||||||
|
result: PolicyResult = self.policy.passes(request)
|
||||||
|
self.assertFalse(result.passing)
|
||||||
|
self.assertEqual(result.messages, ("test message",))
|
||||||
|
|
||||||
|
def test_failed_symbols(self):
|
||||||
|
"""not enough uppercase"""
|
||||||
|
request = PolicyRequest(get_anonymous_user())
|
||||||
|
request.context["password"] = "TETETETETETETETETETETETETe!!!"
|
||||||
|
result: PolicyResult = self.policy.passes(request)
|
||||||
|
self.assertFalse(result.passing)
|
||||||
|
self.assertEqual(result.messages, ("test message",))
|
||||||
|
|
||||||
|
def test_true(self):
|
||||||
|
"""Positive password case"""
|
||||||
|
request = PolicyRequest(get_anonymous_user())
|
||||||
|
request.context["password"] = generate_key() + "ee!!!"
|
||||||
|
result: PolicyResult = self.policy.passes(request)
|
||||||
|
self.assertTrue(result.passing)
|
||||||
|
self.assertEqual(result.messages, tuple())
|
||||||
@ -61,9 +61,10 @@ class IngressReconciler(KubernetesObjectReconciler[NetworkingV1beta1Ingress]):
|
|||||||
have_hosts.sort()
|
have_hosts.sort()
|
||||||
|
|
||||||
have_hosts_tls = []
|
have_hosts_tls = []
|
||||||
for tls_config in current.spec.tls:
|
if current.spec.tls:
|
||||||
if tls_config and tls_config.hosts:
|
for tls_config in current.spec.tls:
|
||||||
have_hosts_tls += tls_config.hosts
|
if tls_config and tls_config.hosts:
|
||||||
|
have_hosts_tls += tls_config.hosts
|
||||||
have_hosts_tls.sort()
|
have_hosts_tls.sort()
|
||||||
|
|
||||||
if have_hosts != expected_hosts:
|
if have_hosts != expected_hosts:
|
||||||
|
|||||||
@ -96,6 +96,7 @@ class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware])
|
|||||||
|
|
||||||
def get_reference_object(self) -> TraefikMiddleware:
|
def get_reference_object(self) -> TraefikMiddleware:
|
||||||
"""Get deployment object for outpost"""
|
"""Get deployment object for outpost"""
|
||||||
|
port = 9000 if self.is_embedded else 4180
|
||||||
return TraefikMiddleware(
|
return TraefikMiddleware(
|
||||||
apiVersion=f"{CRD_GROUP}/{CRD_VERSION}",
|
apiVersion=f"{CRD_GROUP}/{CRD_VERSION}",
|
||||||
kind="Middleware",
|
kind="Middleware",
|
||||||
@ -106,7 +107,7 @@ class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware])
|
|||||||
),
|
),
|
||||||
spec=TraefikMiddlewareSpec(
|
spec=TraefikMiddlewareSpec(
|
||||||
forwardAuth=TraefikMiddlewareSpecForwardAuth(
|
forwardAuth=TraefikMiddlewareSpecForwardAuth(
|
||||||
address=f"http://{self.name}.{self.namespace}:4180/akprox/auth?traefik",
|
address=f"http://{self.name}.{self.namespace}:{port}/akprox/auth?traefik",
|
||||||
authResponseHeaders=[
|
authResponseHeaders=[
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
"X-Auth-Username",
|
"X-Auth-Username",
|
||||||
|
|||||||
@ -150,9 +150,20 @@ SPECTACULAR_SETTINGS = {
|
|||||||
"DESCRIPTION": "Making authentication simple.",
|
"DESCRIPTION": "Making authentication simple.",
|
||||||
"VERSION": __version__,
|
"VERSION": __version__,
|
||||||
"COMPONENT_SPLIT_REQUEST": True,
|
"COMPONENT_SPLIT_REQUEST": True,
|
||||||
|
"SCHEMA_PATH_PREFIX": "/api/v([0-9]+(beta)?)",
|
||||||
|
"SCHEMA_PATH_PREFIX_TRIM": True,
|
||||||
|
"SERVERS": [
|
||||||
|
{
|
||||||
|
"url": "http://authentik.tld/api/v3/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "http://authentik.tld/api/v2beta/",
|
||||||
|
},
|
||||||
|
],
|
||||||
"CONTACT": {
|
"CONTACT": {
|
||||||
"email": "hello@beryju.org",
|
"email": "hello@beryju.org",
|
||||||
},
|
},
|
||||||
|
"AUTHENTICATION_WHITELIST": ["authentik.api.authentication.TokenAuthentication"],
|
||||||
"LICENSE": {
|
"LICENSE": {
|
||||||
"name": "GNU GPLv3",
|
"name": "GNU GPLv3",
|
||||||
"url": "https://github.com/goauthentik/authentik/blob/master/LICENSE",
|
"url": "https://github.com/goauthentik/authentik/blob/master/LICENSE",
|
||||||
@ -180,6 +191,9 @@ REST_FRAMEWORK = {
|
|||||||
"rest_framework.filters.OrderingFilter",
|
"rest_framework.filters.OrderingFilter",
|
||||||
"rest_framework.filters.SearchFilter",
|
"rest_framework.filters.SearchFilter",
|
||||||
],
|
],
|
||||||
|
"DEFAULT_PARSER_CLASSES": [
|
||||||
|
"rest_framework.parsers.JSONParser",
|
||||||
|
],
|
||||||
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.DjangoObjectPermissions",),
|
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.DjangoObjectPermissions",),
|
||||||
"DEFAULT_AUTHENTICATION_CLASSES": (
|
"DEFAULT_AUTHENTICATION_CLASSES": (
|
||||||
"authentik.api.authentication.TokenAuthentication",
|
"authentik.api.authentication.TokenAuthentication",
|
||||||
@ -189,6 +203,7 @@ REST_FRAMEWORK = {
|
|||||||
"rest_framework.renderers.JSONRenderer",
|
"rest_framework.renderers.JSONRenderer",
|
||||||
],
|
],
|
||||||
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
||||||
|
"TEST_REQUEST_DEFAULT_FORMAT": "json",
|
||||||
}
|
}
|
||||||
|
|
||||||
REDIS_PROTOCOL_PREFIX = "redis://"
|
REDIS_PROTOCOL_PREFIX = "redis://"
|
||||||
@ -372,6 +387,7 @@ if CONFIG.y("postgresql.s3_backup"):
|
|||||||
"default_acl": "private",
|
"default_acl": "private",
|
||||||
"endpoint_url": CONFIG.y("postgresql.s3_backup.host"),
|
"endpoint_url": CONFIG.y("postgresql.s3_backup.host"),
|
||||||
"location": CONFIG.y("postgresql.s3_backup.location", ""),
|
"location": CONFIG.y("postgresql.s3_backup.location", ""),
|
||||||
|
"verify": not CONFIG.y_bool("postgresql.s3_backup.insecure_skip_verify", False),
|
||||||
}
|
}
|
||||||
j_print(
|
j_print(
|
||||||
"Database backup to S3 is configured",
|
"Database backup to S3 is configured",
|
||||||
|
|||||||
@ -2,17 +2,13 @@
|
|||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import Client, TestCase
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
|
|
||||||
class TestRoot(TestCase):
|
class TestRoot(TestCase):
|
||||||
"""Test root application"""
|
"""Test root application"""
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super().setUp()
|
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
def test_monitoring_error(self):
|
def test_monitoring_error(self):
|
||||||
"""Test monitoring without any credentials"""
|
"""Test monitoring without any credentials"""
|
||||||
response = self.client.get(reverse("metrics"))
|
response = self.client.get(reverse("metrics"))
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
"""Twitter Type tests"""
|
"""Twitter Type tests"""
|
||||||
from django.test import Client, TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from authentik.sources.oauth.models import OAuthSource
|
from authentik.sources.oauth.models import OAuthSource
|
||||||
from authentik.sources.oauth.types.twitter import TwitterOAuthCallback
|
from authentik.sources.oauth.types.twitter import TwitterOAuthCallback
|
||||||
@ -92,7 +92,6 @@ class TestTypeGitHub(TestCase):
|
|||||||
"""OAuth Source tests"""
|
"""OAuth Source tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = Client()
|
|
||||||
self.source = OAuthSource.objects.create(
|
self.source = OAuthSource.objects.create(
|
||||||
name="test",
|
name="test",
|
||||||
slug="test",
|
slug="test",
|
||||||
|
|||||||
@ -51,20 +51,30 @@ def get_webauthn_challenge(request: HttpRequest, device: WebAuthnDevice) -> dict
|
|||||||
# for the reasons outlined in the comment in webauthn_begin_activate.
|
# for the reasons outlined in the comment in webauthn_begin_activate.
|
||||||
request.session["challenge"] = challenge.rstrip("=")
|
request.session["challenge"] = challenge.rstrip("=")
|
||||||
|
|
||||||
webauthn_user = WebAuthnUser(
|
assertion = {}
|
||||||
device.user.uid,
|
user = device.user
|
||||||
device.user.username,
|
|
||||||
device.user.name,
|
|
||||||
device.user.avatar,
|
|
||||||
device.credential_id,
|
|
||||||
device.public_key,
|
|
||||||
device.sign_count,
|
|
||||||
device.rp_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
webauthn_assertion_options = WebAuthnAssertionOptions(webauthn_user, challenge)
|
# We want all the user's WebAuthn devices and merge their challenges
|
||||||
|
for user_device in WebAuthnDevice.objects.filter(user=device.user).order_by("name"):
|
||||||
|
webauthn_user = WebAuthnUser(
|
||||||
|
user.uid,
|
||||||
|
user.username,
|
||||||
|
user.name,
|
||||||
|
user.avatar,
|
||||||
|
user_device.credential_id,
|
||||||
|
user_device.public_key,
|
||||||
|
user_device.sign_count,
|
||||||
|
user_device.rp_id,
|
||||||
|
)
|
||||||
|
webauthn_assertion_options = WebAuthnAssertionOptions(webauthn_user, challenge)
|
||||||
|
if assertion == {}:
|
||||||
|
assertion = webauthn_assertion_options.assertion_dict
|
||||||
|
else:
|
||||||
|
assertion["allowCredentials"] += webauthn_assertion_options.assertion_dict.get(
|
||||||
|
"allowCredentials"
|
||||||
|
)
|
||||||
|
|
||||||
return webauthn_assertion_options.assertion_dict
|
return assertion
|
||||||
|
|
||||||
|
|
||||||
def validate_challenge_code(code: str, request: HttpRequest, user: User) -> str:
|
def validate_challenge_code(code: str, request: HttpRequest, user: User) -> str:
|
||||||
|
|||||||
@ -20,8 +20,6 @@ from authentik.stages.authenticator_validate.models import AuthenticatorValidate
|
|||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
PER_DEVICE_CLASSES = [DeviceClasses.WEBAUTHN]
|
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorValidationChallenge(WithUserInfoChallenge):
|
class AuthenticatorValidationChallenge(WithUserInfoChallenge):
|
||||||
"""Authenticator challenge"""
|
"""Authenticator challenge"""
|
||||||
@ -91,9 +89,9 @@ class AuthenticatorValidateStageView(ChallengeStageView):
|
|||||||
if device_class not in stage.device_classes:
|
if device_class not in stage.device_classes:
|
||||||
LOGGER.debug("device class not allowed", device_class=device_class)
|
LOGGER.debug("device class not allowed", device_class=device_class)
|
||||||
continue
|
continue
|
||||||
# Ensure only classes in PER_DEVICE_CLASSES are returned per device
|
# Ensure only one challenge per device class
|
||||||
# otherwise only return a single challenge
|
# WebAuthn does another device loop to find all webuahtn devices
|
||||||
if device_class in seen_classes and device_class not in PER_DEVICE_CLASSES:
|
if device_class in seen_classes:
|
||||||
continue
|
continue
|
||||||
if device_class not in seen_classes:
|
if device_class not in seen_classes:
|
||||||
seen_classes.append(device_class)
|
seen_classes.append(device_class)
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
"""Test validator stage"""
|
"""Test validator stage"""
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from django.urls.base import reverse
|
from django.urls.base import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -26,7 +26,7 @@ from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
|
|||||||
from authentik.stages.identification.models import IdentificationStage, UserFields
|
from authentik.stages.identification.models import IdentificationStage, UserFields
|
||||||
|
|
||||||
|
|
||||||
class AuthenticatorValidateStageTests(TestCase):
|
class AuthenticatorValidateStageTests(APITestCase):
|
||||||
"""Test validator stage"""
|
"""Test validator stage"""
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"""captcha tests"""
|
"""captcha tests"""
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -16,13 +16,12 @@ RECAPTCHA_PUBLIC_KEY = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
|
|||||||
RECAPTCHA_PRIVATE_KEY = "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"
|
RECAPTCHA_PRIVATE_KEY = "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"
|
||||||
|
|
||||||
|
|
||||||
class TestCaptchaStage(TestCase):
|
class TestCaptchaStage(APITestCase):
|
||||||
"""Captcha tests"""
|
"""Captcha tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create_user(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create_user(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-captcha",
|
name="test-captcha",
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
"""consent tests"""
|
"""consent tests"""
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import Application, User
|
from authentik.core.models import Application, User
|
||||||
from authentik.core.tasks import clean_expired_models
|
from authentik.core.tasks import clean_expired_models
|
||||||
@ -15,7 +15,7 @@ from authentik.flows.views import SESSION_KEY_PLAN
|
|||||||
from authentik.stages.consent.models import ConsentMode, ConsentStage, UserConsent
|
from authentik.stages.consent.models import ConsentMode, ConsentStage, UserConsent
|
||||||
|
|
||||||
|
|
||||||
class TestConsentStage(TestCase):
|
class TestConsentStage(APITestCase):
|
||||||
"""Consent tests"""
|
"""Consent tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -25,7 +25,6 @@ class TestConsentStage(TestCase):
|
|||||||
name="test-application",
|
name="test-application",
|
||||||
slug="test-application",
|
slug="test-application",
|
||||||
)
|
)
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
def test_always_required(self):
|
def test_always_required(self):
|
||||||
"""Test always required consent"""
|
"""Test always required consent"""
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"""deny tests"""
|
"""deny tests"""
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -12,13 +12,12 @@ from authentik.flows.views import SESSION_KEY_PLAN
|
|||||||
from authentik.stages.deny.models import DenyStage
|
from authentik.stages.deny.models import DenyStage
|
||||||
|
|
||||||
|
|
||||||
class TestUserDenyStage(TestCase):
|
class TestUserDenyStage(APITestCase):
|
||||||
"""Deny tests"""
|
"""Deny tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-logout",
|
name="test-logout",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"""dummy tests"""
|
"""dummy tests"""
|
||||||
from django.test import TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -9,7 +9,7 @@ from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
|||||||
from authentik.stages.dummy.models import DummyStage
|
from authentik.stages.dummy.models import DummyStage
|
||||||
|
|
||||||
|
|
||||||
class TestDummyStage(TestCase):
|
class TestDummyStage(APITestCase):
|
||||||
"""Dummy tests"""
|
"""Dummy tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|||||||
@ -4,8 +4,8 @@ from unittest.mock import MagicMock, patch
|
|||||||
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.mail.backends.locmem import EmailBackend
|
from django.core.mail.backends.locmem import EmailBackend
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
@ -16,13 +16,12 @@ from authentik.flows.views import SESSION_KEY_PLAN
|
|||||||
from authentik.stages.email.models import EmailStage
|
from authentik.stages.email.models import EmailStage
|
||||||
|
|
||||||
|
|
||||||
class TestEmailStageSending(TestCase):
|
class TestEmailStageSending(APITestCase):
|
||||||
"""Email tests"""
|
"""Email tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create_user(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create_user(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-email",
|
name="test-email",
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.http import urlencode
|
from django.utils.http import urlencode
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import Token, User
|
from authentik.core.models import Token, User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -17,13 +17,12 @@ from authentik.stages.email.models import EmailStage
|
|||||||
from authentik.stages.email.stage import QS_KEY_TOKEN
|
from authentik.stages.email.stage import QS_KEY_TOKEN
|
||||||
|
|
||||||
|
|
||||||
class TestEmailStage(TestCase):
|
class TestEmailStage(APITestCase):
|
||||||
"""Email tests"""
|
"""Email tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create_user(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create_user(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-email",
|
name="test-email",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"""identification tests"""
|
"""identification tests"""
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -13,7 +13,7 @@ from authentik.stages.password import BACKEND_INBUILT
|
|||||||
from authentik.stages.password.models import PasswordStage
|
from authentik.stages.password.models import PasswordStage
|
||||||
|
|
||||||
|
|
||||||
class TestIdentificationStage(TestCase):
|
class TestIdentificationStage(APITestCase):
|
||||||
"""Identification tests"""
|
"""Identification tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -22,7 +22,6 @@ class TestIdentificationStage(TestCase):
|
|||||||
self.user = User.objects.create_user(
|
self.user = User.objects.create_user(
|
||||||
username="unittest", email="test@beryju.org", password=self.password
|
username="unittest", email="test@beryju.org", password=self.password
|
||||||
)
|
)
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
# OAuthSource for the login view
|
# OAuthSource for the login view
|
||||||
source = OAuthSource.objects.create(name="test", slug="test")
|
source = OAuthSource.objects.create(name="test", slug="test")
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 3.2.6 on 2021-09-01 12:11
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import authentik.core.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("authentik_stages_invitation", "0004_invitation_single_use"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="invitation",
|
||||||
|
name="expiring",
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="invitation",
|
||||||
|
name="expires",
|
||||||
|
field=models.DateTimeField(default=authentik.core.models.default_token_duration),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from django.views import View
|
from django.views import View
|
||||||
from rest_framework.serializers import BaseSerializer
|
from rest_framework.serializers import BaseSerializer
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import ExpiringModel, User
|
||||||
from authentik.flows.models import Stage
|
from authentik.flows.models import Stage
|
||||||
|
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ class InvitationStage(Stage):
|
|||||||
verbose_name_plural = _("Invitation Stages")
|
verbose_name_plural = _("Invitation Stages")
|
||||||
|
|
||||||
|
|
||||||
class Invitation(models.Model):
|
class Invitation(ExpiringModel):
|
||||||
"""Single-use invitation link"""
|
"""Single-use invitation link"""
|
||||||
|
|
||||||
invite_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
|
invite_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
|
||||||
@ -59,7 +59,6 @@ class Invitation(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
created_by = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
expires = models.DateTimeField(default=None, blank=True, null=True)
|
|
||||||
fixed_data = models.JSONField(
|
fixed_data = models.JSONField(
|
||||||
default=dict,
|
default=dict,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
"""invitation tests"""
|
"""invitation tests"""
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.http import urlencode
|
from django.utils.http import urlencode
|
||||||
@ -21,13 +20,12 @@ from authentik.stages.password import BACKEND_INBUILT
|
|||||||
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
||||||
|
|
||||||
|
|
||||||
class TestUserLoginStage(TestCase):
|
class TestUserLoginStage(APITestCase):
|
||||||
"""Login tests"""
|
"""Login tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-invitation",
|
name="test-invitation",
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -20,7 +20,7 @@ from authentik.stages.password.models import PasswordStage
|
|||||||
MOCK_BACKEND_AUTHENTICATE = MagicMock(side_effect=PermissionDenied("test"))
|
MOCK_BACKEND_AUTHENTICATE = MagicMock(side_effect=PermissionDenied("test"))
|
||||||
|
|
||||||
|
|
||||||
class TestPasswordStage(TestCase):
|
class TestPasswordStage(APITestCase):
|
||||||
"""Password tests"""
|
"""Password tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -29,7 +29,6 @@ class TestPasswordStage(TestCase):
|
|||||||
self.user = User.objects.create_user(
|
self.user = User.objects.create_user(
|
||||||
username="unittest", email="test@beryju.org", password=self.password
|
username="unittest", email="test@beryju.org", password=self.password
|
||||||
)
|
)
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-password",
|
name="test-password",
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
"""Prompt tests"""
|
"""Prompt tests"""
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from rest_framework.exceptions import ErrorDetail
|
from rest_framework.exceptions import ErrorDetail
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -17,13 +17,12 @@ from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
|
|||||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT, PromptChallengeResponse
|
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT, PromptChallengeResponse
|
||||||
|
|
||||||
|
|
||||||
class TestPromptStage(TestCase):
|
class TestPromptStage(APITestCase):
|
||||||
"""Prompt tests"""
|
"""Prompt tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-prompt",
|
name="test-prompt",
|
||||||
@ -97,7 +96,6 @@ class TestPromptStage(TestCase):
|
|||||||
static_prompt,
|
static_prompt,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
self.stage.save()
|
|
||||||
|
|
||||||
self.prompt_data = {
|
self.prompt_data = {
|
||||||
username_prompt.field_key: "test-username",
|
username_prompt.field_key: "test-username",
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
"""delete tests"""
|
"""delete tests"""
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -15,14 +15,13 @@ from authentik.flows.views import SESSION_KEY_PLAN
|
|||||||
from authentik.stages.user_delete.models import UserDeleteStage
|
from authentik.stages.user_delete.models import UserDeleteStage
|
||||||
|
|
||||||
|
|
||||||
class TestUserDeleteStage(TestCase):
|
class TestUserDeleteStage(APITestCase):
|
||||||
"""Delete tests"""
|
"""Delete tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.username = "qerqwerqrwqwerwq"
|
self.username = "qerqwerqrwqwerwq"
|
||||||
self.user = User.objects.create(username=self.username, email="test@beryju.org")
|
self.user = User.objects.create(username=self.username, email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-delete",
|
name="test-delete",
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -16,13 +16,12 @@ from authentik.flows.views import SESSION_KEY_PLAN
|
|||||||
from authentik.stages.user_login.models import UserLoginStage
|
from authentik.stages.user_login.models import UserLoginStage
|
||||||
|
|
||||||
|
|
||||||
class TestUserLoginStage(TestCase):
|
class TestUserLoginStage(APITestCase):
|
||||||
"""Login tests"""
|
"""Login tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-login",
|
name="test-login",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"""logout tests"""
|
"""logout tests"""
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import User
|
from authentik.core.models import User
|
||||||
from authentik.flows.challenge import ChallengeTypes
|
from authentik.flows.challenge import ChallengeTypes
|
||||||
@ -14,13 +14,12 @@ from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
|||||||
from authentik.stages.user_logout.models import UserLogoutStage
|
from authentik.stages.user_logout.models import UserLogoutStage
|
||||||
|
|
||||||
|
|
||||||
class TestUserLogoutStage(TestCase):
|
class TestUserLogoutStage(APITestCase):
|
||||||
"""Logout tests"""
|
"""Logout tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
self.user = User.objects.create(username="unittest", email="test@beryju.org")
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-logout",
|
name="test-logout",
|
||||||
|
|||||||
@ -3,9 +3,9 @@ import string
|
|||||||
from random import SystemRandom
|
from random import SystemRandom
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import USER_ATTRIBUTE_SOURCES, Source, User, UserSourceConnection
|
from authentik.core.models import USER_ATTRIBUTE_SOURCES, Source, User, UserSourceConnection
|
||||||
from authentik.core.sources.stage import PLAN_CONTEXT_SOURCES_CONNECTION
|
from authentik.core.sources.stage import PLAN_CONTEXT_SOURCES_CONNECTION
|
||||||
@ -19,13 +19,11 @@ from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
|||||||
from authentik.stages.user_write.models import UserWriteStage
|
from authentik.stages.user_write.models import UserWriteStage
|
||||||
|
|
||||||
|
|
||||||
class TestUserWriteStage(TestCase):
|
class TestUserWriteStage(APITestCase):
|
||||||
"""Write tests"""
|
"""Write tests"""
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
self.client = Client()
|
|
||||||
|
|
||||||
self.flow = Flow.objects.create(
|
self.flow = Flow.objects.create(
|
||||||
name="test-write",
|
name="test-write",
|
||||||
slug="test-write",
|
slug="test-write",
|
||||||
|
|||||||
@ -1,120 +0,0 @@
|
|||||||
trigger:
|
|
||||||
batch: true
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
- version-*
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- stage: generate
|
|
||||||
jobs:
|
|
||||||
- job: generate_api
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: GoTool@0
|
|
||||||
inputs:
|
|
||||||
version: '1.16.3'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: make gen-outpost
|
|
||||||
- task: PublishPipelineArtifact@1
|
|
||||||
inputs:
|
|
||||||
targetPath: 'api/'
|
|
||||||
artifact: 'go_api_client'
|
|
||||||
publishLocation: 'pipeline'
|
|
||||||
- stage: lint
|
|
||||||
jobs:
|
|
||||||
- job: golint
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: GoTool@0
|
|
||||||
inputs:
|
|
||||||
version: '1.16.3'
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: 'go_api_client'
|
|
||||||
path: "api/"
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
mkdir -p web/dist
|
|
||||||
mkdir -p website/help
|
|
||||||
touch web/dist/test website/help/test
|
|
||||||
docker run \
|
|
||||||
--rm \
|
|
||||||
-v $(pwd):/app \
|
|
||||||
-w /app \
|
|
||||||
golangci/golangci-lint:v1.39.0 \
|
|
||||||
golangci-lint run -v --timeout 200s
|
|
||||||
- stage: build_docker
|
|
||||||
jobs:
|
|
||||||
- job: proxy_build_docker
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: GoTool@0
|
|
||||||
inputs:
|
|
||||||
version: '1.16.3'
|
|
||||||
- task: Bash@3
|
|
||||||
inputs:
|
|
||||||
targetType: 'inline'
|
|
||||||
script: |
|
|
||||||
python ./scripts/az_do_set_branch.py
|
|
||||||
- task: Docker@2
|
|
||||||
inputs:
|
|
||||||
containerRegistry: 'beryjuorg-harbor'
|
|
||||||
repository: 'authentik/outpost-proxy'
|
|
||||||
command: 'build'
|
|
||||||
Dockerfile: 'proxy.Dockerfile'
|
|
||||||
buildContext: '$(Build.SourcesDirectory)'
|
|
||||||
tags: |
|
|
||||||
gh-$(branchName)
|
|
||||||
gh-$(branchName)-$(timestamp)
|
|
||||||
gh-$(Build.SourceVersion)
|
|
||||||
arguments: '--build-arg GIT_BUILD_HASH=$(Build.SourceVersion)'
|
|
||||||
- task: Docker@2
|
|
||||||
inputs:
|
|
||||||
containerRegistry: 'beryjuorg-harbor'
|
|
||||||
repository: 'authentik/outpost-proxy'
|
|
||||||
command: 'push'
|
|
||||||
tags: |
|
|
||||||
gh-$(branchName)
|
|
||||||
gh-$(branchName)-$(timestamp)
|
|
||||||
gh-$(Build.SourceVersion)
|
|
||||||
- job: ldap_build_docker
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: GoTool@0
|
|
||||||
inputs:
|
|
||||||
version: '1.16.3'
|
|
||||||
- task: Bash@3
|
|
||||||
inputs:
|
|
||||||
targetType: 'inline'
|
|
||||||
script: |
|
|
||||||
python ./scripts/az_do_set_branch.py
|
|
||||||
- task: Docker@2
|
|
||||||
inputs:
|
|
||||||
containerRegistry: 'beryjuorg-harbor'
|
|
||||||
repository: 'authentik/outpost-ldap'
|
|
||||||
command: 'build'
|
|
||||||
Dockerfile: 'ldap.Dockerfile'
|
|
||||||
buildContext: '$(Build.SourcesDirectory)'
|
|
||||||
tags: |
|
|
||||||
gh-$(branchName)
|
|
||||||
gh-$(branchName)-$(timestamp)
|
|
||||||
gh-$(Build.SourceVersion)
|
|
||||||
arguments: '--build-arg GIT_BUILD_HASH=$(Build.SourceVersion)'
|
|
||||||
- task: Docker@2
|
|
||||||
inputs:
|
|
||||||
containerRegistry: 'beryjuorg-harbor'
|
|
||||||
repository: 'authentik/outpost-ldap'
|
|
||||||
command: 'push'
|
|
||||||
tags: |
|
|
||||||
gh-$(branchName)
|
|
||||||
gh-$(branchName)-$(timestamp)
|
|
||||||
gh-$(Build.SourceVersion)
|
|
||||||
@ -1,426 +0,0 @@
|
|||||||
trigger:
|
|
||||||
batch: true
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
- version-*
|
|
||||||
paths:
|
|
||||||
exclude:
|
|
||||||
- website
|
|
||||||
- outpost
|
|
||||||
|
|
||||||
resources:
|
|
||||||
- repo: self
|
|
||||||
|
|
||||||
variables:
|
|
||||||
- name: POSTGRES_DB
|
|
||||||
value: authentik
|
|
||||||
- name: POSTGRES_USER
|
|
||||||
value: authentik
|
|
||||||
- name: POSTGRES_PASSWORD
|
|
||||||
value: "EK-5jnKfjrGRm<77"
|
|
||||||
- group: coverage
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- stage: Lint_and_test
|
|
||||||
jobs:
|
|
||||||
- job: pylint
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run services
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'scripts/ci.docker-compose.yml'
|
|
||||||
action: 'Run services'
|
|
||||||
buildImages: false
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run pylint authentik tests lifecycle
|
|
||||||
- job: black
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: pipenv run black --check authentik tests lifecycle
|
|
||||||
- job: isort
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: pipenv run isort --check authentik tests lifecycle
|
|
||||||
- job: bandit
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: pipenv run bandit -r authentik tests lifecycle
|
|
||||||
- job: pyright
|
|
||||||
pool:
|
|
||||||
vmImage: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- task: UseNode@1
|
|
||||||
inputs:
|
|
||||||
version: '12.x'
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: npm install -g pyright@1.1.136
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: pipenv run pyright e2e lifecycle
|
|
||||||
- job: migrations
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run services
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'scripts/ci.docker-compose.yml'
|
|
||||||
action: 'Run services'
|
|
||||||
buildImages: false
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run python -m lifecycle.migrate
|
|
||||||
- job: migrations_from_previous_release
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.8'
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run services
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'scripts/ci.docker-compose.yml'
|
|
||||||
action: 'Run services'
|
|
||||||
buildImages: false
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Prepare Last tagged release
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
# Copy current, latest config to local
|
|
||||||
cp authentik/lib/default.yml local.env.yml
|
|
||||||
git checkout $(git describe --abbrev=0 --match 'version/*')
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Migrate to last tagged release
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run python -m lifecycle.migrate
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Install current branch
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
set -x
|
|
||||||
git checkout ${{ variables.branchName }}
|
|
||||||
pipenv sync --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Migrate to current branch
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run python -m lifecycle.migrate
|
|
||||||
- job: coverage_unittest
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run services
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'scripts/ci.docker-compose.yml'
|
|
||||||
action: 'Run services'
|
|
||||||
buildImages: false
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Run full test suite
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run make test
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
mkdir output-unittest
|
|
||||||
mv unittest.xml output-unittest/unittest.xml
|
|
||||||
mv .coverage output-unittest/coverage
|
|
||||||
- task: PublishPipelineArtifact@1
|
|
||||||
inputs:
|
|
||||||
targetPath: 'output-unittest/'
|
|
||||||
artifact: 'coverage-unittest'
|
|
||||||
publishLocation: 'pipeline'
|
|
||||||
- job: coverage_integration
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run services
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'scripts/ci.docker-compose.yml'
|
|
||||||
action: 'Run services'
|
|
||||||
buildImages: false
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Install K3d and prepare
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
wget -q -O - https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
|
|
||||||
k3d cluster create
|
|
||||||
k3d kubeconfig write -o ~/.kube/config --overwrite
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Run full test suite
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run make test-integration
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
mkdir output-integration
|
|
||||||
mv unittest.xml output-integration/unittest.xml
|
|
||||||
mv .coverage output-integration/coverage
|
|
||||||
- task: PublishPipelineArtifact@1
|
|
||||||
inputs:
|
|
||||||
targetPath: 'output-integration/'
|
|
||||||
artifact: 'coverage-integration'
|
|
||||||
publishLocation: 'pipeline'
|
|
||||||
- job: coverage_e2e
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '16.x'
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run services
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'scripts/ci.docker-compose.yml'
|
|
||||||
action: 'Run services'
|
|
||||||
buildImages: false
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev --python python3.9
|
|
||||||
- task: DockerCompose@0
|
|
||||||
displayName: Run ChromeDriver
|
|
||||||
inputs:
|
|
||||||
dockerComposeFile: 'tests/e2e/ci.docker-compose.yml'
|
|
||||||
action: 'Run a specific service'
|
|
||||||
serviceName: 'chrome'
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Build static files for e2e
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
cd web
|
|
||||||
npm i
|
|
||||||
npm run build
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Run full test suite
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
pipenv run python -m scripts.generate_ci_config
|
|
||||||
pipenv run make test-e2e
|
|
||||||
- task: CmdLine@2
|
|
||||||
condition: always()
|
|
||||||
displayName: Cleanup
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
docker stop $(docker ps -aq)
|
|
||||||
docker container prune -f
|
|
||||||
- task: CmdLine@2
|
|
||||||
displayName: Prepare unittests and coverage for upload
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
mkdir output-e2e
|
|
||||||
mv unittest.xml output-e2e/unittest.xml
|
|
||||||
mv .coverage output-e2e/coverage
|
|
||||||
- task: PublishPipelineArtifact@1
|
|
||||||
condition: failed()
|
|
||||||
displayName: Upload screenshots if selenium tests fail
|
|
||||||
inputs:
|
|
||||||
targetPath: 'selenium_screenshots/'
|
|
||||||
artifact: 'selenium screenshots'
|
|
||||||
publishLocation: 'pipeline'
|
|
||||||
- task: PublishPipelineArtifact@1
|
|
||||||
inputs:
|
|
||||||
targetPath: 'output-e2e/'
|
|
||||||
artifact: 'coverage-e2e'
|
|
||||||
publishLocation: 'pipeline'
|
|
||||||
- stage: test_combine
|
|
||||||
jobs:
|
|
||||||
- job: test_coverage_combine
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: 'coverage-e2e'
|
|
||||||
path: "coverage-e2e/"
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: 'coverage-integration'
|
|
||||||
path: "coverage-integration/"
|
|
||||||
- task: DownloadPipelineArtifact@2
|
|
||||||
inputs:
|
|
||||||
buildType: 'current'
|
|
||||||
artifactName: 'coverage-unittest'
|
|
||||||
path: "coverage-unittest/"
|
|
||||||
- task: UsePythonVersion@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '3.9'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y libxmlsec1-dev pkg-config
|
|
||||||
sudo pip install -U wheel pipenv
|
|
||||||
pipenv install --dev
|
|
||||||
pipenv run coverage combine coverage-e2e/coverage coverage-unittest/coverage coverage-integration/coverage
|
|
||||||
pipenv run coverage xml
|
|
||||||
pipenv run coverage html
|
|
||||||
- task: PublishCodeCoverageResults@1
|
|
||||||
inputs:
|
|
||||||
codeCoverageTool: 'Cobertura'
|
|
||||||
summaryFileLocation: 'coverage.xml'
|
|
||||||
pathToSources: '$(System.DefaultWorkingDirectory)'
|
|
||||||
- task: PublishTestResults@2
|
|
||||||
condition: succeededOrFailed()
|
|
||||||
inputs:
|
|
||||||
testResultsFormat: 'JUnit'
|
|
||||||
testResultsFiles: |
|
|
||||||
coverage-e2e/unittest.xml
|
|
||||||
coverage-integration/unittest.xml
|
|
||||||
coverage-unittest/unittest.xml
|
|
||||||
mergeTestResults: true
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: bash <(curl -s https://codecov.io/bash)
|
|
||||||
- stage: Build
|
|
||||||
jobs:
|
|
||||||
- job: build_server
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: Bash@3
|
|
||||||
inputs:
|
|
||||||
targetType: 'inline'
|
|
||||||
script: |
|
|
||||||
python ./scripts/az_do_set_branch.py
|
|
||||||
- task: Docker@2
|
|
||||||
inputs:
|
|
||||||
containerRegistry: 'beryjuorg-harbor'
|
|
||||||
repository: 'authentik/server'
|
|
||||||
command: 'build'
|
|
||||||
Dockerfile: 'Dockerfile'
|
|
||||||
tags: |
|
|
||||||
gh-$(branchName)
|
|
||||||
gh-$(branchName)-$(timestamp)
|
|
||||||
arguments: '--build-arg GIT_BUILD_HASH=$(Build.SourceVersion)'
|
|
||||||
- task: Docker@2
|
|
||||||
inputs:
|
|
||||||
containerRegistry: 'beryjuorg-harbor'
|
|
||||||
repository: 'authentik/server'
|
|
||||||
command: 'push'
|
|
||||||
tags: |
|
|
||||||
gh-$(branchName)
|
|
||||||
gh-$(branchName)-$(timestamp)
|
|
||||||
@ -60,7 +60,9 @@ func main() {
|
|||||||
for {
|
for {
|
||||||
go attemptStartBackend(g)
|
go attemptStartBackend(g)
|
||||||
ws.Start()
|
ws.Start()
|
||||||
go attemptProxyStart(ws, u)
|
if !config.G.Web.DisableEmbeddedOutpost {
|
||||||
|
go attemptProxyStart(ws, u)
|
||||||
|
}
|
||||||
|
|
||||||
<-ex
|
<-ex
|
||||||
running = false
|
running = false
|
||||||
|
|||||||
@ -21,7 +21,7 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
server:
|
server:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.8.3}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.8.4}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: server
|
command: server
|
||||||
environment:
|
environment:
|
||||||
@ -44,7 +44,7 @@ services:
|
|||||||
- "0.0.0.0:9000:9000"
|
- "0.0.0.0:9000:9000"
|
||||||
- "0.0.0.0:9443:9443"
|
- "0.0.0.0:9443:9443"
|
||||||
worker:
|
worker:
|
||||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.8.3}
|
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.8.4}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: worker
|
command: worker
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@ -27,9 +27,10 @@ type RedisConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WebConfig struct {
|
type WebConfig struct {
|
||||||
Listen string `yaml:"listen"`
|
Listen string `yaml:"listen"`
|
||||||
ListenTLS string `yaml:"listen_tls"`
|
ListenTLS string `yaml:"listen_tls"`
|
||||||
LoadLocalFiles bool `yaml:"load_local_files" env:"AUTHENTIK_WEB_LOAD_LOCAL_FILES"`
|
LoadLocalFiles bool `yaml:"load_local_files" env:"AUTHENTIK_WEB_LOAD_LOCAL_FILES"`
|
||||||
|
DisableEmbeddedOutpost bool `yaml:"disable_embedded_outpost" env:"AUTHENTIK_WEB__DISABLE_EMBEDDED_OUTPOST"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PathsConfig struct {
|
type PathsConfig struct {
|
||||||
|
|||||||
@ -17,4 +17,4 @@ func OutpostUserAgent() string {
|
|||||||
return fmt.Sprintf("authentik-outpost@%s (%s)", VERSION, BUILD())
|
return fmt.Sprintf("authentik-outpost@%s (%s)", VERSION, BUILD())
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERSION = "2021.8.3"
|
const VERSION = "2021.8.4"
|
||||||
|
|||||||
32
internal/outpost/ldap/close.go
Normal file
32
internal/outpost/ldap/close.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (ls *LDAPServer) Close(boundDN string, conn net.Conn) error {
|
||||||
|
for _, p := range ls.providers {
|
||||||
|
p.delayDeleteUserInfo(boundDN)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pi *ProviderInstance) delayDeleteUserInfo(dn string) {
|
||||||
|
ticker := time.NewTicker(30 * time.Second)
|
||||||
|
quit := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
pi.boundUsersMutex.Lock()
|
||||||
|
delete(pi.boundUsers, dn)
|
||||||
|
pi.boundUsersMutex.Unlock()
|
||||||
|
close(quit)
|
||||||
|
case <-quit:
|
||||||
|
ticker.Stop()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
goldap "github.com/go-ldap/ldap/v3"
|
goldap "github.com/go-ldap/ldap/v3"
|
||||||
@ -83,7 +82,6 @@ func (pi *ProviderInstance) Bind(username string, req BindRequest) (ldap.LDAPRes
|
|||||||
}
|
}
|
||||||
uisp.Finish()
|
uisp.Finish()
|
||||||
defer pi.boundUsersMutex.Unlock()
|
defer pi.boundUsersMutex.Unlock()
|
||||||
pi.delayDeleteUserInfo(username)
|
|
||||||
return ldap.LDAPResultSuccess, nil
|
return ldap.LDAPResultSuccess, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,25 +98,6 @@ func (pi *ProviderInstance) SearchAccessCheck(user api.UserSelf) *string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pi *ProviderInstance) delayDeleteUserInfo(dn string) {
|
|
||||||
ticker := time.NewTicker(30 * time.Second)
|
|
||||||
quit := make(chan struct{})
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-ticker.C:
|
|
||||||
pi.boundUsersMutex.Lock()
|
|
||||||
delete(pi.boundUsers, dn)
|
|
||||||
pi.boundUsersMutex.Unlock()
|
|
||||||
close(quit)
|
|
||||||
case <-quit:
|
|
||||||
ticker.Stop()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pi *ProviderInstance) TimerFlowCacheExpiry() {
|
func (pi *ProviderInstance) TimerFlowCacheExpiry() {
|
||||||
fe := outpost.NewFlowExecutor(context.Background(), pi.flowSlug, pi.s.ac.Client.GetConfig(), log.Fields{})
|
fe := outpost.NewFlowExecutor(context.Background(), pi.flowSlug, pi.s.ac.Client.GetConfig(), log.Fields{})
|
||||||
fe.Params.Add("goauthentik.io/outpost/ldap", "true")
|
fe.Params.Add("goauthentik.io/outpost/ldap", "true")
|
||||||
|
|||||||
@ -83,5 +83,6 @@ func NewServer(ac *ak.APIController) *LDAPServer {
|
|||||||
ls.defaultCert = &defaultCert
|
ls.defaultCert = &defaultCert
|
||||||
s.BindFunc("", ls)
|
s.BindFunc("", ls)
|
||||||
s.SearchFunc("", ls)
|
s.SearchFunc("", ls)
|
||||||
|
s.CloseFunc("", ls)
|
||||||
return ls
|
return ls
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ type providerBundle struct {
|
|||||||
Host string
|
Host string
|
||||||
|
|
||||||
endSessionUrl string
|
endSessionUrl string
|
||||||
|
Mode *api.ProxyMode
|
||||||
|
|
||||||
cert *tls.Certificate
|
cert *tls.Certificate
|
||||||
|
|
||||||
@ -38,8 +39,8 @@ func intToPointer(i int) *int {
|
|||||||
func (pb *providerBundle) replaceLocal(url string) string {
|
func (pb *providerBundle) replaceLocal(url string) string {
|
||||||
if strings.HasPrefix(url, "http://localhost:8000") {
|
if strings.HasPrefix(url, "http://localhost:8000") {
|
||||||
authentikHost, c := pb.s.ak.Outpost.Config["authentik_host"]
|
authentikHost, c := pb.s.ak.Outpost.Config["authentik_host"]
|
||||||
if !c {
|
if !c || authentikHost == "" {
|
||||||
pb.log.Warning("Outpost has localhost API Connection but no authentik_host is configured.")
|
pb.log.Warning("Outpost has localhost/blank API Connection but no authentik_host is configured.")
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
f := strings.ReplaceAll(url, "http://localhost:8000", authentikHost.(string))
|
f := strings.ReplaceAll(url, "http://localhost:8000", authentikHost.(string))
|
||||||
@ -49,6 +50,10 @@ func (pb *providerBundle) replaceLocal(url string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pb *providerBundle) prepareOpts(provider api.ProxyOutpostConfig) *options.Options {
|
func (pb *providerBundle) prepareOpts(provider api.ProxyOutpostConfig) *options.Options {
|
||||||
|
// We need to save the mode in the bundle
|
||||||
|
// Since for the embedded outpost we only switch for fully proxy providers
|
||||||
|
pb.Mode = provider.Mode
|
||||||
|
|
||||||
externalHost, err := url.Parse(provider.ExternalHost)
|
externalHost, err := url.Parse(provider.ExternalHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithError(err).Warning("Failed to parse URL, skipping provider")
|
log.WithError(err).Warning("Failed to parse URL, skipping provider")
|
||||||
|
|||||||
@ -121,7 +121,7 @@ func NewOAuthProxy(opts *options.Options, provider api.ProxyOutpostConfig, c *ht
|
|||||||
redirectURL.Path = fmt.Sprintf("%s/callback", opts.ProxyPrefix)
|
redirectURL.Path = fmt.Sprintf("%s/callback", opts.ProxyPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Printf("proxy instance configured for Client ID: %s", opts.ClientID)
|
logger.WithField("auth_url", opts.GetProvider().Data().LoginURL).WithField("client_id", opts.ClientID).Info("proxy instance configured")
|
||||||
|
|
||||||
sessionChain := buildSessionChain(opts, sessionStore)
|
sessionChain := buildSessionChain(opts, sessionStore)
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"goauthentik.io/api"
|
||||||
"goauthentik.io/internal/utils/web"
|
"goauthentik.io/internal/utils/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -36,10 +37,12 @@ func (ws *WebServer) configureProxy() {
|
|||||||
ws.m.PathPrefix("/").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
ws.m.PathPrefix("/").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
host := web.GetHost(r)
|
host := web.GetHost(r)
|
||||||
if ws.ProxyServer != nil {
|
if ws.ProxyServer != nil {
|
||||||
if _, ok := ws.ProxyServer.Handlers[host]; ok {
|
if p, ok := ws.ProxyServer.Handlers[host]; ok {
|
||||||
ws.log.WithField("host", host).Trace("routing to proxy outpost")
|
if *p.Mode == api.PROXYMODE_PROXY {
|
||||||
ws.ProxyServer.Handler(rw, r)
|
ws.log.WithField("host", host).Trace("routing to proxy outpost")
|
||||||
return
|
ws.ProxyServer.Handler(rw, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ws.log.WithField("host", host).Trace("routing to application server")
|
ws.log.WithField("host", host).Trace("routing to application server")
|
||||||
|
|||||||
2251
schema.yml
2251
schema.yml
File diff suppressed because it is too large
Load Diff
@ -1,13 +0,0 @@
|
|||||||
"""Helper script to get the actual branch name, docker safe"""
|
|
||||||
import os
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
env_pr_branch = "SYSTEM_PULLREQUEST_SOURCEBRANCH"
|
|
||||||
default_branch = "BUILD_SOURCEBRANCHNAME"
|
|
||||||
|
|
||||||
branch_name = os.environ[default_branch]
|
|
||||||
if env_pr_branch in os.environ:
|
|
||||||
branch_name = os.environ[env_pr_branch].replace("/", "-")
|
|
||||||
|
|
||||||
print("##vso[task.setvariable variable=branchName]%s" % branch_name)
|
|
||||||
print("##vso[task.setvariable variable=timestamp]%s" % int(time()))
|
|
||||||
7
scripts/ci_prepare.sh
Executable file
7
scripts/ci_prepare.sh
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
docker-compose -f scripts/ci.docker-compose.yml up -d
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y libxmlsec1-dev pkg-config
|
||||||
|
sudo pip install -U wheel pipenv
|
||||||
|
pipenv install --dev
|
||||||
|
pipenv run python -m scripts.generate_ci_config
|
||||||
16
scripts/gh_do_set_branch.py
Normal file
16
scripts/gh_do_set_branch.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
"""Helper script to get the actual branch name, docker safe"""
|
||||||
|
import os
|
||||||
|
from time import time
|
||||||
|
|
||||||
|
env_pr_branch = "GITHUB_HEAD_REF"
|
||||||
|
default_branch = "GITHUB_REF"
|
||||||
|
sha = "GITHUB_SHA"
|
||||||
|
|
||||||
|
branch_name = os.environ[default_branch]
|
||||||
|
if os.environ.get(env_pr_branch, "") != "":
|
||||||
|
branch_name = os.environ[env_pr_branch]
|
||||||
|
branch_name = branch_name.replace("refs/heads/", "").replace("/", "-")
|
||||||
|
|
||||||
|
print("##[set-output name=branchName]%s" % branch_name)
|
||||||
|
print("##[set-output name=timestamp]%s" % int(time()))
|
||||||
|
print("##[set-output name=sha]%s" % os.environ[sha])
|
||||||
@ -6,4 +6,3 @@ dist
|
|||||||
coverage
|
coverage
|
||||||
# don't lint generated code
|
# don't lint generated code
|
||||||
api/
|
api/
|
||||||
azure-pipelines.yml
|
|
||||||
|
|||||||
@ -1,93 +0,0 @@
|
|||||||
trigger:
|
|
||||||
batch: true
|
|
||||||
branches:
|
|
||||||
include:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
- version-*
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- stage: lint
|
|
||||||
jobs:
|
|
||||||
- job: eslint
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '16.x'
|
|
||||||
displayName: 'Install Node.js'
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'install'
|
|
||||||
workingDir: 'web/'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: make gen-web
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'custom'
|
|
||||||
workingDir: 'web/'
|
|
||||||
customCommand: 'run lint'
|
|
||||||
- job: prettier
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '16.x'
|
|
||||||
displayName: 'Install Node.js'
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'install'
|
|
||||||
workingDir: 'web/'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: make gen-web
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'custom'
|
|
||||||
workingDir: 'web/'
|
|
||||||
customCommand: 'run prettier-check'
|
|
||||||
- job: lit_analyse
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '16.x'
|
|
||||||
displayName: 'Install Node.js'
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'install'
|
|
||||||
workingDir: 'web/'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: make gen-web
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'custom'
|
|
||||||
workingDir: 'web/'
|
|
||||||
customCommand: 'run lit-analyse'
|
|
||||||
- stage: build_local
|
|
||||||
jobs:
|
|
||||||
- job: build
|
|
||||||
pool:
|
|
||||||
vmImage: 'ubuntu-latest'
|
|
||||||
steps:
|
|
||||||
- task: NodeTool@0
|
|
||||||
inputs:
|
|
||||||
versionSpec: '16.x'
|
|
||||||
displayName: 'Install Node.js'
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'install'
|
|
||||||
workingDir: 'web/'
|
|
||||||
- task: CmdLine@2
|
|
||||||
inputs:
|
|
||||||
script: make gen-web
|
|
||||||
- task: Npm@1
|
|
||||||
inputs:
|
|
||||||
command: 'custom'
|
|
||||||
workingDir: 'web/'
|
|
||||||
customCommand: 'run build'
|
|
||||||
306
web/package-lock.json
generated
306
web/package-lock.json
generated
@ -15,7 +15,7 @@
|
|||||||
"@babel/preset-env": "^7.15.0",
|
"@babel/preset-env": "^7.15.0",
|
||||||
"@babel/preset-typescript": "^7.15.0",
|
"@babel/preset-typescript": "^7.15.0",
|
||||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"@goauthentik/api": "^2021.8.2-1629997023",
|
"@goauthentik/api": "^2021.8.3-1630597235",
|
||||||
"@lingui/cli": "^3.10.2",
|
"@lingui/cli": "^3.10.2",
|
||||||
"@lingui/core": "^3.10.4",
|
"@lingui/core": "^3.10.4",
|
||||||
"@lingui/macro": "^3.10.2",
|
"@lingui/macro": "^3.10.2",
|
||||||
@ -25,13 +25,13 @@
|
|||||||
"@rollup/plugin-babel": "^5.3.0",
|
"@rollup/plugin-babel": "^5.3.0",
|
||||||
"@rollup/plugin-replace": "^3.0.0",
|
"@rollup/plugin-replace": "^3.0.0",
|
||||||
"@rollup/plugin-typescript": "^8.2.5",
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
"@sentry/browser": "^6.11.0",
|
"@sentry/browser": "^6.12.0",
|
||||||
"@sentry/tracing": "^6.11.0",
|
"@sentry/tracing": "^6.12.0",
|
||||||
"@types/chart.js": "^2.9.34",
|
"@types/chart.js": "^2.9.34",
|
||||||
"@types/codemirror": "5.60.2",
|
"@types/codemirror": "5.60.2",
|
||||||
"@types/grecaptcha": "^3.0.3",
|
"@types/grecaptcha": "^3.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
"@typescript-eslint/eslint-plugin": "^4.30.0",
|
||||||
"@typescript-eslint/parser": "^4.29.3",
|
"@typescript-eslint/parser": "^4.30.0",
|
||||||
"@webcomponents/webcomponentsjs": "^2.6.0",
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
||||||
"babel-plugin-macros": "^3.1.0",
|
"babel-plugin-macros": "^3.1.0",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
@ -1689,9 +1689,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@goauthentik/api": {
|
"node_modules/@goauthentik/api": {
|
||||||
"version": "2021.8.2-1629997023",
|
"version": "2021.8.3-1630597235",
|
||||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.2-1629997023.tgz",
|
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.3-1630597235.tgz",
|
||||||
"integrity": "sha512-j80ZOgU+ZP40WD6PGJzxYmVKeGEcNJLjRqAQDvVmdfxA1++O6Ul1hYk02kSrDpQRbjdqmuO3u3a9s/HHKEvkrw=="
|
"integrity": "sha512-W/AWgWE8WS8pWYPqy9JuzbzdYcTJ7aCjzgcLbOmD4roYTp1vP1znSZKx0zg9ZH7EBskFfDqm2eAueF1ktPC09g=="
|
||||||
},
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
@ -2276,13 +2276,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/browser": {
|
"node_modules/@sentry/browser": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.12.0.tgz",
|
||||||
"integrity": "sha512-Qr2QRA0t5/S9QQqxzYKvM9W8prvmiWuldfwRX4hubovXzcXLgUi4WK0/H612wSbYZ4dNAEcQbtlxFWJNN4wxdg==",
|
"integrity": "sha512-wsJi1NLOmfwtPNYxEC50dpDcVY7sdYckzwfqz1/zHrede1mtxpqSw+7iP4bHADOJXuF+ObYYTHND0v38GSXznQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/core": "6.11.0",
|
"@sentry/core": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2295,14 +2295,14 @@
|
|||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/core": {
|
"node_modules/@sentry/core": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.12.0.tgz",
|
||||||
"integrity": "sha512-09TB+f3pqEq8LFahFWHO6I/4DxHo+NcS52OkbWMDqEi6oNZRD7PhPn3i14LfjsYVv3u3AESU8oxSEGbFrr2UjQ==",
|
"integrity": "sha512-mU/zdjlzFHzdXDZCPZm8OeCw7c9xsbL49Mq0TrY0KJjLt4CJBkiq5SDTGfRsenBLgTedYhe5Z/J8Z+xVVq+MfQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/hub": "6.11.0",
|
"@sentry/hub": "6.12.0",
|
||||||
"@sentry/minimal": "6.11.0",
|
"@sentry/minimal": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2315,12 +2315,12 @@
|
|||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/hub": {
|
"node_modules/@sentry/hub": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.12.0.tgz",
|
||||||
"integrity": "sha512-pT9hf+ZJfVFpoZopoC+yJmFNclr4NPqPcl2cgguqCHb69DklD1NxgBNWK8D6X05qjnNFDF991U6t1mxP9HrGuw==",
|
"integrity": "sha512-yR/UQVU+ukr42bSYpeqvb989SowIXlKBanU0cqLFDmv5LPCnaQB8PGeXwJAwWhQgx44PARhmB82S6Xor8gYNxg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2333,12 +2333,12 @@
|
|||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/minimal": {
|
"node_modules/@sentry/minimal": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.12.0.tgz",
|
||||||
"integrity": "sha512-XkZ7qrdlGp4IM/gjGxf1Q575yIbl5RvPbg+WFeekpo16Ufvzx37Mr8c2xsZaWosISVyE6eyFpooORjUlzy8EDw==",
|
"integrity": "sha512-r3C54Q1KN+xIqUvcgX9DlcoWE7ezWvFk2pSu1Ojx9De81hVqR9u5T3sdSAP2Xma+um0zr6coOtDJG4WtYlOtsw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/hub": "6.11.0",
|
"@sentry/hub": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2351,14 +2351,14 @@
|
|||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/tracing": {
|
"node_modules/@sentry/tracing": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.12.0.tgz",
|
||||||
"integrity": "sha512-9VA1/SY++WeoMQI4K6n/sYgIdRtCu9NLWqmGqu/5kbOtESYFgAt1DqSyqGCr00ZjQiC2s7tkDkTNZb38K6KytQ==",
|
"integrity": "sha512-u10QHNknPBzbWSUUNMkvuH53sQd5NaBo6YdNPj4p5b7sE7445Sh0PwBpRbY3ZiUUiwyxV59fx9UQ4yVnPGxZQA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/hub": "6.11.0",
|
"@sentry/hub": "6.12.0",
|
||||||
"@sentry/minimal": "6.11.0",
|
"@sentry/minimal": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2371,19 +2371,19 @@
|
|||||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/types": {
|
"node_modules/@sentry/types": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
|
||||||
"integrity": "sha512-gm5H9eZhL6bsIy/h3T+/Fzzz2vINhHhqd92CjHle3w7uXdTdFV98i2pDpErBGNTSNzbntqOMifYEB5ENtZAvcg==",
|
"integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/utils": {
|
"node_modules/@sentry/utils": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
|
||||||
"integrity": "sha512-IOvyFHcnbRQxa++jO+ZUzRvFHEJ1cZjrBIQaNVc0IYF0twUOB5PTP6joTcix38ldaLeapaPZ9LGfudbvYvxkdg==",
|
"integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2557,12 +2557,12 @@
|
|||||||
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
|
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.30.0.tgz",
|
||||||
"integrity": "sha512-tBgfA3K/3TsZY46ROGvoRxQr1wBkclbVqRQep97MjVHJzcRBURRY3sNFqLk0/Xr//BY5hM9H2p/kp+6qim85SA==",
|
"integrity": "sha512-NgAnqk55RQ/SD+tZFD9aPwNSeHmDHHe5rtUyhIq0ZeCWZEvo4DK9rYz7v9HDuQZFvn320Ot+AikaCKMFKLlD0g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/experimental-utils": "4.29.3",
|
"@typescript-eslint/experimental-utils": "4.30.0",
|
||||||
"@typescript-eslint/scope-manager": "4.29.3",
|
"@typescript-eslint/scope-manager": "4.30.0",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"functional-red-black-tree": "^1.0.1",
|
"functional-red-black-tree": "^1.0.1",
|
||||||
"regexpp": "^3.1.0",
|
"regexpp": "^3.1.0",
|
||||||
@ -2601,14 +2601,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/experimental-utils": {
|
"node_modules/@typescript-eslint/experimental-utils": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.30.0.tgz",
|
||||||
"integrity": "sha512-ffIvbytTVWz+3keg+Sy94FG1QeOvmV9dP2YSdLFHw/ieLXWCa3U1TYu8IRCOpMv2/SPS8XqhM1+ou1YHsdzKrg==",
|
"integrity": "sha512-K8RNIX9GnBsv5v4TjtwkKtqMSzYpjqAQg/oSphtxf3xxdt6T0owqnpojztjjTcatSteH3hLj3t/kklKx87NPqw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/json-schema": "^7.0.7",
|
"@types/json-schema": "^7.0.7",
|
||||||
"@typescript-eslint/scope-manager": "4.29.3",
|
"@typescript-eslint/scope-manager": "4.30.0",
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/typescript-estree": "4.29.3",
|
"@typescript-eslint/typescript-estree": "4.30.0",
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
"eslint-utils": "^3.0.0"
|
"eslint-utils": "^3.0.0"
|
||||||
},
|
},
|
||||||
@ -2624,13 +2624,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.30.0.tgz",
|
||||||
"integrity": "sha512-jrHOV5g2u8ROghmspKoW7pN8T/qUzk0+DITun0MELptvngtMrwUJ1tv5zMI04CYVEUsSrN4jV7AKSv+I0y0EfQ==",
|
"integrity": "sha512-HJ0XuluSZSxeboLU7Q2VQ6eLlCwXPBOGnA7CqgBnz2Db3JRQYyBDJgQnop6TZ+rsbSx5gEdWhw4rE4mDa1FnZg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "4.29.3",
|
"@typescript-eslint/scope-manager": "4.30.0",
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/typescript-estree": "4.29.3",
|
"@typescript-eslint/typescript-estree": "4.30.0",
|
||||||
"debug": "^4.3.1"
|
"debug": "^4.3.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -2650,12 +2650,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.30.0.tgz",
|
||||||
"integrity": "sha512-x+w8BLXO7iWPkG5mEy9bA1iFRnk36p/goVlYobVWHyDw69YmaH9q6eA+Fgl7kYHmFvWlebUTUfhtIg4zbbl8PA==",
|
"integrity": "sha512-VJ/jAXovxNh7rIXCQbYhkyV2Y3Ac/0cVHP/FruTJSAUUm4Oacmn/nkN5zfWmWFEanN4ggP0vJSHOeajtHq3f8A==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/visitor-keys": "4.29.3"
|
"@typescript-eslint/visitor-keys": "4.30.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
||||||
@ -2666,9 +2666,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.30.0.tgz",
|
||||||
"integrity": "sha512-s1eV1lKNgoIYLAl1JUba8NhULmf+jOmmeFO1G5MN/RBCyyzg4TIOfIOICVNC06lor+Xmy4FypIIhFiJXOknhIg==",
|
"integrity": "sha512-YKldqbNU9K4WpTNwBqtAerQKLLW/X2A/j4yw92e3ZJYLx+BpKLeheyzoPfzIXHfM8BXfoleTdiYwpsvVPvHrDw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
"node": "^8.10.0 || ^10.13.0 || >=11.10.1"
|
||||||
},
|
},
|
||||||
@ -2678,12 +2678,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.30.0.tgz",
|
||||||
"integrity": "sha512-45oQJA0bxna4O5TMwz55/TpgjX1YrAPOI/rb6kPgmdnemRZx/dB0rsx+Ku8jpDvqTxcE1C/qEbVHbS3h0hflag==",
|
"integrity": "sha512-6WN7UFYvykr/U0Qgy4kz48iGPWILvYL34xXJxvDQeiRE018B7POspNRVtAZscWntEPZpFCx4hcz/XBT+erenfg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/visitor-keys": "4.29.3",
|
"@typescript-eslint/visitor-keys": "4.30.0",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"globby": "^11.0.3",
|
"globby": "^11.0.3",
|
||||||
"is-glob": "^4.0.1",
|
"is-glob": "^4.0.1",
|
||||||
@ -2718,11 +2718,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.30.0.tgz",
|
||||||
"integrity": "sha512-MGGfJvXT4asUTeVs0Q2m+sY63UsfnA+C/FDgBKV3itLBmM9H0u+URcneePtkd0at1YELmZK6HSolCqM4Fzs6yA==",
|
"integrity": "sha512-pNaaxDt/Ol/+JZwzP7MqWc8PJQTUhZwoee/PVlQ+iYoYhagccvoHnC9e4l+C/krQYYkENxznhVSDwClIbZVxRw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"eslint-visitor-keys": "^2.0.0"
|
"eslint-visitor-keys": "^2.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@ -9566,9 +9566,9 @@
|
|||||||
"integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="
|
"integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg=="
|
||||||
},
|
},
|
||||||
"@goauthentik/api": {
|
"@goauthentik/api": {
|
||||||
"version": "2021.8.2-1629997023",
|
"version": "2021.8.3-1630597235",
|
||||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.2-1629997023.tgz",
|
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.8.3-1630597235.tgz",
|
||||||
"integrity": "sha512-j80ZOgU+ZP40WD6PGJzxYmVKeGEcNJLjRqAQDvVmdfxA1++O6Ul1hYk02kSrDpQRbjdqmuO3u3a9s/HHKEvkrw=="
|
"integrity": "sha512-W/AWgWE8WS8pWYPqy9JuzbzdYcTJ7aCjzgcLbOmD4roYTp1vP1znSZKx0zg9ZH7EBskFfDqm2eAueF1ktPC09g=="
|
||||||
},
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.5.0",
|
"version": "0.5.0",
|
||||||
@ -10022,13 +10022,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/browser": {
|
"@sentry/browser": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.12.0.tgz",
|
||||||
"integrity": "sha512-Qr2QRA0t5/S9QQqxzYKvM9W8prvmiWuldfwRX4hubovXzcXLgUi4WK0/H612wSbYZ4dNAEcQbtlxFWJNN4wxdg==",
|
"integrity": "sha512-wsJi1NLOmfwtPNYxEC50dpDcVY7sdYckzwfqz1/zHrede1mtxpqSw+7iP4bHADOJXuF+ObYYTHND0v38GSXznQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/core": "6.11.0",
|
"@sentry/core": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10040,14 +10040,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/core": {
|
"@sentry/core": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.12.0.tgz",
|
||||||
"integrity": "sha512-09TB+f3pqEq8LFahFWHO6I/4DxHo+NcS52OkbWMDqEi6oNZRD7PhPn3i14LfjsYVv3u3AESU8oxSEGbFrr2UjQ==",
|
"integrity": "sha512-mU/zdjlzFHzdXDZCPZm8OeCw7c9xsbL49Mq0TrY0KJjLt4CJBkiq5SDTGfRsenBLgTedYhe5Z/J8Z+xVVq+MfQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/hub": "6.11.0",
|
"@sentry/hub": "6.12.0",
|
||||||
"@sentry/minimal": "6.11.0",
|
"@sentry/minimal": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10059,12 +10059,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/hub": {
|
"@sentry/hub": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.12.0.tgz",
|
||||||
"integrity": "sha512-pT9hf+ZJfVFpoZopoC+yJmFNclr4NPqPcl2cgguqCHb69DklD1NxgBNWK8D6X05qjnNFDF991U6t1mxP9HrGuw==",
|
"integrity": "sha512-yR/UQVU+ukr42bSYpeqvb989SowIXlKBanU0cqLFDmv5LPCnaQB8PGeXwJAwWhQgx44PARhmB82S6Xor8gYNxg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10076,12 +10076,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/minimal": {
|
"@sentry/minimal": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.12.0.tgz",
|
||||||
"integrity": "sha512-XkZ7qrdlGp4IM/gjGxf1Q575yIbl5RvPbg+WFeekpo16Ufvzx37Mr8c2xsZaWosISVyE6eyFpooORjUlzy8EDw==",
|
"integrity": "sha512-r3C54Q1KN+xIqUvcgX9DlcoWE7ezWvFk2pSu1Ojx9De81hVqR9u5T3sdSAP2Xma+um0zr6coOtDJG4WtYlOtsw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/hub": "6.11.0",
|
"@sentry/hub": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10093,14 +10093,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/tracing": {
|
"@sentry/tracing": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.12.0.tgz",
|
||||||
"integrity": "sha512-9VA1/SY++WeoMQI4K6n/sYgIdRtCu9NLWqmGqu/5kbOtESYFgAt1DqSyqGCr00ZjQiC2s7tkDkTNZb38K6KytQ==",
|
"integrity": "sha512-u10QHNknPBzbWSUUNMkvuH53sQd5NaBo6YdNPj4p5b7sE7445Sh0PwBpRbY3ZiUUiwyxV59fx9UQ4yVnPGxZQA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/hub": "6.11.0",
|
"@sentry/hub": "6.12.0",
|
||||||
"@sentry/minimal": "6.11.0",
|
"@sentry/minimal": "6.12.0",
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"@sentry/utils": "6.11.0",
|
"@sentry/utils": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10112,16 +10112,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sentry/types": {
|
"@sentry/types": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
|
||||||
"integrity": "sha512-gm5H9eZhL6bsIy/h3T+/Fzzz2vINhHhqd92CjHle3w7uXdTdFV98i2pDpErBGNTSNzbntqOMifYEB5ENtZAvcg=="
|
"integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA=="
|
||||||
},
|
},
|
||||||
"@sentry/utils": {
|
"@sentry/utils": {
|
||||||
"version": "6.11.0",
|
"version": "6.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
|
||||||
"integrity": "sha512-IOvyFHcnbRQxa++jO+ZUzRvFHEJ1cZjrBIQaNVc0IYF0twUOB5PTP6joTcix38ldaLeapaPZ9LGfudbvYvxkdg==",
|
"integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@sentry/types": "6.11.0",
|
"@sentry/types": "6.12.0",
|
||||||
"tslib": "^1.9.3"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -10292,12 +10292,12 @@
|
|||||||
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
|
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
|
||||||
},
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.30.0.tgz",
|
||||||
"integrity": "sha512-tBgfA3K/3TsZY46ROGvoRxQr1wBkclbVqRQep97MjVHJzcRBURRY3sNFqLk0/Xr//BY5hM9H2p/kp+6qim85SA==",
|
"integrity": "sha512-NgAnqk55RQ/SD+tZFD9aPwNSeHmDHHe5rtUyhIq0ZeCWZEvo4DK9rYz7v9HDuQZFvn320Ot+AikaCKMFKLlD0g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/experimental-utils": "4.29.3",
|
"@typescript-eslint/experimental-utils": "4.30.0",
|
||||||
"@typescript-eslint/scope-manager": "4.29.3",
|
"@typescript-eslint/scope-manager": "4.30.0",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"functional-red-black-tree": "^1.0.1",
|
"functional-red-black-tree": "^1.0.1",
|
||||||
"regexpp": "^3.1.0",
|
"regexpp": "^3.1.0",
|
||||||
@ -10316,50 +10316,50 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/experimental-utils": {
|
"@typescript-eslint/experimental-utils": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.30.0.tgz",
|
||||||
"integrity": "sha512-ffIvbytTVWz+3keg+Sy94FG1QeOvmV9dP2YSdLFHw/ieLXWCa3U1TYu8IRCOpMv2/SPS8XqhM1+ou1YHsdzKrg==",
|
"integrity": "sha512-K8RNIX9GnBsv5v4TjtwkKtqMSzYpjqAQg/oSphtxf3xxdt6T0owqnpojztjjTcatSteH3hLj3t/kklKx87NPqw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/json-schema": "^7.0.7",
|
"@types/json-schema": "^7.0.7",
|
||||||
"@typescript-eslint/scope-manager": "4.29.3",
|
"@typescript-eslint/scope-manager": "4.30.0",
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/typescript-estree": "4.29.3",
|
"@typescript-eslint/typescript-estree": "4.30.0",
|
||||||
"eslint-scope": "^5.1.1",
|
"eslint-scope": "^5.1.1",
|
||||||
"eslint-utils": "^3.0.0"
|
"eslint-utils": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/parser": {
|
"@typescript-eslint/parser": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.30.0.tgz",
|
||||||
"integrity": "sha512-jrHOV5g2u8ROghmspKoW7pN8T/qUzk0+DITun0MELptvngtMrwUJ1tv5zMI04CYVEUsSrN4jV7AKSv+I0y0EfQ==",
|
"integrity": "sha512-HJ0XuluSZSxeboLU7Q2VQ6eLlCwXPBOGnA7CqgBnz2Db3JRQYyBDJgQnop6TZ+rsbSx5gEdWhw4rE4mDa1FnZg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/scope-manager": "4.29.3",
|
"@typescript-eslint/scope-manager": "4.30.0",
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/typescript-estree": "4.29.3",
|
"@typescript-eslint/typescript-estree": "4.30.0",
|
||||||
"debug": "^4.3.1"
|
"debug": "^4.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/scope-manager": {
|
"@typescript-eslint/scope-manager": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.30.0.tgz",
|
||||||
"integrity": "sha512-x+w8BLXO7iWPkG5mEy9bA1iFRnk36p/goVlYobVWHyDw69YmaH9q6eA+Fgl7kYHmFvWlebUTUfhtIg4zbbl8PA==",
|
"integrity": "sha512-VJ/jAXovxNh7rIXCQbYhkyV2Y3Ac/0cVHP/FruTJSAUUm4Oacmn/nkN5zfWmWFEanN4ggP0vJSHOeajtHq3f8A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/visitor-keys": "4.29.3"
|
"@typescript-eslint/visitor-keys": "4.30.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/types": {
|
"@typescript-eslint/types": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.30.0.tgz",
|
||||||
"integrity": "sha512-s1eV1lKNgoIYLAl1JUba8NhULmf+jOmmeFO1G5MN/RBCyyzg4TIOfIOICVNC06lor+Xmy4FypIIhFiJXOknhIg=="
|
"integrity": "sha512-YKldqbNU9K4WpTNwBqtAerQKLLW/X2A/j4yw92e3ZJYLx+BpKLeheyzoPfzIXHfM8BXfoleTdiYwpsvVPvHrDw=="
|
||||||
},
|
},
|
||||||
"@typescript-eslint/typescript-estree": {
|
"@typescript-eslint/typescript-estree": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.30.0.tgz",
|
||||||
"integrity": "sha512-45oQJA0bxna4O5TMwz55/TpgjX1YrAPOI/rb6kPgmdnemRZx/dB0rsx+Ku8jpDvqTxcE1C/qEbVHbS3h0hflag==",
|
"integrity": "sha512-6WN7UFYvykr/U0Qgy4kz48iGPWILvYL34xXJxvDQeiRE018B7POspNRVtAZscWntEPZpFCx4hcz/XBT+erenfg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"@typescript-eslint/visitor-keys": "4.29.3",
|
"@typescript-eslint/visitor-keys": "4.30.0",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"globby": "^11.0.3",
|
"globby": "^11.0.3",
|
||||||
"is-glob": "^4.0.1",
|
"is-glob": "^4.0.1",
|
||||||
@ -10378,11 +10378,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/visitor-keys": {
|
"@typescript-eslint/visitor-keys": {
|
||||||
"version": "4.29.3",
|
"version": "4.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.30.0.tgz",
|
||||||
"integrity": "sha512-MGGfJvXT4asUTeVs0Q2m+sY63UsfnA+C/FDgBKV3itLBmM9H0u+URcneePtkd0at1YELmZK6HSolCqM4Fzs6yA==",
|
"integrity": "sha512-pNaaxDt/Ol/+JZwzP7MqWc8PJQTUhZwoee/PVlQ+iYoYhagccvoHnC9e4l+C/krQYYkENxznhVSDwClIbZVxRw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/types": "4.29.3",
|
"@typescript-eslint/types": "4.30.0",
|
||||||
"eslint-visitor-keys": "^2.0.0"
|
"eslint-visitor-keys": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -46,7 +46,7 @@
|
|||||||
"@babel/preset-env": "^7.15.0",
|
"@babel/preset-env": "^7.15.0",
|
||||||
"@babel/preset-typescript": "^7.15.0",
|
"@babel/preset-typescript": "^7.15.0",
|
||||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"@goauthentik/api": "^2021.8.2-1629997023",
|
"@goauthentik/api": "^2021.8.3-1630597235",
|
||||||
"@lingui/cli": "^3.10.2",
|
"@lingui/cli": "^3.10.2",
|
||||||
"@lingui/core": "^3.10.4",
|
"@lingui/core": "^3.10.4",
|
||||||
"@lingui/macro": "^3.10.2",
|
"@lingui/macro": "^3.10.2",
|
||||||
@ -56,13 +56,13 @@
|
|||||||
"@rollup/plugin-babel": "^5.3.0",
|
"@rollup/plugin-babel": "^5.3.0",
|
||||||
"@rollup/plugin-replace": "^3.0.0",
|
"@rollup/plugin-replace": "^3.0.0",
|
||||||
"@rollup/plugin-typescript": "^8.2.5",
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
"@sentry/browser": "^6.11.0",
|
"@sentry/browser": "^6.12.0",
|
||||||
"@sentry/tracing": "^6.11.0",
|
"@sentry/tracing": "^6.12.0",
|
||||||
"@types/chart.js": "^2.9.34",
|
"@types/chart.js": "^2.9.34",
|
||||||
"@types/codemirror": "5.60.2",
|
"@types/codemirror": "5.60.2",
|
||||||
"@types/grecaptcha": "^3.0.3",
|
"@types/grecaptcha": "^3.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.29.3",
|
"@typescript-eslint/eslint-plugin": "^4.30.0",
|
||||||
"@typescript-eslint/parser": "^4.29.3",
|
"@typescript-eslint/parser": "^4.30.0",
|
||||||
"@webcomponents/webcomponentsjs": "^2.6.0",
|
"@webcomponents/webcomponentsjs": "^2.6.0",
|
||||||
"babel-plugin-macros": "^3.1.0",
|
"babel-plugin-macros": "^3.1.0",
|
||||||
"base64-js": "^1.5.1",
|
"base64-js": "^1.5.1",
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { Config, Configuration, CoreApi, CurrentTenant, Middleware, ResponseCont
|
|||||||
import { getCookie } from "../utils";
|
import { getCookie } from "../utils";
|
||||||
import { APIMiddleware } from "../elements/notifications/APIDrawer";
|
import { APIMiddleware } from "../elements/notifications/APIDrawer";
|
||||||
import { MessageMiddleware } from "../elements/messages/Middleware";
|
import { MessageMiddleware } from "../elements/messages/Middleware";
|
||||||
|
import { VERSION } from "../constants";
|
||||||
|
|
||||||
export class LoggingMiddleware implements Middleware {
|
export class LoggingMiddleware implements Middleware {
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ export function tenant(): Promise<CurrentTenant> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_CONFIG = new Configuration({
|
export const DEFAULT_CONFIG = new Configuration({
|
||||||
basePath: "",
|
basePath: "/api/v3",
|
||||||
headers: {
|
headers: {
|
||||||
"X-CSRFToken": getCookie("authentik_csrf"),
|
"X-CSRFToken": getCookie("authentik_csrf"),
|
||||||
},
|
},
|
||||||
@ -59,3 +60,5 @@ export const DEFAULT_CONFIG = new Configuration({
|
|||||||
new LoggingMiddleware(),
|
new LoggingMiddleware(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.debug(`authentik(early): version ${VERSION}`);
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export function configureSentry(canDoPpi: boolean = false): Promise<Config> {
|
|||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8",
|
dsn: "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8",
|
||||||
release: `authentik@${VERSION}`,
|
release: `authentik@${VERSION}`,
|
||||||
tunnel: "/api/v2beta/sentry/",
|
tunnel: "/api/v3/sentry/",
|
||||||
integrations: [
|
integrations: [
|
||||||
new Integrations.BrowserTracing({
|
new Integrations.BrowserTracing({
|
||||||
tracingOrigins: [window.location.host, "localhost"],
|
tracingOrigins: [window.location.host, "localhost"],
|
||||||
|
|||||||
@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
|
|||||||
export const ERROR_CLASS = "pf-m-danger";
|
export const ERROR_CLASS = "pf-m-danger";
|
||||||
export const PROGRESS_CLASS = "pf-m-in-progress";
|
export const PROGRESS_CLASS = "pf-m-in-progress";
|
||||||
export const CURRENT_CLASS = "pf-m-current";
|
export const CURRENT_CLASS = "pf-m-current";
|
||||||
export const VERSION = "2021.8.3";
|
export const VERSION = "2021.8.4";
|
||||||
export const PAGE_SIZE = 20;
|
export const PAGE_SIZE = 20;
|
||||||
export const TITLE_DEFAULT = "authentik";
|
export const TITLE_DEFAULT = "authentik";
|
||||||
export const ROUTE_SEPARATOR = ";";
|
export const ROUTE_SEPARATOR = ";";
|
||||||
|
|||||||
@ -224,9 +224,15 @@ export class Form<T> extends LitElement {
|
|||||||
throw ex;
|
throw ex;
|
||||||
})
|
})
|
||||||
.catch((ex: Error) => {
|
.catch((ex: Error) => {
|
||||||
|
let msg = ex.toString();
|
||||||
|
// Only change the message when we have `detail`.
|
||||||
|
// Everything else is handled in the form.
|
||||||
|
if (ex instanceof APIError && "detail" in ex.response) {
|
||||||
|
msg = ex.response.detail;
|
||||||
|
}
|
||||||
// error is local or not from rest_framework
|
// error is local or not from rest_framework
|
||||||
showMessage({
|
showMessage({
|
||||||
message: ex.toString(),
|
message: msg,
|
||||||
level: MessageLevel.error,
|
level: MessageLevel.error,
|
||||||
});
|
});
|
||||||
// rethrow the error so the form doesn't close
|
// rethrow the error so the form doesn't close
|
||||||
|
|||||||
@ -77,6 +77,7 @@ export class FlowExecutor extends LitElement implements StageHost {
|
|||||||
document.title = tenant.brandingTitle || TITLE_DEFAULT;
|
document.title = tenant.brandingTitle || TITLE_DEFAULT;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
get challenge(): ChallengeTypes | undefined {
|
get challenge(): ChallengeTypes | undefined {
|
||||||
|
|||||||
@ -180,7 +180,7 @@ export class AuthenticatorValidateStage
|
|||||||
${this.selectedDeviceChallenge
|
${this.selectedDeviceChallenge
|
||||||
? ""
|
? ""
|
||||||
: html`<p class="pf-c-login__main-header-desc">
|
: html`<p class="pf-c-login__main-header-desc">
|
||||||
${t`Select an identification method.`}
|
${t`Select an authentication method.`}
|
||||||
</p>`}
|
</p>`}
|
||||||
</header>
|
</header>
|
||||||
${this.selectedDeviceChallenge
|
${this.selectedDeviceChallenge
|
||||||
|
|||||||
@ -3370,6 +3370,10 @@ msgstr "Request token URL"
|
|||||||
msgid "Required"
|
msgid "Required"
|
||||||
msgstr "Required"
|
msgstr "Required"
|
||||||
|
|
||||||
|
#: src/flows/stages/prompt/PromptStage.ts
|
||||||
|
msgid "Required."
|
||||||
|
msgstr "Required."
|
||||||
|
|
||||||
#: src/pages/user-settings/UserSelfForm.ts
|
#: src/pages/user-settings/UserSelfForm.ts
|
||||||
#: src/pages/users/ServiceAccountForm.ts
|
#: src/pages/users/ServiceAccountForm.ts
|
||||||
#: src/pages/users/UserForm.ts
|
#: src/pages/users/UserForm.ts
|
||||||
@ -3524,13 +3528,17 @@ msgstr "Select a provider that this application should use. Alternatively, creat
|
|||||||
msgid "Select all rows"
|
msgid "Select all rows"
|
||||||
msgstr "Select all rows"
|
msgstr "Select all rows"
|
||||||
|
|
||||||
|
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
|
||||||
|
msgid "Select an authentication method."
|
||||||
|
msgstr "Select an authentication method."
|
||||||
|
|
||||||
#: src/pages/stages/invitation/InvitationListLink.ts
|
#: src/pages/stages/invitation/InvitationListLink.ts
|
||||||
msgid "Select an enrollment flow"
|
msgid "Select an enrollment flow"
|
||||||
msgstr "Select an enrollment flow"
|
msgstr "Select an enrollment flow"
|
||||||
|
|
||||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
|
#:
|
||||||
msgid "Select an identification method."
|
#~ msgid "Select an identification method."
|
||||||
msgstr "Select an identification method."
|
#~ msgstr "Select an identification method."
|
||||||
|
|
||||||
#: src/pages/users/GroupSelectModal.ts
|
#: src/pages/users/GroupSelectModal.ts
|
||||||
msgid "Select groups to add user to"
|
msgid "Select groups to add user to"
|
||||||
@ -3757,9 +3765,13 @@ msgstr "Source(s)"
|
|||||||
msgid "Sources"
|
msgid "Sources"
|
||||||
msgstr "Sources"
|
msgstr "Sources"
|
||||||
|
|
||||||
|
#:
|
||||||
|
#~ msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
|
||||||
|
#~ msgstr "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
|
||||||
|
|
||||||
#: src/pages/sources/SourcesListPage.ts
|
#: src/pages/sources/SourcesListPage.ts
|
||||||
msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
|
msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves."
|
||||||
msgstr "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
|
msgstr "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves."
|
||||||
|
|
||||||
#: src/pages/flows/BoundStagesList.ts
|
#: src/pages/flows/BoundStagesList.ts
|
||||||
#: src/pages/flows/StageBindingForm.ts
|
#: src/pages/flows/StageBindingForm.ts
|
||||||
|
|||||||
@ -3362,6 +3362,10 @@ msgstr ""
|
|||||||
msgid "Required"
|
msgid "Required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/flows/stages/prompt/PromptStage.ts
|
||||||
|
msgid "Required."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/user-settings/UserSelfForm.ts
|
#: src/pages/user-settings/UserSelfForm.ts
|
||||||
#: src/pages/users/ServiceAccountForm.ts
|
#: src/pages/users/ServiceAccountForm.ts
|
||||||
#: src/pages/users/UserForm.ts
|
#: src/pages/users/UserForm.ts
|
||||||
@ -3516,13 +3520,17 @@ msgstr ""
|
|||||||
msgid "Select all rows"
|
msgid "Select all rows"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
|
||||||
|
msgid "Select an authentication method."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/stages/invitation/InvitationListLink.ts
|
#: src/pages/stages/invitation/InvitationListLink.ts
|
||||||
msgid "Select an enrollment flow"
|
msgid "Select an enrollment flow"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
|
#:
|
||||||
msgid "Select an identification method."
|
#~ msgid "Select an identification method."
|
||||||
msgstr ""
|
#~ msgstr ""
|
||||||
|
|
||||||
#: src/pages/users/GroupSelectModal.ts
|
#: src/pages/users/GroupSelectModal.ts
|
||||||
msgid "Select groups to add user to"
|
msgid "Select groups to add user to"
|
||||||
@ -3749,8 +3757,12 @@ msgstr ""
|
|||||||
msgid "Sources"
|
msgid "Sources"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#:
|
||||||
|
#~ msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
|
||||||
|
#~ msgstr ""
|
||||||
|
|
||||||
#: src/pages/sources/SourcesListPage.ts
|
#: src/pages/sources/SourcesListPage.ts
|
||||||
msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
|
msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/flows/BoundStagesList.ts
|
#: src/pages/flows/BoundStagesList.ts
|
||||||
|
|||||||
@ -32,7 +32,6 @@ export class SystemStatusCard extends AdminStatusCard<System> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
const timeDiff = value.serverTime.getTime() - (this.now || new Date()).getTime();
|
const timeDiff = value.serverTime.getTime() - (this.now || new Date()).getTime();
|
||||||
console.log(`authentik/: timediff ${timeDiff}`);
|
|
||||||
if (timeDiff > 5000 || timeDiff < -5000) {
|
if (timeDiff > 5000 || timeDiff < -5000) {
|
||||||
this.header = t`Warning`;
|
this.header = t`Warning`;
|
||||||
return Promise.resolve<AdminStatus>({
|
return Promise.resolve<AdminStatus>({
|
||||||
|
|||||||
@ -243,7 +243,7 @@ export class FlowForm extends ModelForm<Flow, string> {
|
|||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="pf-c-check__input"
|
class="pf-c-check__input"
|
||||||
?checked=${first(this.instance?.compatibilityMode, true)}
|
?checked=${first(this.instance?.compatibilityMode, false)}
|
||||||
/>
|
/>
|
||||||
<label class="pf-c-check__label"> ${t`Compatibility mode`} </label>
|
<label class="pf-c-check__label"> ${t`Compatibility mode`} </label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -101,9 +101,7 @@ export class FlowListPage extends TablePage<Flow> {
|
|||||||
slug: item.slug,
|
slug: item.slug,
|
||||||
})
|
})
|
||||||
.then((link) => {
|
.then((link) => {
|
||||||
window.location.assign(
|
window.open(`${link.link}?next=/%23${window.location.href}`);
|
||||||
`${link.link}?next=/%23${window.location.href}`,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export class SourceListPage extends TablePage<Source> {
|
|||||||
return t`Sources`;
|
return t`Sources`;
|
||||||
}
|
}
|
||||||
pageDescription(): string | undefined {
|
pageDescription(): string | undefined {
|
||||||
return t`Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins`;
|
return t`Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.`;
|
||||||
}
|
}
|
||||||
pageIcon(): string {
|
pageIcon(): string {
|
||||||
return "pf-icon pf-icon-middleware";
|
return "pf-icon pf-icon-middleware";
|
||||||
|
|||||||
@ -48,6 +48,9 @@ export class InvitationListLink extends LitElement {
|
|||||||
designation: FlowsInstancesListDesignationEnum.Enrollment,
|
designation: FlowsInstancesListDesignationEnum.Enrollment,
|
||||||
})
|
})
|
||||||
.then((flows) => {
|
.then((flows) => {
|
||||||
|
if (!this.selectedFlow && flows.results.length > 0) {
|
||||||
|
this.selectedFlow = flows.results[0].slug;
|
||||||
|
}
|
||||||
return flows.results.map((flow) => {
|
return flows.results.map((flow) => {
|
||||||
return html`<option
|
return html`<option
|
||||||
value=${flow.slug}
|
value=${flow.slug}
|
||||||
|
|||||||
@ -103,7 +103,7 @@ export class TokenListPage extends TablePage<Token> {
|
|||||||
row(item: Token): TemplateResult[] {
|
row(item: Token): TemplateResult[] {
|
||||||
return [
|
return [
|
||||||
html`${item.identifier}`,
|
html`${item.identifier}`,
|
||||||
html`${item.userObj?.username}`,
|
html`<a href="#/identity/users/${item.userObj?.pk}">${item.userObj?.username}</a>`,
|
||||||
html`${item.expiring ? t`Yes` : t`No`}`,
|
html`${item.expiring ? t`Yes` : t`No`}`,
|
||||||
html`${item.expiring ? item.expires?.toLocaleString() : "-"}`,
|
html`${item.expiring ? item.expires?.toLocaleString() : "-"}`,
|
||||||
html`${IntentToLabel(item.intent || IntentEnum.Api)}`,
|
html`${IntentToLabel(item.intent || IntentEnum.Api)}`,
|
||||||
|
|||||||
@ -51,10 +51,14 @@ export class UserSettingsAuthenticatorWebAuthn extends BaseUserSettings {
|
|||||||
slot="form"
|
slot="form"
|
||||||
successMessage=${t`Successfully updated device.`}
|
successMessage=${t`Successfully updated device.`}
|
||||||
.send=${(data: unknown) => {
|
.send=${(data: unknown) => {
|
||||||
return new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsWebauthnUpdate({
|
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||||
id: device.pk || 0,
|
.authenticatorsWebauthnUpdate({
|
||||||
webAuthnDeviceRequest: data as WebAuthnDevice,
|
id: device.pk || 0,
|
||||||
});
|
webAuthnDeviceRequest: data as WebAuthnDevice,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.requestUpdate();
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<form class="pf-c-form pf-m-horizontal">
|
<form class="pf-c-form pf-m-horizontal">
|
||||||
|
|||||||
@ -2,9 +2,9 @@
|
|||||||
title: API
|
title: API
|
||||||
---
|
---
|
||||||
|
|
||||||
Starting with 2021.3.5, every authentik instance has a built-in API browser, which can be accessed at https://authentik.company/api/v2beta/.
|
Starting with 2021.3.5, every authentik instance has a built-in API browser, which can be accessed at https://authentik.company/api/v3/.
|
||||||
|
|
||||||
To generate an API client, you can use the OpenAPI v3 schema at https://authentik.company/api/v2beta/schema/.
|
To generate an API client, you can use the OpenAPI v3 schema at https://authentik.company/api/v3/schema/.
|
||||||
|
|
||||||
While testing, the API requests are authenticated by your browser session.
|
While testing, the API requests are authenticated by your browser session.
|
||||||
|
|
||||||
@ -10,13 +10,13 @@ However, any flow can be executed via an API from anywhere, in fact that is what
|
|||||||
Because the flow executor stores its state in the HTTP Session, so you need to ensure cookies between flow executor requests are persisted.
|
Because the flow executor stores its state in the HTTP Session, so you need to ensure cookies between flow executor requests are persisted.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
The main endpoint for flow execution is `/api/v2beta/flows/executor/:slug`.
|
The main endpoint for flow execution is `/api/v3/flows/executor/:slug`.
|
||||||
|
|
||||||
This endpoint accepts a query parameter called `query`, in which the flow executor sends the full Query-string.
|
This endpoint accepts a query parameter called `query`, in which the flow executor sends the full Query-string.
|
||||||
|
|
||||||
To initiate a new flow, execute a GET request.
|
To initiate a new flow, execute a GET request.
|
||||||
|
|
||||||
## `GET /api/v2beta/flows/executor/test-flow/`
|
## `GET /api/v3/flows/executor/test-flow/`
|
||||||
|
|
||||||
Below is the response, for example for an Identification stage.
|
Below is the response, for example for an Identification stage.
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ Below is the response, for example for an Identification stage.
|
|||||||
|
|
||||||
To respond to this challenge, send a response:
|
To respond to this challenge, send a response:
|
||||||
|
|
||||||
## `POST /api/v2beta/flows/executor/test-flow/`
|
## `POST /api/v3/flows/executor/test-flow/`
|
||||||
|
|
||||||
With this body
|
With this body
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ Depending on the flow, you'll either get a 200 Response with another challenge,
|
|||||||
|
|
||||||
Depending also on the stage, a response might take longer to be returned (especially with the Duo Authenticator validation).
|
Depending also on the stage, a response might take longer to be returned (especially with the Duo Authenticator validation).
|
||||||
|
|
||||||
To see the data layout for every stage possible, see the [API Browser](https://goauthentik.io/api/#get-/api/v2beta/flows/executor/-flow_slug-/)
|
To see the data layout for every stage possible, see the [API Browser](https://goauthentik.io/api/#get-/api/v3/flows/executor/-flow_slug-/)
|
||||||
|
|
||||||
## Result
|
## Result
|
||||||
|
|
||||||
48
website/developer-docs/api/websocket.md
Normal file
48
website/developer-docs/api/websocket.md
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
title: Websocket API
|
||||||
|
---
|
||||||
|
|
||||||
|
authentik has two different WebSocket endpoints, one is used for web-based clients to get real-time updates, and the other is used for outposts to report their healthiness.
|
||||||
|
|
||||||
|
|
||||||
|
### Web `/ws/client/`
|
||||||
|
|
||||||
|
:::info
|
||||||
|
Authentication is done using the session, so make sure to send the `Cookie` header.
|
||||||
|
:::
|
||||||
|
|
||||||
|
All messages have a common field called `message_type` to discern the type of message.
|
||||||
|
|
||||||
|
#### `message` type:
|
||||||
|
|
||||||
|
This type is used when the backend has a notice to show to the user. A full payload looks like:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"message_type": "message",
|
||||||
|
"level": "error" | "warning" | "success" | "info",
|
||||||
|
"tags": "",
|
||||||
|
"message": "a message",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Outpost `/ws/outpost/<outpost-uuid>/`
|
||||||
|
|
||||||
|
:::info
|
||||||
|
Authentication is done via the `Authorization` header, same as the regular API. You must send a valid token with a `Bearer ` prefix.
|
||||||
|
:::
|
||||||
|
|
||||||
|
All messages have two fields, `instruction` and `args`. Instruction is any number from this list:
|
||||||
|
|
||||||
|
- `0`: ACK, simply acknowledges the previous message
|
||||||
|
- `1`: HELLO, used for monitoring and regularly sent by outposts
|
||||||
|
- `2`: TRIGGER_UPDATE, sent by authentik to trigger a reload of the configuration
|
||||||
|
|
||||||
|
Arguments for these messages vary, all though these common args are always sent:
|
||||||
|
|
||||||
|
- `args['uuid']`: A unique UUID generated on startup of an outpost, used to uniquely identify it.
|
||||||
|
|
||||||
|
These fields are only sent for HELLO instructions:
|
||||||
|
|
||||||
|
- `args['version']`: Version of the outpost
|
||||||
|
- `args['buildHash']`: Build hash of the outpost, when available
|
||||||
@ -23,6 +23,21 @@ All of these variables can be set to values, but you can also use a URI-like for
|
|||||||
- `AUTHENTIK_POSTGRESQL__PORT`: Database port, defaults to 5432
|
- `AUTHENTIK_POSTGRESQL__PORT`: Database port, defaults to 5432
|
||||||
- `AUTHENTIK_POSTGRESQL__PASSWORD`: Database password, defaults to the environment variable `POSTGRES_PASSWORD`
|
- `AUTHENTIK_POSTGRESQL__PASSWORD`: Database password, defaults to the environment variable `POSTGRES_PASSWORD`
|
||||||
|
|
||||||
|
### PostgreSQL Backup Settings
|
||||||
|
|
||||||
|
Optionally enable automated database backups to S3 or S3-compatible storages.
|
||||||
|
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__ACCESS_KEY`: S3 Access Key
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__SECRET_KEY`: S3 Secret Key
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__BUCKET`: S3 Bucket
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__REGION`: S3 Region, defaults to `eu-central-1`
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__LOCATION`: Relative Location of the files to the bucket. Defaults to the root of the bucket.
|
||||||
|
|
||||||
|
To use an S3-compatible storage, set the following settings.
|
||||||
|
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__HOST`: URL to the Service, for example `https://play.min.io`
|
||||||
|
- `AUTHENTIK_POSTGRESQL__S3_BACKUP__INSECURE_SKIP_VERIFY`: Set to `true` to disable SSL Certificate verification.
|
||||||
|
|
||||||
## Redis Settings
|
## Redis Settings
|
||||||
|
|
||||||
- `AUTHENTIK_REDIS__HOST`: Hostname of your Redis Server
|
- `AUTHENTIK_REDIS__HOST`: Hostname of your Redis Server
|
||||||
|
|||||||
@ -12,9 +12,9 @@ This installation method is for test-setups and small-scale productive setups.
|
|||||||
|
|
||||||
## Preparation
|
## Preparation
|
||||||
|
|
||||||
Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/goauthentik/authentik/version/2021.8.3/docker-compose.yml). Place it in a directory of your choice.
|
Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/goauthentik/authentik/version/2021.8.4/docker-compose.yml). Place it in a directory of your choice.
|
||||||
|
|
||||||
To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.8.3 >> .env`
|
To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.8.4 >> .env`
|
||||||
|
|
||||||
If this is a fresh authentik install run the following commands to generate a password:
|
If this is a fresh authentik install run the following commands to generate a password:
|
||||||
|
|
||||||
|
|||||||
43
website/docs/outposts/embedded/embedded.md
Normal file
43
website/docs/outposts/embedded/embedded.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
title: Embedded Outpost
|
||||||
|
---
|
||||||
|
|
||||||
|
Starting with 2021.8.1, authentik comes with an embedded outpost. This has been added to simplify deployment for users using the Proxy provider.
|
||||||
|
|
||||||
|
The embedded outpost is ran in the main `server` container, and is managed by authentik itself. The embedded outpost authenticates itself via the secret key.
|
||||||
|
|
||||||
|
You can access the embedded outpost on the same ports as authentik itself, 9000 and 9443.
|
||||||
|
|
||||||
|
The embedded outpost cannot be disabled, if it doesn't make sense to use in your deployment you can simply ignore it.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Since the outpost uses OAuth2, there is some configuration required.
|
||||||
|
|
||||||
|
On a fresh authentik install, your Outpost list will look like this:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Click the edit button on the right of the colum, and set the value of `authentik_host` to the URL you want to login with.
|
||||||
|
Make sure to set it to full URL, only configuring a hostname or FQDN will not work.
|
||||||
|
|
||||||
|
### Routing
|
||||||
|
|
||||||
|
Routing is handled like this:
|
||||||
|
|
||||||
|
1. Paths starting with `/static`, `/media` and `/help` return packaged CSS/JS files, and user-uploaded media files.
|
||||||
|
2. Paths starting with `/akprox` are sent to the embedded outpost.
|
||||||
|
3. Any hosts configured in the providers assigned to the embedded outpost are sent to the outpost.
|
||||||
|
4. Everything remaining is sent to the authentik backend server.
|
||||||
|
|
||||||
|
### Differences
|
||||||
|
|
||||||
|
There are a few more differences between managed outposts and the embedded outpost, mainly due to the fact that authentik can't fully manage the containers.
|
||||||
|
|
||||||
|
1. (Docker-only) No automatic traefik labels are added to the server container.
|
||||||
|
|
||||||
|
When you deploy a managed outpost on docker, the container has several labels to automatically configure traefik. This is not done for the embedded outpost.
|
||||||
|
|
||||||
|
2. (Kubernetes-only) An additional service is created.
|
||||||
|
|
||||||
|
Since authentik does not know what the normal authentik Service is called, another one is created with a common set of labels that is always set.
|
||||||
BIN
website/docs/outposts/embedded/stock.png
Normal file
BIN
website/docs/outposts/embedded/stock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@ -11,7 +11,7 @@ version: "3.5"
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
authentik_proxy:
|
authentik_proxy:
|
||||||
image: ghcr.io/goauthentik/proxy:2021.8.3
|
image: ghcr.io/goauthentik/proxy:2021.8.4
|
||||||
ports:
|
ports:
|
||||||
- 4180:4180
|
- 4180:4180
|
||||||
- 4443:4443
|
- 4443:4443
|
||||||
@ -21,7 +21,7 @@ services:
|
|||||||
AUTHENTIK_TOKEN: token-generated-by-authentik
|
AUTHENTIK_TOKEN: token-generated-by-authentik
|
||||||
# Or, for the LDAP Outpost
|
# Or, for the LDAP Outpost
|
||||||
authentik_proxy:
|
authentik_proxy:
|
||||||
image: ghcr.io/goauthentik/ldap:2021.8.3
|
image: ghcr.io/goauthentik/ldap:2021.8.4
|
||||||
ports:
|
ports:
|
||||||
- 389:3389
|
- 389:3389
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
@ -14,7 +14,7 @@ metadata:
|
|||||||
app.kubernetes.io/instance: __OUTPOST_NAME__
|
app.kubernetes.io/instance: __OUTPOST_NAME__
|
||||||
app.kubernetes.io/managed-by: goauthentik.io
|
app.kubernetes.io/managed-by: goauthentik.io
|
||||||
app.kubernetes.io/name: authentik-proxy
|
app.kubernetes.io/name: authentik-proxy
|
||||||
app.kubernetes.io/version: 2021.8.3
|
app.kubernetes.io/version: 2021.8.4
|
||||||
name: authentik-outpost-api
|
name: authentik-outpost-api
|
||||||
stringData:
|
stringData:
|
||||||
authentik_host: "__AUTHENTIK_URL__"
|
authentik_host: "__AUTHENTIK_URL__"
|
||||||
@ -29,7 +29,7 @@ metadata:
|
|||||||
app.kubernetes.io/instance: __OUTPOST_NAME__
|
app.kubernetes.io/instance: __OUTPOST_NAME__
|
||||||
app.kubernetes.io/managed-by: goauthentik.io
|
app.kubernetes.io/managed-by: goauthentik.io
|
||||||
app.kubernetes.io/name: authentik-proxy
|
app.kubernetes.io/name: authentik-proxy
|
||||||
app.kubernetes.io/version: 2021.8.3
|
app.kubernetes.io/version: 2021.8.4
|
||||||
name: authentik-outpost
|
name: authentik-outpost
|
||||||
spec:
|
spec:
|
||||||
ports:
|
ports:
|
||||||
@ -54,7 +54,7 @@ metadata:
|
|||||||
app.kubernetes.io/instance: __OUTPOST_NAME__
|
app.kubernetes.io/instance: __OUTPOST_NAME__
|
||||||
app.kubernetes.io/managed-by: goauthentik.io
|
app.kubernetes.io/managed-by: goauthentik.io
|
||||||
app.kubernetes.io/name: authentik-proxy
|
app.kubernetes.io/name: authentik-proxy
|
||||||
app.kubernetes.io/version: 2021.8.3
|
app.kubernetes.io/version: 2021.8.4
|
||||||
name: authentik-outpost
|
name: authentik-outpost
|
||||||
spec:
|
spec:
|
||||||
selector:
|
selector:
|
||||||
@ -62,14 +62,14 @@ spec:
|
|||||||
app.kubernetes.io/instance: __OUTPOST_NAME__
|
app.kubernetes.io/instance: __OUTPOST_NAME__
|
||||||
app.kubernetes.io/managed-by: goauthentik.io
|
app.kubernetes.io/managed-by: goauthentik.io
|
||||||
app.kubernetes.io/name: authentik-proxy
|
app.kubernetes.io/name: authentik-proxy
|
||||||
app.kubernetes.io/version: 2021.8.3
|
app.kubernetes.io/version: 2021.8.4
|
||||||
template:
|
template:
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/instance: __OUTPOST_NAME__
|
app.kubernetes.io/instance: __OUTPOST_NAME__
|
||||||
app.kubernetes.io/managed-by: goauthentik.io
|
app.kubernetes.io/managed-by: goauthentik.io
|
||||||
app.kubernetes.io/name: authentik-proxy
|
app.kubernetes.io/name: authentik-proxy
|
||||||
app.kubernetes.io/version: 2021.8.3
|
app.kubernetes.io/version: 2021.8.4
|
||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- env:
|
- env:
|
||||||
@ -88,7 +88,7 @@ spec:
|
|||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
key: authentik_host_insecure
|
key: authentik_host_insecure
|
||||||
name: authentik-outpost-api
|
name: authentik-outpost-api
|
||||||
image: ghcr.io/goauthentik/proxy:2021.8.3
|
image: ghcr.io/goauthentik/proxy:2021.8.4
|
||||||
name: proxy
|
name: proxy
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 4180
|
- containerPort: 4180
|
||||||
@ -98,7 +98,7 @@ spec:
|
|||||||
name: https
|
name: https
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
---
|
---
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
@ -110,7 +110,7 @@ metadata:
|
|||||||
app.kubernetes.io/instance: __OUTPOST_NAME__
|
app.kubernetes.io/instance: __OUTPOST_NAME__
|
||||||
app.kubernetes.io/managed-by: goauthentik.io
|
app.kubernetes.io/managed-by: goauthentik.io
|
||||||
app.kubernetes.io/name: authentik-proxy
|
app.kubernetes.io/name: authentik-proxy
|
||||||
app.kubernetes.io/version: 2021.8.3
|
app.kubernetes.io/version: 2021.8.4
|
||||||
name: authentik-outpost
|
name: authentik-outpost
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
@ -118,7 +118,9 @@ spec:
|
|||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- backend:
|
- backend:
|
||||||
serviceName: authentik-outpost
|
service:
|
||||||
servicePort: http
|
name: authentik-outpost
|
||||||
|
port:
|
||||||
|
name: http
|
||||||
path: /
|
path: /
|
||||||
```
|
```
|
||||||
|
|||||||
@ -66,7 +66,7 @@ This includes the following:
|
|||||||
Can be any of:
|
Can be any of:
|
||||||
|
|
||||||
- `password`: Standard password login
|
- `password`: Standard password login
|
||||||
- `app_password`: App passowrd (token)
|
- `app_password`: App password (token)
|
||||||
|
|
||||||
Sets `context['auth_method_args']` to
|
Sets `context['auth_method_args']` to
|
||||||
```json
|
```json
|
||||||
|
|||||||
@ -261,6 +261,12 @@ spec:
|
|||||||
|
|
||||||
Add the following settings to your IngressRoute
|
Add the following settings to your IngressRoute
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
By default traefik does not allow cross-namespace references for middlewares:
|
||||||
|
|
||||||
|
See [here](https://doc.traefik.io/traefik/v2.4/providers/kubernetes-crd/#allowcrossnamespace) to enable it.
|
||||||
|
:::
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
spec:
|
spec:
|
||||||
routes:
|
routes:
|
||||||
@ -268,8 +274,10 @@ spec:
|
|||||||
match: "Host(`*external host that you configured in authentik*`)"
|
match: "Host(`*external host that you configured in authentik*`)"
|
||||||
middlewares:
|
middlewares:
|
||||||
- name: authentik
|
- name: authentik
|
||||||
|
namespace: authentik
|
||||||
priority: 10
|
priority: 10
|
||||||
services: # Unchanged
|
services: # Unchanged
|
||||||
|
# This part is only required for single-app setups
|
||||||
- kind: Rule
|
- kind: Rule
|
||||||
match: "Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)"
|
match: "Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)"
|
||||||
priority: 15
|
priority: 15
|
||||||
|
|||||||
@ -10,7 +10,7 @@ Default fields are exposed through auto-generated Property Mappings, which are p
|
|||||||
| SSO (Redirect binding) | `/application/saml/<application slug>/sso/binding/redirect/` |
|
| SSO (Redirect binding) | `/application/saml/<application slug>/sso/binding/redirect/` |
|
||||||
| SSO (POST binding) | `/application/saml/<application slug>/sso/binding/post/` |
|
| SSO (POST binding) | `/application/saml/<application slug>/sso/binding/post/` |
|
||||||
| IdP-initiated login | `/application/saml/<application slug>/sso/binding/init/` |
|
| IdP-initiated login | `/application/saml/<application slug>/sso/binding/init/` |
|
||||||
| Metadata Download | `/api/v2beta/providers/saml/<provider uid>/metadata/?download/`|
|
| Metadata Download | `/api/v3/providers/saml/<provider uid>/metadata/?download/`|
|
||||||
|
|
||||||
You can download the metadata through the Webinterface, this link might be handy if your software wants to download the metadata directly.
|
You can download the metadata through the Webinterface, this link might be handy if your software wants to download the metadata directly.
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user