From 317afc932adaa75d824476d44f96c248fa81c5e5 Mon Sep 17 00:00:00 2001 From: Saeverix <1863379+Saeverix@users.noreply.github.com> Date: Mon, 29 May 2023 14:20:40 +0200 Subject: [PATCH 1/7] web/flows: fix RedirectStage not detecting absolute URLs correctly (#5781) * web: getURL() method in RedirectStage.ts now actually detects URLs (#5732) Signed-off-by: Saeverix <1863379+Saeverix@users.noreply.github.com> * use native API to build full URL Signed-off-by: Jens Langhammer --------- Signed-off-by: Saeverix <1863379+Saeverix@users.noreply.github.com> Signed-off-by: Jens Langhammer Co-authored-by: Jens Langhammer --- web/src/flow/stages/RedirectStage.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/web/src/flow/stages/RedirectStage.ts b/web/src/flow/stages/RedirectStage.ts index 591dc66fe..8396bbe1e 100644 --- a/web/src/flow/stages/RedirectStage.ts +++ b/web/src/flow/stages/RedirectStage.ts @@ -39,10 +39,7 @@ export class RedirectStage extends BaseStage Date: Tue, 30 May 2023 09:36:51 +0100 Subject: [PATCH 2/7] stages/deny: fix typos (#5800) * Fix typo in stage.py Fix typo in "Cancells the current flow" Signed-off-by: rlew-is <96594816+rlew-is@users.noreply.github.com> * Fix typo in models.py Fix typo in "Cancells the current flow" Signed-off-by: rlew-is <96594816+rlew-is@users.noreply.github.com> --------- Signed-off-by: rlew-is <96594816+rlew-is@users.noreply.github.com> --- authentik/stages/deny/models.py | 2 +- authentik/stages/deny/stage.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/authentik/stages/deny/models.py b/authentik/stages/deny/models.py index 4ef252e3c..4aa2e692f 100644 --- a/authentik/stages/deny/models.py +++ b/authentik/stages/deny/models.py @@ -8,7 +8,7 @@ from authentik.flows.models import Stage class DenyStage(Stage): - """Cancells the current flow.""" + """Cancels the current flow.""" @property def serializer(self) -> type[BaseSerializer]: diff --git a/authentik/stages/deny/stage.py b/authentik/stages/deny/stage.py index 0513c269a..4e9e93d0c 100644 --- a/authentik/stages/deny/stage.py +++ b/authentik/stages/deny/stage.py @@ -5,10 +5,10 @@ from authentik.flows.stage import StageView class DenyStageView(StageView): - """Cancells the current flow""" + """Cancels the current flow""" def get(self, request: HttpRequest) -> HttpResponse: - """Cancells the current flow""" + """Cancels the current flow""" return self.executor.stage_invalid() def post(self, request: HttpRequest) -> HttpResponse: From 772acb10d6565d6f6fec3879625716f1ccdcf921 Mon Sep 17 00:00:00 2001 From: Jens L Date: Wed, 31 May 2023 14:14:25 +0200 Subject: [PATCH 3/7] providers/ldap: fix LDAP Outpost application selection (#5812) Signed-off-by: Jens Langhammer --- authentik/core/api/providers.py | 19 +++++++---- authentik/providers/ldap/api.py | 47 +++++++++++++++++++-------- web/src/admin/outposts/OutpostForm.ts | 6 +++- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/authentik/core/api/providers.py b/authentik/core/api/providers.py index 67b2427fc..a5095dcde 100644 --- a/authentik/core/api/providers.py +++ b/authentik/core/api/providers.py @@ -1,4 +1,6 @@ """Provider API Views""" +from django.db.models import QuerySet +from django.db.models.query import Q from django.utils.translation import gettext_lazy as _ from django_filters.filters import BooleanFilter from django_filters.filterset import FilterSet @@ -56,17 +58,22 @@ class ProviderSerializer(ModelSerializer, MetaNameSerializer): class ProviderFilter(FilterSet): - """Filter for groups""" + """Filter for providers""" - application__isnull = BooleanFilter( - field_name="application", - lookup_expr="isnull", - ) + application__isnull = BooleanFilter(method="filter_application__isnull") backchannel_only = BooleanFilter( method="filter_backchannel_only", ) - def filter_backchannel_only(self, queryset, name, value): + def filter_application__isnull(self, queryset: QuerySet, name, value): + """Only return providers that are neither assigned to application, + both as provider or application provider""" + return queryset.filter( + Q(backchannel_application__isnull=value, is_backchannel=True) + | Q(application__isnull=value) + ) + + def filter_backchannel_only(self, queryset: QuerySet, name, value): """Only return backchannel providers""" return queryset.filter(is_backchannel=value) diff --git a/authentik/providers/ldap/api.py b/authentik/providers/ldap/api.py index 52c4cdc60..96b3a5926 100644 --- a/authentik/providers/ldap/api.py +++ b/authentik/providers/ldap/api.py @@ -1,4 +1,8 @@ """LDAPProvider API Views""" +from django.db.models import QuerySet +from django.db.models.query import Q +from django_filters.filters import BooleanFilter +from django_filters.filterset import FilterSet from rest_framework.fields import CharField, ListField, SerializerMethodField from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet @@ -29,24 +33,41 @@ class LDAPProviderSerializer(ProviderSerializer): extra_kwargs = ProviderSerializer.Meta.extra_kwargs +class LDAPProviderFilter(FilterSet): + """LDAP Provider filters""" + + application__isnull = BooleanFilter(method="filter_application__isnull") + + def filter_application__isnull(self, queryset: QuerySet, name, value): + """Only return providers that are neither assigned to application, + both as provider or application provider""" + return queryset.filter( + Q(backchannel_application__isnull=value) | Q(application__isnull=value) + ) + + class Meta: + model = LDAPProvider + fields = { + "application": ["isnull"], + "name": ["iexact"], + "authorization_flow__slug": ["iexact"], + "base_dn": ["iexact"], + "search_group__group_uuid": ["iexact"], + "search_group__name": ["iexact"], + "certificate__kp_uuid": ["iexact"], + "certificate__name": ["iexact"], + "tls_server_name": ["iexact"], + "uid_start_number": ["iexact"], + "gid_start_number": ["iexact"], + } + + class LDAPProviderViewSet(UsedByMixin, ModelViewSet): """LDAPProvider Viewset""" queryset = LDAPProvider.objects.all() serializer_class = LDAPProviderSerializer - filterset_fields = { - "application": ["isnull"], - "name": ["iexact"], - "authorization_flow__slug": ["iexact"], - "base_dn": ["iexact"], - "search_group__group_uuid": ["iexact"], - "search_group__name": ["iexact"], - "certificate__kp_uuid": ["iexact"], - "certificate__name": ["iexact"], - "tls_server_name": ["iexact"], - "uid_start_number": ["iexact"], - "gid_start_number": ["iexact"], - } + filterset_class = LDAPProviderFilter search_fields = ["name"] ordering = ["name"] diff --git a/web/src/admin/outposts/OutpostForm.ts b/web/src/admin/outposts/OutpostForm.ts index 9a845a49f..0b4f70338 100644 --- a/web/src/admin/outposts/OutpostForm.ts +++ b/web/src/admin/outposts/OutpostForm.ts @@ -191,8 +191,12 @@ export class OutpostForm extends ModelForm { const selected = Array.from(this.instance?.providers || []).some((sp) => { return sp == provider.pk; }); + let appName = provider.assignedApplicationName; + if (provider.assignedBackchannelApplicationName) { + appName = provider.assignedBackchannelApplicationName; + } return html``; })} From b055adec2ab02bd7f4dc4d3c7bc482c819307e4b Mon Sep 17 00:00:00 2001 From: risson <18313093+rissson@users.noreply.github.com> Date: Wed, 31 May 2023 14:23:04 +0200 Subject: [PATCH 4/7] ci: replace github bot account with github app (#5819) Co-authored-by: Jens Langhammer --- .github/workflows/ghcr-retention.yml | 7 ++++++- .github/workflows/release-tag.yml | 9 +++++++-- .github/workflows/translation-compile.yml | 9 +++++++-- .github/workflows/web-api-publish.yml | 11 ++++++++--- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ghcr-retention.yml b/.github/workflows/ghcr-retention.yml index 308c1351a..b7dc6c447 100644 --- a/.github/workflows/ghcr-retention.yml +++ b/.github/workflows/ghcr-retention.yml @@ -10,6 +10,11 @@ jobs: name: Delete old unused container images runs-on: ubuntu-latest steps: + - id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} - name: Delete 'dev' containers older than a week uses: snok/container-retention-policy@v2 with: @@ -18,5 +23,5 @@ jobs: account-type: org org-name: goauthentik untagged-only: false - token: ${{ secrets.BOT_GITHUB_TOKEN }} + token: ${{ steps.generate_token.outputs.token }} skip-tags: gh-next,gh-main diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index 6673cc4f2..7598c58f1 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -22,18 +22,23 @@ jobs: docker-compose up --no-start docker-compose start postgresql redis docker-compose run -u root server test-all + - id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} - name: Extract version number id: get_version uses: actions/github-script@v6 with: - github-token: ${{ secrets.BOT_GITHUB_TOKEN }} + github-token: ${{ steps.generate_token.outputs.token }} script: | return context.payload.ref.replace(/\/refs\/tags\/version\//, ''); - name: Create Release id: create_release uses: actions/create-release@v1.1.4 env: - GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} with: tag_name: ${{ github.ref }} release_name: Release ${{ steps.get_version.outputs.result }} diff --git a/.github/workflows/translation-compile.yml b/.github/workflows/translation-compile.yml index 6084493d9..8fa655213 100644 --- a/.github/workflows/translation-compile.yml +++ b/.github/workflows/translation-compile.yml @@ -15,9 +15,14 @@ jobs: compile: runs-on: ubuntu-latest steps: + - id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} - uses: actions/checkout@v3 with: - token: ${{ secrets.BOT_GITHUB_TOKEN }} + token: ${{ steps.generate_token.outputs.token }} - name: Setup authentik env uses: ./.github/actions/setup - name: run compile @@ -26,7 +31,7 @@ jobs: uses: peter-evans/create-pull-request@v5 id: cpr with: - token: ${{ secrets.BOT_GITHUB_TOKEN }} + token: ${{ steps.generate_token.outputs.token }} branch: compile-backend-translation commit-message: "core: compile backend translations" title: "core: compile backend translations" diff --git a/.github/workflows/web-api-publish.yml b/.github/workflows/web-api-publish.yml index 1b8521d87..6bd1fd570 100644 --- a/.github/workflows/web-api-publish.yml +++ b/.github/workflows/web-api-publish.yml @@ -9,9 +9,14 @@ jobs: build: runs-on: ubuntu-latest steps: + - id: generate_token + uses: tibdex/github-app-token@v1 + with: + app_id: ${{ secrets.GH_APP_ID }} + private_key: ${{ secrets.GH_APP_PRIVATE_KEY }} - uses: actions/checkout@v3 with: - token: ${{ secrets.BOT_GITHUB_TOKEN }} + token: ${{ steps.generate_token.outputs.token }} - uses: actions/setup-node@v3.6.0 with: node-version: "20" @@ -33,7 +38,7 @@ jobs: - uses: peter-evans/create-pull-request@v5 id: cpr with: - token: ${{ secrets.BOT_GITHUB_TOKEN }} + token: ${{ steps.generate_token.outputs.token }} branch: update-web-api-client commit-message: "web: bump API Client version" title: "web: bump API Client version" @@ -44,6 +49,6 @@ jobs: author: authentik bot - uses: peter-evans/enable-pull-request-automerge@v3 with: - token: ${{ secrets.BOT_GITHUB_TOKEN }} + token: ${{ steps.generate_token.outputs.token }} pull-request-number: ${{ steps.cpr.outputs.pull-request-number }} merge-method: squash From e141a1147596174095a64ba9a61013a2475aac9d Mon Sep 17 00:00:00 2001 From: Jens L Date: Wed, 31 May 2023 14:50:39 +0200 Subject: [PATCH 5/7] blueprints: fix API validation with OCI blueprint path (#5822) Signed-off-by: Jens Langhammer --- authentik/blueprints/api.py | 3 ++- authentik/blueprints/models.py | 6 +++--- authentik/blueprints/tests/test_v1_api.py | 8 ++++++++ authentik/blueprints/v1/oci.py | 1 + authentik/blueprints/v1/tasks.py | 3 ++- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/authentik/blueprints/api.py b/authentik/blueprints/api.py index e22bd18e1..4ae847106 100644 --- a/authentik/blueprints/api.py +++ b/authentik/blueprints/api.py @@ -13,6 +13,7 @@ from rest_framework.viewsets import ModelViewSet from authentik.api.decorators import permission_required from authentik.blueprints.models import BlueprintInstance from authentik.blueprints.v1.importer import Importer +from authentik.blueprints.v1.oci import OCI_PREFIX from authentik.blueprints.v1.tasks import apply_blueprint, blueprints_find_dict from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import PassiveSerializer @@ -36,7 +37,7 @@ class BlueprintInstanceSerializer(ModelSerializer): def validate_path(self, path: str) -> str: """Ensure the path (if set) specified is retrievable""" - if path == "": + if path == "" or path.startswith(OCI_PREFIX): return path files: list[dict] = blueprints_find_dict.delay().get() if path not in [file["path"] for file in files]: diff --git a/authentik/blueprints/models.py b/authentik/blueprints/models.py index 012e4986c..130b13264 100644 --- a/authentik/blueprints/models.py +++ b/authentik/blueprints/models.py @@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework.serializers import Serializer from structlog import get_logger -from authentik.blueprints.v1.oci import BlueprintOCIClient, OCIException +from authentik.blueprints.v1.oci import OCI_PREFIX, BlueprintOCIClient, OCIException from authentik.lib.config import CONFIG from authentik.lib.models import CreatedUpdatedModel, SerializerModel from authentik.lib.sentry import SentryIgnoredException @@ -72,7 +72,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel): def retrieve_oci(self) -> str: """Get blueprint from an OCI registry""" - client = BlueprintOCIClient(self.path.replace("oci://", "https://")) + client = BlueprintOCIClient(self.path.replace(OCI_PREFIX, "https://")) try: manifests = client.fetch_manifests() return client.fetch_blobs(manifests) @@ -90,7 +90,7 @@ class BlueprintInstance(SerializerModel, ManagedModel, CreatedUpdatedModel): def retrieve(self) -> str: """Retrieve blueprint contents""" - if self.path.startswith("oci://"): + if self.path.startswith(OCI_PREFIX): return self.retrieve_oci() if self.path != "": return self.retrieve_file() diff --git a/authentik/blueprints/tests/test_v1_api.py b/authentik/blueprints/tests/test_v1_api.py index 33bdd1b03..6ee4bd7f6 100644 --- a/authentik/blueprints/tests/test_v1_api.py +++ b/authentik/blueprints/tests/test_v1_api.py @@ -44,6 +44,14 @@ class TestBlueprintsV1API(APITestCase): ), ) + def test_api_oci(self): + """Test validation with OCI path""" + res = self.client.post( + reverse("authentik_api:blueprintinstance-list"), + data={"name": "foo", "path": "oci://foo/bar"}, + ) + self.assertEqual(res.status_code, 201) + def test_api_blank(self): """Test blank""" res = self.client.post( diff --git a/authentik/blueprints/v1/oci.py b/authentik/blueprints/v1/oci.py index bda7bcf73..d02f3fa2f 100644 --- a/authentik/blueprints/v1/oci.py +++ b/authentik/blueprints/v1/oci.py @@ -19,6 +19,7 @@ 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(SentryIgnoredException): diff --git a/authentik/blueprints/v1/tasks.py b/authentik/blueprints/v1/tasks.py index 3a278ef3c..757eb556c 100644 --- a/authentik/blueprints/v1/tasks.py +++ b/authentik/blueprints/v1/tasks.py @@ -28,6 +28,7 @@ from authentik.blueprints.models import ( from authentik.blueprints.v1.common import BlueprintLoader, BlueprintMetadata, EntryInvalidError 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.events.monitored_tasks import ( MonitoredTask, TaskResult, @@ -228,7 +229,7 @@ def apply_blueprint(self: MonitoredTask, instance_pk: str): def clear_failed_blueprints(): """Remove blueprints which couldn't be fetched""" # Exclude OCI blueprints as those might be temporarily unavailable - for blueprint in BlueprintInstance.objects.exclude(path__startswith="oci://"): + for blueprint in BlueprintInstance.objects.exclude(path__startswith=OCI_PREFIX): try: blueprint.retrieve() except BlueprintRetrievalFailed: From 24385c9c687cc0a835c9d172e0bb00862cac69df Mon Sep 17 00:00:00 2001 From: Jens L Date: Wed, 31 May 2023 16:48:14 +0200 Subject: [PATCH 6/7] ci: build outpost binaries statically linked (#5823) --- .github/workflows/ci-outpost.yml | 1 + .github/workflows/release-publish.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci-outpost.yml b/.github/workflows/ci-outpost.yml index 4159e76f2..a8b6004bc 100644 --- a/.github/workflows/ci-outpost.yml +++ b/.github/workflows/ci-outpost.yml @@ -135,4 +135,5 @@ jobs: set -x export GOOS=${{ matrix.goos }} export GOARCH=${{ matrix.goarch }} + export CGO_ENABLED=0 go build -tags=outpost_static_embed -v -o ./authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/${{ matrix.type }} diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index b54a4a956..28ba16a16 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -123,6 +123,7 @@ jobs: set -x export GOOS=${{ matrix.goos }} export GOARCH=${{ matrix.goarch }} + export CGO_ENABLED=0 go build -tags=outpost_static_embed -v -o ./authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }} ./cmd/${{ matrix.type }} - name: Upload binaries to release uses: svenstaro/upload-release-action@v2 From be85eecac54e051f1daebe6e8719e726c78068d3 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 1 Jun 2023 19:35:13 +0200 Subject: [PATCH 7/7] release: 2023.5.3 --- .bumpversion.cfg | 2 +- authentik/__init__.py | 2 +- docker-compose.yml | 4 ++-- internal/constants/constants.go | 2 +- pyproject.toml | 2 +- schema.yml | 2 +- web/src/common/constants.ts | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 18fba7f20..d45b6b5a9 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2023.5.2 +current_version = 2023.5.3 tag = True commit = True parse = (?P\d+)\.(?P\d+)\.(?P\d+) diff --git a/authentik/__init__.py b/authentik/__init__.py index e6099773d..b4f8092c4 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -2,7 +2,7 @@ from os import environ from typing import Optional -__version__ = "2023.5.2" +__version__ = "2023.5.3" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" diff --git a/docker-compose.yml b/docker-compose.yml index 8fe64a7cd..d31e9c702 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,7 @@ services: volumes: - redis:/data server: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.2} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.3} restart: unless-stopped command: server environment: @@ -50,7 +50,7 @@ services: - "${COMPOSE_PORT_HTTP:-9000}:9000" - "${COMPOSE_PORT_HTTPS:-9443}:9443" worker: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.2} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.3} restart: unless-stopped command: worker environment: diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 8a3999a2c..08ee10aea 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -29,4 +29,4 @@ func UserAgent() string { return fmt.Sprintf("authentik@%s", FullVersion()) } -const VERSION = "2023.5.2" +const VERSION = "2023.5.3" diff --git a/pyproject.toml b/pyproject.toml index 26cadc0be..72fe6edfb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,7 +113,7 @@ filterwarnings = [ [tool.poetry] name = "authentik" -version = "2023.5.2" +version = "2023.5.3" description = "" authors = ["authentik Team "] diff --git a/schema.yml b/schema.yml index 18d86af11..97198cab0 100644 --- a/schema.yml +++ b/schema.yml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: authentik - version: 2023.5.2 + version: 2023.5.3 description: Making authentication simple. contact: email: hello@goauthentik.io diff --git a/web/src/common/constants.ts b/web/src/common/constants.ts index 56151d4ad..1ebb03ccc 100644 --- a/web/src/common/constants.ts +++ b/web/src/common/constants.ts @@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success"; export const ERROR_CLASS = "pf-m-danger"; export const PROGRESS_CLASS = "pf-m-in-progress"; export const CURRENT_CLASS = "pf-m-current"; -export const VERSION = "2023.5.2"; +export const VERSION = "2023.5.3"; export const TITLE_DEFAULT = "authentik"; export const ROUTE_SEPARATOR = ";";