Compare commits

..

1 Commits

Author SHA1 Message Date
3d06924f42 Add human friendly labels to tasks. 2025-04-29 19:40:00 +02:00
856 changed files with 7315 additions and 17547 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2025.4.0
current_version = 2025.2.4
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?

View File

@ -1,6 +1,5 @@
---
name: "Prepare docker environment variables"
description: "Prepare docker environment variables"
inputs:
image-name:

View File

@ -1,4 +1,4 @@
name: "Setup authentik testing environment"
name: Setup authentik testing environment
description: "Setup authentik testing environment"
inputs:
@ -48,7 +48,7 @@ runs:
- name: Generate config
shell: uv run python {0}
run: |
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
from yaml import safe_dump
with open("local.env.yml", "w") as _config:

View File

@ -118,15 +118,3 @@ updates:
prefix: "core:"
labels:
- dependencies
- package-ecosystem: docker-compose
directories:
# - /scripts # Maybe
- /tests/e2e
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
commit-message:
prefix: "core:"
labels:
- dependencies

View File

@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3.6.0
- uses: docker/setup-buildx-action@v3
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
@ -64,12 +64,12 @@ jobs:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: make empty clients
- name: Make empty clients
if: ${{ inputs.release }}
run: |
mkdir -p ./gen-ts-api
mkdir -p ./gen-go-api
- name: generate ts client
- name: Generate TypeScript API Client
if: ${{ !inputs.release }}
run: make gen-client-ts
- name: Build Docker Image

View File

@ -49,7 +49,7 @@ jobs:
shouldPush: ${{ steps.ev.outputs.shouldPush }}
steps:
- uses: actions/checkout@v4
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
@ -69,7 +69,7 @@ jobs:
tag: ${{ fromJson(needs.get-tags.outputs.tags) }}
steps:
- uses: actions/checkout@v4
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -7,6 +7,7 @@ on:
workflow_dispatch:
jobs:
build:
name: Build and Publish
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
permissions:
@ -14,6 +15,7 @@ jobs:
steps:
- id: generate_token
uses: tibdex/github-app-token@v2
name: Generate token
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
@ -30,7 +32,7 @@ jobs:
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
- name: Generate API Client
- name: Generate Python API Client
run: make gen-client-py
- name: Publish package
working-directory: gen-py-api/

View File

@ -7,6 +7,7 @@ on:
workflow_dispatch:
jobs:
build:
name: Build and Publish
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:
@ -22,7 +23,7 @@ jobs:
with:
node-version-file: web/package.json
registry-url: "https://registry.npmjs.org"
- name: Generate API Client
- name: Generate TypeScript API Client
run: make gen-client-ts
- name: Publish package
working-directory: gen-ts-api/

View File

@ -18,6 +18,7 @@ env:
jobs:
check-changes-applied:
name: Check changes applied
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -36,6 +37,7 @@ jobs:
uv run make aws-cfn
git diff --exit-code
ci-aws-cfn-mark:
name: CI AWS CloudFormation Mark
if: always()
needs:
- check-changes-applied

View File

@ -9,6 +9,7 @@ on:
jobs:
test-container:
name: Test Container ${{ matrix.version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -19,6 +20,7 @@ jobs:
- version-2024-12
steps:
- uses: actions/checkout@v4
name: ${{ matrix.version }} Setup
- run: |
current="$(pwd)"
dir="/tmp/authentik/${{ matrix.version }}"

View File

@ -19,6 +19,7 @@ env:
jobs:
lint:
name: Lint
strategy:
fail-fast: false
matrix:
@ -33,9 +34,10 @@ jobs:
- uses: actions/checkout@v4
- name: Setup authentik env
uses: ./.github/actions/setup
- name: run job
- name: Run job ${{ matrix.job }}
run: uv run make ci-${{ matrix.job }}
test-migrations:
name: Test Migrations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -44,6 +46,7 @@ jobs:
- name: run migrations
run: uv run python -m lifecycle.migrate
test-make-seed:
name: Test Make Seed
runs-on: ubuntu-latest
steps:
- id: seed
@ -52,7 +55,7 @@ jobs:
outputs:
seed: ${{ steps.seed.outputs.seed }}
test-migrations-from-stable:
name: test-migrations-from-stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
name: Test Migrations From Stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
runs-on: ubuntu-latest
timeout-minutes: 20
needs: test-make-seed
@ -67,22 +70,26 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: checkout stable
- name: Checkout Stable
run: |
# Copy current, latest config to local
cp authentik/common/config/default.yml local.env.yml
cp -R .github ..
# Temporarly comment the .github backup while migrating to uv
cp authentik/lib/default.yml local.env.yml
# cp -R .github ..
cp -R scripts ..
git checkout $(git tag --sort=version:refname | grep '^version/' | grep -vE -- '-rc[0-9]+$' | tail -n1)
rm -rf .github/ scripts/
mv ../.github ../scripts .
# rm -rf .github/ scripts/
# mv ../.github ../scripts .
rm -rf scripts/
mv ../scripts .
- name: Setup authentik env (stable)
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
- name: run migrations to stable
run: uv run python -m lifecycle.migrate
- name: checkout current code
continue-on-error: true
- name: Run migrations to stable
run: poetry run python -m lifecycle.migrate
- name: Checkout current code
run: |
set -x
git fetch
@ -93,10 +100,10 @@ jobs:
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
- name: migrate to latest
- name: Migrate to latest
run: |
uv run python -m lifecycle.migrate
- name: run tests
- name: Run tests
env:
# Test in the main database that we just migrated from the previous stable version
AUTHENTIK_POSTGRESQL__TEST__NAME: authentik
@ -106,7 +113,7 @@ jobs:
run: |
uv run make ci-test
test-unittest:
name: test-unittest - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
name: Unit tests - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
runs-on: ubuntu-latest
timeout-minutes: 20
needs: test-make-seed
@ -119,7 +126,7 @@ jobs:
run_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4
- name: Setup authentik env
- name: Setup authentik env (${{ matrix.psql }})
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
@ -142,6 +149,7 @@ jobs:
file: unittest.xml
token: ${{ secrets.CODECOV_TOKEN }}
test-integration:
name: Integration tests
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
@ -150,7 +158,7 @@ jobs:
uses: ./.github/actions/setup
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.12.0
- name: run integration
- name: Run integration
run: |
uv run coverage run manage.py test tests/integration
uv run coverage xml
@ -166,34 +174,34 @@ jobs:
file: unittest.xml
token: ${{ secrets.CODECOV_TOKEN }}
test-e2e:
name: test-e2e (${{ matrix.job.name }})
name: Test E2E (${{ matrix.job.name }})
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
job:
- name: proxy
- name: Proxy Provider
glob: tests/e2e/test_provider_proxy*
- name: oauth
- name: OAuth2 Provider
glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth*
- name: oauth-oidc
- name: OIDC Provider
glob: tests/e2e/test_provider_oidc*
- name: saml
- name: SAML Provider
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
- name: ldap
- name: LDAP Provider
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
- name: radius
- name: RADIUS Provider
glob: tests/e2e/test_provider_radius*
- name: scim
- name: SCIM Source
glob: tests/e2e/test_source_scim*
- name: flows
- name: Flows
glob: tests/e2e/test_flows*
steps:
- uses: actions/checkout@v4
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Setup e2e env (chrome, etc)
- name: Setup E2E env (chrome, etc)
run: |
docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
- id: cache-web
@ -201,14 +209,14 @@ jobs:
with:
path: web/dist
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**') }}
- name: prepare web ui
- name: Prepare Web UI
if: steps.cache-web.outputs.cache-hit != 'true'
working-directory: web
run: |
npm ci
make -C .. gen-client-ts
npm run build
- name: run e2e
- name: Run E2E tests
run: |
uv run coverage run manage.py test ${{ matrix.job.glob }}
uv run coverage xml
@ -224,6 +232,7 @@ jobs:
file: unittest.xml
token: ${{ secrets.CODECOV_TOKEN }}
ci-core-mark:
name: CI Core Mark
if: always()
needs:
- lint
@ -238,6 +247,7 @@ jobs:
with:
jobs: ${{ toJSON(needs) }}
build:
name: Build
permissions:
# Needed to upload container images to ghcr.io
packages: write
@ -251,6 +261,7 @@ jobs:
image_name: ghcr.io/goauthentik/dev-server
release: false
pr-comment:
name: PR Comment
needs:
- build
runs-on: ubuntu-latest
@ -263,7 +274,7 @@ jobs:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -14,6 +14,7 @@ on:
jobs:
lint-golint:
name: Lint Go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -26,15 +27,16 @@ jobs:
mkdir -p web/dist
mkdir -p website/help
touch web/dist/test website/help/test
- name: Generate API
- name: Generate Go API Client
run: make gen-client-go
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
uses: golangci/golangci-lint-action@v7
with:
version: latest
args: --timeout 5000s --verbose
skip-cache: true
test-unittest:
name: Unit Test Go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -43,12 +45,13 @@ jobs:
go-version-file: "go.mod"
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Generate API
- name: Generate Go API Client
run: make gen-client-go
- name: Go unittests
run: |
go test -timeout 0 -v -race -coverprofile=coverage.out -covermode=atomic -cover ./...
ci-outpost-mark:
name: CI Outpost Mark
if: always()
needs:
- lint-golint
@ -59,6 +62,7 @@ jobs:
with:
jobs: ${{ toJSON(needs) }}
build-container:
name: Build Container
timeout-minutes: 120
needs:
- ci-outpost-mark
@ -85,7 +89,7 @@ jobs:
uses: docker/setup-qemu-action@v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
@ -99,7 +103,7 @@ jobs:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate API
- name: Generate Go API Client
run: make gen-client-go
- name: Build Docker Image
id: push
@ -122,6 +126,7 @@ jobs:
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-binary:
name: Build Binary
timeout-minutes: 120
needs:
- ci-outpost-mark
@ -140,7 +145,6 @@ jobs:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- uses: actions/setup-node@v4
@ -148,7 +152,7 @@ jobs:
node-version-file: web/package.json
cache: "npm"
cache-dependency-path: web/package-lock.json
- name: Generate API
- name: Generate Go API Client
run: make gen-client-go
- name: Build web
working-directory: web/

View File

@ -13,6 +13,7 @@ on:
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -39,12 +40,13 @@ jobs:
- working-directory: ${{ matrix.project }}/
run: |
npm ci
- name: Generate API
- name: Generate TypeScript API
run: make gen-client-ts
- name: Lint
working-directory: ${{ matrix.project }}/
run: npm run ${{ matrix.command }}
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -61,6 +63,7 @@ jobs:
working-directory: web/
run: npm run build
ci-web-mark:
name: CI Web Mark
if: always()
needs:
- build

View File

@ -13,6 +13,7 @@ on:
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -24,10 +25,11 @@ jobs:
- uses: actions/checkout@v4
- working-directory: website/
run: npm ci
- name: Lint
- name: Lint ${{ matrix.command }}
working-directory: website/
run: npm run ${{ matrix.command }}
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -37,18 +39,14 @@ jobs:
cache: "npm"
cache-dependency-path: website/package-lock.json
- working-directory: website/
name: Install dependencies
run: npm ci
- name: test
- name: Documentation test
working-directory: website/
run: npm test
build:
name: Build Docs
runs-on: ubuntu-latest
name: ${{ matrix.job }}
strategy:
fail-fast: false
matrix:
job:
- build
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@ -58,10 +56,11 @@ jobs:
cache-dependency-path: website/package-lock.json
- working-directory: website/
run: npm ci
- name: build
- name: Build Docusaurus
working-directory: website/
run: npm run ${{ matrix.job }}
run: npm run build
ci-website-mark:
name: Mark CI Website
if: always()
needs:
- lint

View File

@ -1,4 +1,4 @@
name: "CodeQL"
name: CodeQL
on:
push:

View File

@ -11,6 +11,7 @@ env:
jobs:
build:
name: Update WebAuthn MDS
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:

View File

@ -12,6 +12,7 @@ permissions:
jobs:
cleanup:
name: Cleanup Cache
runs-on: ubuntu-latest
steps:
- name: Check out code

View File

@ -20,7 +20,7 @@ on:
jobs:
compress:
name: compress
name: Compress Docker images
runs-on: ubuntu-latest
# Don't run on forks. Token will not be available. Will run on main and open a PR anyway
if: |

View File

@ -25,16 +25,17 @@ jobs:
with:
fetch-depth: 2
- uses: actions/setup-node@v4
name: Setup Node.js
with:
node-version-file: packages/${{ matrix.package }}/package.json
registry-url: "https://registry.npmjs.org"
- name: Get changed files
- name: Changed files (${{ matrix.package }})
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
packages/${{ matrix.package }}/package.json
- name: Publish package
- name: Publish package (${{ matrix.package }})
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: packages/${{ matrix.package}}
run: |

View File

@ -12,6 +12,7 @@ env:
jobs:
publish-source-docs:
name: Publish
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
timeout-minutes: 120
@ -19,11 +20,11 @@ jobs:
- uses: actions/checkout@v4
- name: Setup authentik env
uses: ./.github/actions/setup
- name: generate docs
- name: Generate docs
run: |
uv run make migrate
uv run ak build_source_docs
- name: Publish
- name: Deploy to Netlify
uses: netlify/actions/cli@master
with:
args: deploy --dir=source_docs --prod

View File

@ -11,6 +11,7 @@ permissions:
jobs:
update-next:
name: Update Next Branch
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
environment: internal-production

View File

@ -7,6 +7,7 @@ on:
jobs:
build-server:
name: Build server
uses: ./.github/workflows/_reusable-docker-build.yaml
secrets: inherit
permissions:
@ -21,6 +22,7 @@ jobs:
registry_dockerhub: true
registry_ghcr: true
build-outpost:
name: Build outpost
runs-on: ubuntu-latest
permissions:
# Needed to upload container images to ghcr.io
@ -45,14 +47,14 @@ jobs:
uses: docker/setup-qemu-action@v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
with:
image-name: ghcr.io/goauthentik/${{ matrix.type }},beryju/authentik-${{ matrix.type }}
- name: make empty clients
- name: Make empty clients
run: |
mkdir -p ./gen-ts-api
mkdir -p ./gen-go-api
@ -85,6 +87,7 @@ jobs:
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-outpost-binary:
name: Build outpost binary
timeout-minutes: 120
runs-on: ubuntu-latest
permissions:
@ -129,6 +132,7 @@ jobs:
asset_name: authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }}
tag: ${{ github.ref }}
upload-aws-cfn-template:
name: Upload AWS CloudFormation template
permissions:
# Needed for AWS login
id-token: write
@ -150,6 +154,7 @@ jobs:
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.${{ github.ref }}.yaml
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.latest.yaml
test-release:
name: Test release
needs:
- build-server
- build-outpost
@ -166,6 +171,7 @@ jobs:
docker compose start postgresql redis
docker compose run -u root server test-all
sentry-release:
name: Sentry release
needs:
- build-server
- build-outpost
@ -173,7 +179,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -20,7 +20,7 @@ jobs:
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: prepare variables
- name: Prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -4,6 +4,7 @@ on: [push, delete]
jobs:
to_internal:
name: Mirror to internal repository
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:

View File

@ -11,6 +11,7 @@ permissions:
jobs:
stale:
name: Stale Issues
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:

View File

@ -16,6 +16,7 @@ permissions:
jobs:
post-comment:
name: Post Comment
runs-on: ubuntu-latest
steps:
- name: Find Comment

View File

@ -16,6 +16,7 @@ env:
jobs:
compile:
name: Compile Translations
runs-on: ubuntu-latest
steps:
- id: generate_token
@ -32,12 +33,12 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Generate API
- name: Generate TypeScript API
run: make gen-client-ts
- name: run extract
- name: Extract Translations
run: |
uv run make i18n-extract
- name: run compile
- name: Compile Messages
run: |
uv run ak compilemessages
make web-check-compile

View File

@ -12,6 +12,7 @@ permissions:
jobs:
rename_pr:
name: Rename PR
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'transifex-integration[bot]'}}
steps:

View File

@ -16,7 +16,7 @@
],
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.importModuleSpecifierEnding": "index",
"typescript.tsdk": "./node_modules/typescript/lib",
"typescript.tsdk": "./web/node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
"yaml.schemas": {
"./blueprints/schema.json": "blueprints/**/*.yaml"
@ -30,5 +30,7 @@
}
],
"go.testFlags": ["-count=1"],
"github-actions.workflows.pinned.workflows": [".github/workflows/ci-main.yml"]
"github-actions.workflows.pinned.workflows": [
".github/workflows/ci-main.yml"
]
}

View File

@ -85,17 +85,18 @@ FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v7.1.0 AS geoip
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
ENV GEOIPUPDATE_VERBOSE="1"
ENV GEOIPUPDATE_ACCOUNT_ID_FILE="/run/secrets/GEOIPUPDATE_ACCOUNT_ID"
ENV GEOIPUPDATE_LICENSE_KEY_FILE="/run/secrets/GEOIPUPDATE_LICENSE_KEY"
USER root
RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
--mount=type=secret,id=GEOIPUPDATE_LICENSE_KEY \
mkdir -p /usr/share/GeoIP && \
/bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 5: Download uv
FROM ghcr.io/astral-sh/uv:0.7.3 AS uv
FROM ghcr.io/astral-sh/uv:0.6.17 AS uv
# Stage 6: Base python image
FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base
ENV VENV_PATH="/ak-root/.venv" \
PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \

View File

@ -12,9 +12,9 @@ GEN_API_TS = "gen-ts-api"
GEN_API_PY = "gen-py-api"
GEN_API_GO = "gen-go-api"
pg_user := $(shell uv run python -m authentik.common.config postgresql.user 2>/dev/null)
pg_host := $(shell uv run python -m authentik.common.config postgresql.host 2>/dev/null)
pg_name := $(shell uv run python -m authentik.common.config postgresql.name 2>/dev/null)
pg_user := $(shell uv run python -m authentik.lib.config postgresql.user 2>/dev/null)
pg_host := $(shell uv run python -m authentik.lib.config postgresql.host 2>/dev/null)
pg_name := $(shell uv run python -m authentik.lib.config postgresql.name 2>/dev/null)
all: lint-fix lint test gen web ## Lint, build, and test everything

View File

@ -42,4 +42,4 @@ See [SECURITY.md](SECURITY.md)
## Adoption and Contributions
Your organization uses authentik? We'd love to add your logo to the readme and our website! Email us @ hello@goauthentik.io or open a GitHub Issue/PR! For more information on how to contribute to authentik, please refer to our [contribution guide](https://docs.goauthentik.io/docs/developer-docs?utm_source=github).
Your organization uses authentik? We'd love to add your logo to the readme and our website! Email us @ hello@goauthentik.io or open a GitHub Issue/PR! For more information on how to contribute to authentik, please refer to our [CONTRIBUTING.md file](./CONTRIBUTING.md).

View File

@ -20,8 +20,8 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni
| Version | Supported |
| --------- | --------- |
| 2024.12.x | ✅ |
| 2025.2.x | ✅ |
| 2025.4.x | ✅ |
## Reporting a Vulnerability

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2025.4.0"
__version__ = "2025.2.4"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -7,8 +7,8 @@ from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
from authentik.common.utils.reflection import get_apps
from authentik.core.api.utils import PassiveSerializer
from authentik.lib.utils.reflection import get_apps
from authentik.policies.event_matcher.models import model_choices

View File

@ -7,7 +7,6 @@ from sys import version as python_version
from typing import TypedDict
from cryptography.hazmat.backends.openssl.backend import backend
from django.apps import apps
from django.conf import settings
from django.utils.timezone import now
from django.views.debug import SafeExceptionReporterFilter
@ -18,10 +17,12 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from authentik import get_full_version
from authentik.common.config import CONFIG
from authentik.common.utils.reflection import get_env
from authentik.core.api.utils import PassiveSerializer
from authentik.enterprise.license import LicenseKey
from authentik.lib.config import CONFIG
from authentik.lib.utils.reflection import get_env
from authentik.outposts.apps import MANAGED_OUTPOST
from authentik.outposts.models import Outpost
from authentik.rbac.permissions import HasPermission
@ -102,12 +103,6 @@ class SystemInfoSerializer(PassiveSerializer):
def get_embedded_outpost_host(self, request: Request) -> str:
"""Get the FQDN configured on the embedded outpost"""
if not apps.is_installed("authentik.outposts"):
return ""
from authentik.outposts.apps import MANAGED_OUTPOST
from authentik.outposts.models import Outpost
outposts = Outpost.objects.filter(managed=MANAGED_OUTPOST)
if not outposts.exists(): # pragma: no cover
return ""

View File

@ -2,7 +2,7 @@
from celery.schedules import crontab
from authentik.common.utils.time import fqdn_rand
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"admin_latest_version": {

View File

@ -9,10 +9,10 @@ from structlog.stdlib import get_logger
from authentik import __version__, get_build_hash
from authentik.admin.apps import PROM_INFO
from authentik.common.config import CONFIG
from authentik.common.utils.http import get_http_session
from authentik.events.models import Event, EventAction, Notification
from authentik.events.system_tasks import SystemTask, TaskStatus, prefill_task
from authentik.lib.config import CONFIG
from authentik.lib.utils.http import get_http_session
from authentik.root.celery import CELERY_APP
LOGGER = get_logger()

View File

@ -8,7 +8,7 @@ from django.urls import reverse
from authentik import __version__
from authentik.blueprints.tests import reconcile_app
from authentik.core.models import Group, User
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
class TestAdminAPI(TestCase):

View File

@ -9,8 +9,8 @@ from authentik.admin.tasks import (
clear_update_notifications,
update_latest_version,
)
from authentik.common.config import CONFIG
from authentik.events.models import Event, EventAction
from authentik.lib.config import CONFIG
RESPONSE_VALID = {
"$schema": "https://version.goauthentik.io/schema.json",

View File

@ -1,16 +1,19 @@
"""API Authentication"""
from hmac import compare_digest
from typing import Any
from django.conf import settings
from drf_spectacular.extensions import OpenApiAuthenticationExtension
from rest_framework.authentication import BaseAuthentication, get_authorization_header
from rest_framework.exceptions import AuthenticationFailed
from rest_framework.request import Request
from structlog.stdlib import get_logger
from authentik.common.oauth.constants import SCOPE_AUTHENTIK_API
from authentik.core.middleware import CTX_AUTH_VIA
from authentik.core.models import Token, TokenIntents, User
from authentik.outposts.models import Outpost
from authentik.providers.oauth2.constants import SCOPE_AUTHENTIK_API
LOGGER = get_logger()
@ -65,9 +68,28 @@ def auth_user_lookup(raw_header: bytes) -> User | None:
raise AuthenticationFailed("Token invalid/expired")
CTX_AUTH_VIA.set("jwt")
return jwt_token.user
# then try to auth via secret key (for embedded outpost/etc)
user = token_secret_key(auth_credentials)
if user:
CTX_AUTH_VIA.set("secret_key")
return user
raise AuthenticationFailed("Token invalid/expired")
def token_secret_key(value: str) -> User | None:
"""Check if the token is the secret key
and return the service account for the managed outpost"""
from authentik.outposts.apps import MANAGED_OUTPOST
if not compare_digest(value, settings.SECRET_KEY):
return None
outposts = Outpost.objects.filter(managed=MANAGED_OUTPOST)
if not outposts:
return None
outpost = outposts.first()
return outpost.user
class TokenAuthentication(BaseAuthentication):
"""Token-based authentication using HTTP Bearer authentication"""

View File

@ -54,7 +54,7 @@ def create_component(generator: SchemaGenerator, name, schema, type_=ResolvedCom
return component
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs):
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs): # noqa: W0613
"""Workaround to set a default response for endpoints.
Workaround suggested at
<https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>

View File

@ -3,15 +3,19 @@
import json
from base64 import b64encode
from django.conf import settings
from django.test import TestCase
from django.utils import timezone
from rest_framework.exceptions import AuthenticationFailed
from authentik.api.authentication import bearer_auth
from authentik.common.oauth.constants import SCOPE_AUTHENTIK_API
from authentik.core.models import Token, TokenIntents
from authentik.blueprints.tests import reconcile_app
from authentik.core.models import Token, TokenIntents, User, UserTypes
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
from authentik.outposts.apps import MANAGED_OUTPOST
from authentik.outposts.models import Outpost
from authentik.providers.oauth2.constants import SCOPE_AUTHENTIK_API
from authentik.providers.oauth2.models import AccessToken, OAuth2Provider
@ -48,6 +52,21 @@ class TestAPIAuth(TestCase):
with self.assertRaises(AuthenticationFailed):
bearer_auth(f"Bearer {token.key}".encode())
@reconcile_app("authentik_outposts")
def test_managed_outpost_fail(self):
"""Test managed outpost"""
outpost = Outpost.objects.filter(managed=MANAGED_OUTPOST).first()
outpost.user.delete()
outpost.delete()
with self.assertRaises(AuthenticationFailed):
bearer_auth(f"Bearer {settings.SECRET_KEY}".encode())
@reconcile_app("authentik_outposts")
def test_managed_outpost_success(self):
"""Test managed outpost"""
user: User = bearer_auth(f"Bearer {settings.SECRET_KEY}".encode())
self.assertEqual(user.type, UserTypes.INTERNAL_SERVICE_ACCOUNT)
def test_jwt_valid(self):
"""Test valid JWT"""
provider = OAuth2Provider.objects.create(

View File

@ -19,9 +19,9 @@ from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from authentik.common.config import CONFIG
from authentik.core.api.utils import PassiveSerializer
from authentik.events.context_processors.base import get_context_processors
from authentik.lib.config import CONFIG
capabilities = Signal()

View File

@ -11,7 +11,7 @@ from structlog.stdlib import get_logger
from authentik.api.v3.config import ConfigView
from authentik.api.views import APIBrowserView
from authentik.common.utils.reflection import get_apps
from authentik.lib.utils.reflection import get_apps
LOGGER = get_logger()

View File

@ -12,8 +12,8 @@ from structlog.stdlib import get_logger
from yaml import load
from authentik.blueprints.v1.common import BlueprintLoader, EntryInvalidError
from authentik.common.utils.errors import exception_to_string
from authentik.core.management.commands.shell import get_banner_text
from authentik.lib.utils.errors import exception_to_string
LOGGER = get_logger()

View File

@ -15,7 +15,7 @@ from authentik import __version__
from authentik.blueprints.v1.common import BlueprintEntryDesiredState
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT, is_model_allowed
from authentik.blueprints.v1.meta.registry import BaseMetaModel, registry
from authentik.common.models import SerializerModel
from authentik.lib.models import SerializerModel
LOGGER = get_logger()

View File

@ -11,7 +11,7 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from yaml import load
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_SYSTEM
from authentik.common.config import CONFIG
from authentik.lib.config import CONFIG
def check_blueprint_v1_file(BlueprintInstance: type, db_alias, path: Path):

View File

@ -2,7 +2,7 @@
from django.db import migrations, models
from authentik.common.migrations import fallback_names
from authentik.lib.migrations import fallback_names
class Migration(migrations.Migration):

View File

@ -10,14 +10,14 @@ from rest_framework.serializers import Serializer
from structlog import get_logger
from authentik.blueprints.v1.oci import OCI_PREFIX, BlueprintOCIClient, OCIException
from authentik.common.config import CONFIG
from authentik.common.exceptions import NotReportedException
from authentik.common.models import CreatedUpdatedModel, SerializerModel
from authentik.lib.config import CONFIG
from authentik.lib.models import CreatedUpdatedModel, SerializerModel
from authentik.lib.sentry import SentryIgnoredException
LOGGER = get_logger()
class BlueprintRetrievalFailed(NotReportedException):
class BlueprintRetrievalFailed(SentryIgnoredException):
"""Error raised when we are unable to fetch the blueprint contents, whether it be HTTP files
not being accessible or local files not being readable"""

View File

@ -2,7 +2,7 @@
from celery.schedules import crontab
from authentik.common.utils.time import fqdn_rand
from authentik.lib.utils.time import fqdn_rand
CELERY_BEAT_SCHEDULE = {
"blueprints_v1_discover": {

View File

@ -3,7 +3,7 @@
from django.test import TestCase
from authentik.blueprints.models import BlueprintInstance, BlueprintRetrievalFailed
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
class TestModels(TestCase):

View File

@ -6,7 +6,7 @@ from django.apps import apps
from django.test import TestCase
from authentik.blueprints.v1.importer import is_model_allowed
from authentik.common.models import SerializerModel
from authentik.lib.models import SerializerModel
from authentik.providers.oauth2.models import RefreshToken

View File

@ -6,10 +6,10 @@ from django.test import TransactionTestCase
from authentik.blueprints.v1.exporter import FlowExporter
from authentik.blueprints.v1.importer import Importer, transaction_rollback
from authentik.common.tests import load_fixture
from authentik.core.models import Group
from authentik.crypto.generators import generate_id
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import PolicyBinding
from authentik.sources.oauth.models import OAuthSource

View File

@ -7,8 +7,8 @@ from django.urls import reverse
from rest_framework.test import APITestCase
from yaml import dump
from authentik.common.config import CONFIG
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.config import CONFIG
TMP = mkdtemp("authentik-blueprints")

View File

@ -3,11 +3,11 @@
from django.test import TransactionTestCase
from authentik.blueprints.v1.importer import Importer
from authentik.common.tests import load_fixture
from authentik.core.models import Application, Token, User
from authentik.core.tests.utils import create_test_admin_user
from authentik.crypto.generators import generate_id
from authentik.flows.models import Flow
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
from authentik.sources.oauth.models import OAuthSource

View File

@ -3,9 +3,9 @@
from django.test import TransactionTestCase
from authentik.blueprints.v1.importer import Importer
from authentik.common.tests import load_fixture
from authentik.crypto.generators import generate_id
from authentik.flows.models import Flow
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
class TestBlueprintsV1Conditions(TransactionTestCase):

View File

@ -4,10 +4,10 @@ from django.test import TransactionTestCase
from guardian.shortcuts import get_perms
from authentik.blueprints.v1.importer import Importer
from authentik.common.tests import load_fixture
from authentik.core.models import User
from authentik.crypto.generators import generate_id
from authentik.flows.models import Flow
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
from authentik.rbac.models import Role

View File

@ -3,9 +3,9 @@
from django.test import TransactionTestCase
from authentik.blueprints.v1.importer import Importer
from authentik.common.tests import load_fixture
from authentik.crypto.generators import generate_id
from authentik.flows.models import Flow
from authentik.lib.generators import generate_id
from authentik.lib.tests.utils import load_fixture
class TestBlueprintsV1State(TransactionTestCase):

View File

@ -8,8 +8,8 @@ from yaml import dump
from authentik.blueprints.models import BlueprintInstance, BlueprintInstanceStatus
from authentik.blueprints.v1.tasks import apply_blueprint, blueprints_discovery, blueprints_find
from authentik.common.config import CONFIG
from authentik.crypto.generators import generate_id
from authentik.lib.config import CONFIG
from authentik.lib.generators import generate_id
TMP = mkdtemp("authentik-blueprints")

View File

@ -19,8 +19,8 @@ from rest_framework.fields import Field
from rest_framework.serializers import Serializer
from yaml import SafeDumper, SafeLoader, ScalarNode, SequenceNode
from authentik.common.exceptions import NotReportedException
from authentik.common.models import SerializerModel
from authentik.lib.models import SerializerModel
from authentik.lib.sentry import SentryIgnoredException
from authentik.policies.models import PolicyBindingModel
@ -164,7 +164,9 @@ class BlueprintEntry:
"""Get the blueprint model, with yaml tags resolved if present"""
return str(self.tag_resolver(self.model, blueprint))
def get_permissions(self, blueprint: "Blueprint") -> Generator[BlueprintEntryPermission]:
def get_permissions(
self, blueprint: "Blueprint"
) -> Generator[BlueprintEntryPermission, None, None]:
"""Get permissions of this entry, with all yaml tags resolved"""
for perm in self.permissions:
yield BlueprintEntryPermission(
@ -661,7 +663,7 @@ class BlueprintLoader(SafeLoader):
self.add_constructor("!AtIndex", AtIndex)
class EntryInvalidError(NotReportedException):
class EntryInvalidError(SentryIgnoredException):
"""Error raised when an entry is invalid"""
entry_model: str | None

View File

@ -8,11 +8,14 @@ from dacite.config import Config
from dacite.core import from_dict
from dacite.exceptions import DaciteError
from deepmerge import always_merger
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import FieldError
from django.db.models import Model
from django.db.models.query_utils import Q
from django.db.transaction import atomic
from django.db.utils import IntegrityError
from guardian.models import UserObjectPermission
from guardian.shortcuts import assign_perm
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import BaseSerializer, Serializer
@ -28,26 +31,119 @@ from authentik.blueprints.v1.common import (
EntryInvalidError,
)
from authentik.blueprints.v1.meta.registry import BaseMetaModel, registry
from authentik.common.exceptions import NotReportedException
from authentik.common.models import SerializerModel, excluded_models
from authentik.common.utils.reflection import get_apps
from authentik.core.models import User
from authentik.core.models import (
AuthenticatedSession,
GroupSourceConnection,
PropertyMapping,
Provider,
Session,
Source,
User,
UserSourceConnection,
)
from authentik.enterprise.license import LicenseKey
from authentik.enterprise.models import LicenseUsage
from authentik.enterprise.providers.google_workspace.models import (
GoogleWorkspaceProviderGroup,
GoogleWorkspaceProviderUser,
)
from authentik.enterprise.providers.microsoft_entra.models import (
MicrosoftEntraProviderGroup,
MicrosoftEntraProviderUser,
)
from authentik.enterprise.providers.ssf.models import StreamEvent
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
EndpointDevice,
EndpointDeviceConnection,
)
from authentik.events.logs import LogEvent, capture_logs
from authentik.events.models import SystemTask
from authentik.events.utils import cleanse_dict
from authentik.flows.models import FlowToken, Stage
from authentik.lib.models import SerializerModel
from authentik.lib.sentry import SentryIgnoredException
from authentik.lib.utils.reflection import get_apps
from authentik.outposts.models import OutpostServiceConnection
from authentik.policies.models import Policy, PolicyBindingModel
from authentik.policies.reputation.models import Reputation
from authentik.providers.oauth2.models import (
AccessToken,
AuthorizationCode,
DeviceToken,
RefreshToken,
)
from authentik.providers.rac.models import ConnectionToken
from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
from authentik.rbac.models import Role
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
from authentik.stages.authenticator_webauthn.models import WebAuthnDeviceType
from authentik.tenants.models import Tenant
# Context set when the serializer is created in a blueprint context
# Update website/docs/customize/blueprints/v1/models.md when used
SERIALIZER_CONTEXT_BLUEPRINT = "blueprint_entry"
def excluded_models() -> list[type[Model]]:
"""Return a list of all excluded models that shouldn't be exposed via API
or other means (internal only, base classes, non-used objects, etc)"""
from django.contrib.auth.models import Group as DjangoGroup
from django.contrib.auth.models import User as DjangoUser
return (
# Django only classes
DjangoUser,
DjangoGroup,
ContentType,
Permission,
UserObjectPermission,
# Base classes
Provider,
Source,
PropertyMapping,
UserSourceConnection,
GroupSourceConnection,
Stage,
OutpostServiceConnection,
Policy,
PolicyBindingModel,
# Classes that have other dependencies
Session,
AuthenticatedSession,
# Classes which are only internally managed
# FIXME: these shouldn't need to be explicitly listed, but rather based off of a mixin
FlowToken,
LicenseUsage,
SCIMProviderGroup,
SCIMProviderUser,
Tenant,
SystemTask,
ConnectionToken,
AuthorizationCode,
AccessToken,
RefreshToken,
Reputation,
WebAuthnDeviceType,
SCIMSourceUser,
SCIMSourceGroup,
GoogleWorkspaceProviderUser,
GoogleWorkspaceProviderGroup,
MicrosoftEntraProviderUser,
MicrosoftEntraProviderGroup,
EndpointDevice,
EndpointDeviceConnection,
DeviceToken,
StreamEvent,
)
def is_model_allowed(model: type[Model]) -> bool:
"""Check if model is allowed"""
return model not in excluded_models() and issubclass(model, SerializerModel | BaseMetaModel)
class DoRollback(NotReportedException):
class DoRollback(SentryIgnoredException):
"""Exception to trigger a rollback"""

View File

@ -16,14 +16,14 @@ from requests.exceptions import RequestException
from structlog import get_logger
from structlog.stdlib import BoundLogger
from authentik.common.exceptions import NotReportedException
from authentik.common.utils.http import authentik_user_agent
from authentik.lib.sentry import SentryIgnoredException
from authentik.lib.utils.http import authentik_user_agent
OCI_MEDIA_TYPE = "application/vnd.goauthentik.blueprint.v1+yaml"
OCI_PREFIX = "oci://"
class OCIException(NotReportedException):
class OCIException(SentryIgnoredException):
"""OCI-related errors"""

View File

@ -30,11 +30,11 @@ from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata, E
from authentik.blueprints.v1.importer import Importer
from authentik.blueprints.v1.labels import LABEL_AUTHENTIK_INSTANTIATE
from authentik.blueprints.v1.oci import OCI_PREFIX
from authentik.common.config import CONFIG
from authentik.events.logs import capture_logs
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask, prefill_task
from authentik.events.utils import sanitize_dict
from authentik.lib.config import CONFIG
from authentik.root.celery import CELERY_APP
from authentik.tenants.models import Tenant

View File

@ -5,7 +5,7 @@ import uuid
import django.db.models.deletion
from django.db import migrations, models
import authentik.common.utils.time
import authentik.lib.utils.time
class Migration(migrations.Migration):
@ -104,7 +104,7 @@ class Migration(migrations.Migration):
"Events will be deleted after this duration.(Format:"
" weeks=3;days=2;hours=3,seconds=2)."
),
validators=[authentik.common.utils.time.timedelta_string_validator],
validators=[authentik.lib.utils.time.timedelta_string_validator],
),
),
migrations.AddField(

View File

@ -16,7 +16,7 @@ def migrate_custom_css(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
if not path.exists():
return
css = path.read_text()
Brand.objects.using(db_alias).all().update(branding_custom_css=css)
Brand.objects.using(db_alias).update(branding_custom_css=css)
class Migration(migrations.Migration):

View File

@ -8,10 +8,10 @@ from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import Serializer
from structlog.stdlib import get_logger
from authentik.common.config import CONFIG
from authentik.common.models import SerializerModel
from authentik.crypto.models import CertificateKeyPair
from authentik.flows.models import Flow
from authentik.lib.config import CONFIG
from authentik.lib.models import SerializerModel
LOGGER = get_logger()

View File

@ -7,7 +7,7 @@ from authentik.brands.api import Themes
from authentik.brands.models import Brand
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_brand
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
from authentik.providers.oauth2.models import OAuth2Provider
from authentik.providers.saml.models import SAMLProvider

View File

@ -1,7 +0,0 @@
class AuthentikException(Exception):
"""Base class for authentik exceptions"""
class NotReportedException(AuthentikException):
"""Exception base class for all errors that are suppressed,
and not sent to any kind of monitoring."""

View File

@ -1,6 +0,0 @@
from authentik.common.exceptions import NotReportedException
class ControlFlowException(NotReportedException):
"""Exceptions used to control the flow from exceptions, not reported as a warning/
error in logs"""

View File

@ -1 +0,0 @@
LDAP_DISTINGUISHED_NAME = "distinguishedName"

View File

@ -1,10 +0,0 @@
from rest_framework.fields import CharField
from authentik.core.api.utils import PassiveSerializer
class SAMLMetadataSerializer(PassiveSerializer):
"""SAML Provider Metadata serializer"""
metadata = CharField(read_only=True)
download_url = CharField(read_only=True, required=False)

View File

@ -1,19 +0,0 @@
"""Test HTTP Helpers"""
from django.test import RequestFactory, TestCase
from authentik.common.views import bad_request_message
from authentik.core.tests.utils import create_test_admin_user
class TestViews(TestCase):
"""Test Views Helpers"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.factory = RequestFactory()
def test_bad_request_message(self):
"""test bad_request_message"""
request = self.factory.get("/")
self.assertEqual(bad_request_message(request, "foo").status_code, 400)

View File

@ -23,18 +23,18 @@ from structlog.stdlib import get_logger
from authentik.admin.api.metrics import CoordinateSerializer
from authentik.api.pagination import Pagination
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.common.utils.file import (
FilePathSerializer,
FileUploadSerializer,
set_file,
set_file_url,
)
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import ModelSerializer
from authentik.core.models import Application, User
from authentik.events.logs import LogEventSerializer, capture_logs
from authentik.events.models import EventAction
from authentik.lib.utils.file import (
FilePathSerializer,
FileUploadSerializer,
set_file,
set_file_url,
)
from authentik.policies.api.exec import PolicyTestResultSerializer
from authentik.policies.engine import PolicyEngine
from authentik.policies.types import CACHE_PREFIX, PolicyResult

View File

@ -9,9 +9,9 @@ from rest_framework.fields import (
from rest_framework.request import Request
from rest_framework.response import Response
from authentik.common.utils.reflection import all_subclasses
from authentik.core.api.utils import PassiveSerializer
from authentik.enterprise.apps import EnterpriseConfig
from authentik.lib.utils.reflection import all_subclasses
class TypeCreateSerializer(PassiveSerializer):

View File

@ -22,7 +22,6 @@ from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from authentik.blueprints.api import ManagedSerializer
from authentik.common.utils.errors import exception_to_string
from authentik.core.api.object_types import TypesMixin
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import (
@ -34,6 +33,7 @@ from authentik.core.expression.evaluator import PropertyMappingEvaluator
from authentik.core.expression.exceptions import PropertyMappingExpressionException
from authentik.core.models import Group, PropertyMapping, User
from authentik.events.utils import sanitize_item
from authentik.lib.utils.errors import exception_to_string
from authentik.policies.api.exec import PolicyTestSerializer
from authentik.rbac.decorators import permission_required

View File

@ -14,17 +14,17 @@ from rest_framework.viewsets import GenericViewSet
from structlog.stdlib import get_logger
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.common.utils.file import (
FilePathSerializer,
FileUploadSerializer,
set_file,
set_file_url,
)
from authentik.core.api.object_types import TypesMixin
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer, ModelSerializer
from authentik.core.models import GroupSourceConnection, Source, UserSourceConnection
from authentik.core.types import UserSettingSerializer
from authentik.lib.utils.file import (
FilePathSerializer,
FileUploadSerializer,
set_file,
set_file_url,
)
from authentik.policies.engine import PolicyEngine
from authentik.rbac.decorators import permission_required

View File

@ -14,7 +14,6 @@ from rest_framework.viewsets import ModelViewSet
from authentik.blueprints.api import ManagedSerializer
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.common.utils.time import timedelta_from_string
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
@ -28,6 +27,7 @@ from authentik.core.models import (
)
from authentik.events.models import Event, EventAction
from authentik.events.utils import model_to_dict
from authentik.lib.utils.time import timedelta_from_string
from authentik.rbac.decorators import permission_required

View File

@ -20,10 +20,10 @@ from authentik.blueprints.v1.common import (
KeyOf,
)
from authentik.blueprints.v1.importer import Importer
from authentik.common.utils.reflection import all_subclasses
from authentik.core.api.applications import ApplicationSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Application, Provider
from authentik.lib.utils.reflection import all_subclasses
from authentik.policies.api.bindings import PolicyBindingSerializer

View File

@ -62,7 +62,6 @@ from authentik.core.api.utils import (
ModelSerializer,
PassiveSerializer,
)
from authentik.core.avatars import get_avatar
from authentik.core.middleware import (
SESSION_KEY_IMPERSONATE_ORIGINAL_USER,
SESSION_KEY_IMPERSONATE_USER,
@ -82,6 +81,7 @@ from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import FlowToken
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlanner
from authentik.flows.views.executor import QS_KEY_TOKEN
from authentik.lib.avatars import get_avatar
from authentik.rbac.decorators import permission_required
from authentik.rbac.models import get_permission_choices
from authentik.stages.email.models import EmailStage

View File

@ -7,11 +7,11 @@ from django.db.models import Model
from django.http import HttpRequest
from prometheus_client import Histogram
from authentik.common.expression.evaluator import BaseEvaluator
from authentik.common.utils.errors import exception_to_string
from authentik.core.expression.exceptions import SkipObjectException
from authentik.core.models import User
from authentik.events.models import Event, EventAction
from authentik.lib.expression.evaluator import BaseEvaluator
from authentik.lib.utils.errors import exception_to_string
from authentik.policies.types import PolicyRequest
PROPERTY_MAPPING_TIME = Histogram(

View File

@ -1,10 +1,10 @@
"""authentik core exceptions"""
from authentik.common.exceptions import NotReportedException
from authentik.common.expression.exceptions import ControlFlowException
from authentik.lib.expression.exceptions import ControlFlowException
from authentik.lib.sentry import SentryIgnoredException
class PropertyMappingExpressionException(NotReportedException):
class PropertyMappingExpressionException(SentryIgnoredException):
"""Error when a PropertyMapping Exception expression could not be parsed or evaluated."""
def __init__(self, exc: Exception, mapping) -> None:

View File

@ -5,7 +5,7 @@ from typing import TextIO
from daphne.management.commands.runserver import Command as RunServer
from daphne.server import Server
from authentik.root.debug import start_debug_server
from authentik.lib.debug import start_debug_server
from authentik.root.signals import post_startup, pre_startup, startup

View File

@ -8,9 +8,9 @@ from django.core.management.base import BaseCommand
from django.db import close_old_connections
from structlog.stdlib import get_logger
from authentik.common.config import CONFIG
from authentik.lib.config import CONFIG
from authentik.lib.debug import start_debug_server
from authentik.root.celery import CELERY_APP
from authentik.root.debug import start_debug_server
LOGGER = get_logger()

View File

@ -5,7 +5,7 @@ from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
import authentik.core.models
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
def set_default_token_key(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):

View File

@ -10,7 +10,7 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.models import Count
import authentik.core.models
import authentik.common.models
import authentik.lib.models
def migrate_sessions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
@ -160,7 +160,7 @@ class Migration(migrations.Migration):
field=models.TextField(
blank=True,
default="",
validators=[authentik.common.models.DomainlessFormattedURLValidator()],
validators=[authentik.lib.models.DomainlessFormattedURLValidator()],
),
),
migrations.RunPython(

View File

@ -2,7 +2,7 @@
from django.db import migrations, models
from authentik.common.migrations import fallback_names
from authentik.lib.migrations import fallback_names
class Migration(migrations.Migration):

View File

@ -9,7 +9,7 @@ import django.db.models.deletion
from django.conf import settings
from django.contrib.sessions.backends.cache import KEY_PREFIX
from django.utils.timezone import now, timedelta
from authentik.common.migrations import progress_bar
from authentik.lib.migrations import progress_bar
from authentik.root.middleware import ClientIPMiddleware

View File

@ -6,7 +6,7 @@ from hashlib import sha256
from typing import Any, Optional, Self
from uuid import uuid4
from deepmerge import Merger, always_merger
from deepmerge import always_merger
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import UserManager as DjangoUserManager
@ -26,18 +26,18 @@ from rest_framework.serializers import Serializer
from structlog.stdlib import get_logger
from authentik.blueprints.models import ManagedModel
from authentik.common.expression.exceptions import ControlFlowException
from authentik.common.models import (
from authentik.core.expression.exceptions import PropertyMappingExpressionException
from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.lib.avatars import get_avatar
from authentik.lib.expression.exceptions import ControlFlowException
from authentik.lib.generators import generate_id
from authentik.lib.merge import MERGE_LIST_UNIQUE
from authentik.lib.models import (
CreatedUpdatedModel,
DomainlessFormattedURLValidator,
SerializerModel,
internal_model,
)
from authentik.common.utils.time import timedelta_from_string
from authentik.core.avatars import get_avatar
from authentik.core.expression.exceptions import PropertyMappingExpressionException
from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.crypto.generators import generate_id
from authentik.lib.utils.time import timedelta_from_string
from authentik.policies.models import PolicyBindingModel
from authentik.tenants.models import DEFAULT_TOKEN_DURATION, DEFAULT_TOKEN_LENGTH
from authentik.tenants.utils import get_current_tenant, get_unique_identifier
@ -64,10 +64,6 @@ options.DEFAULT_NAMES = options.DEFAULT_NAMES + (
GROUP_RECURSION_LIMIT = 20
MERGE_LIST_UNIQUE = Merger(
[(list, ["append_unique"]), (dict, ["merge"]), (set, ["union"])], ["override"], ["override"]
)
def default_token_duration() -> datetime:
"""Default duration a Token is valid"""
@ -412,7 +408,6 @@ class User(SerializerModel, GuardianUserMixin, AttributesMixin, AbstractUser):
return get_avatar(self)
@internal_model
class Provider(SerializerModel):
"""Application-independent Provider instance. For example SAML2 Remote, OAuth2 Application"""
@ -697,7 +692,6 @@ class SourceGroupMatchingModes(models.TextChoices):
)
@internal_model
class Source(ManagedModel, SerializerModel, PolicyBindingModel):
"""Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server"""
@ -759,14 +753,6 @@ class Source(ManagedModel, SerializerModel, PolicyBindingModel):
objects = InheritanceManager()
@property
def serializer(self) -> type[Serializer]:
if self.managed == self.MANAGED_INBUILT:
from authentik.core.api.sources import SourceSerializer
return SourceSerializer
return super().serializer
@property
def icon_url(self) -> str | None:
"""Get the URL to the Icon. If the name is /static or
@ -849,7 +835,6 @@ class Source(ManagedModel, SerializerModel, PolicyBindingModel):
]
@internal_model
class UserSourceConnection(SerializerModel, CreatedUpdatedModel):
"""Connection between User and Source."""
@ -875,7 +860,6 @@ class UserSourceConnection(SerializerModel, CreatedUpdatedModel):
)
@internal_model
class GroupSourceConnection(SerializerModel, CreatedUpdatedModel):
"""Connection between Group and Source."""
@ -1005,7 +989,6 @@ class Token(SerializerModel, ManagedModel, ExpiringModel):
).save()
@internal_model
class PropertyMapping(SerializerModel, ManagedModel):
"""User-defined key -> x mapping which can be used by providers to expose extra data."""
@ -1045,7 +1028,6 @@ class PropertyMapping(SerializerModel, ManagedModel):
verbose_name_plural = _("Property Mappings")
@internal_model
class Session(ExpiringModel, AbstractBaseSession):
"""User session with extra fields for fast access"""
@ -1092,7 +1074,6 @@ class Session(ExpiringModel, AbstractBaseSession):
raise NotImplementedError
@internal_model
class AuthenticatedSession(SerializerModel):
session = models.OneToOneField(Session, on_delete=models.CASCADE, primary_key=True)
# We use the session as primary key, but we need the API to be able to reference

View File

@ -10,7 +10,6 @@ from django.urls import reverse
from django.utils.translation import gettext as _
from structlog.stdlib import get_logger
from authentik.common.views import bad_request_message
from authentik.core.models import (
Group,
GroupSourceConnection,
@ -37,6 +36,7 @@ from authentik.flows.planner import (
)
from authentik.flows.stage import StageView
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET
from authentik.lib.views import bad_request_message
from authentik.policies.denied import AccessDeniedResponse
from authentik.policies.utils import delete_none_values
from authentik.stages.password import BACKEND_INBUILT

View File

@ -3,10 +3,11 @@ from typing import Any
from django.http import HttpRequest
from structlog.stdlib import get_logger
from authentik.common.sync.mapper import PropertyMappingManager
from authentik.core.expression.exceptions import PropertyMappingExpressionException
from authentik.core.models import MERGE_LIST_UNIQUE, Group, PropertyMapping, Source, User
from authentik.core.models import Group, PropertyMapping, Source, User
from authentik.events.models import Event, EventAction
from authentik.lib.merge import MERGE_LIST_UNIQUE
from authentik.lib.sync.mapper import PropertyMappingManager
from authentik.policies.utils import delete_none_values
LOGGER = get_logger()

View File

@ -9,9 +9,9 @@ from rest_framework.serializers import (
)
from rest_framework.test import APITestCase
from authentik.common.utils.reflection import all_subclasses
from authentik.core.api.utils import ModelSerializer as CustomModelSerializer
from authentik.core.api.utils import is_dict
from authentik.lib.utils.reflection import all_subclasses
class TestAPIUtils(APITestCase):

View File

@ -6,7 +6,7 @@ from rest_framework.test import APITestCase
from authentik.core.models import Application, ApplicationEntitlement, Group
from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_user
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
from authentik.policies.dummy.models import DummyPolicy
from authentik.policies.models import PolicyBinding
from authentik.providers.oauth2.models import OAuth2Provider

View File

@ -9,7 +9,7 @@ from rest_framework.test import APITestCase
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
from authentik.policies.dummy.models import DummyPolicy
from authentik.policies.models import PolicyBinding
from authentik.providers.oauth2.models import OAuth2Provider, RedirectURI, RedirectURIMatchingMode

View File

@ -3,7 +3,7 @@
from django.test.testcases import TestCase
from authentik.core.models import Group, User
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
class TestGroups(TestCase):

View File

@ -6,7 +6,7 @@ from rest_framework.test import APITestCase
from authentik.core.models import Group
from authentik.core.tests.utils import create_test_admin_user, create_test_user
from authentik.crypto.generators import generate_id
from authentik.lib.generators import generate_id
class TestGroupsAPI(APITestCase):

Some files were not shown because too many files have changed in this diff Show More