Compare commits
7 Commits
version/20
...
version/20
Author | SHA1 | Date | |
---|---|---|---|
be85eecac5 | |||
24385c9c68 | |||
e141a11475 | |||
b055adec2a | |||
772acb10d6 | |||
a7bf963409 | |||
317afc932a |
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 2023.5.2
|
||||
current_version = 2023.5.3
|
||||
tag = True
|
||||
commit = True
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
|
||||
|
1
.github/workflows/ci-outpost.yml
vendored
1
.github/workflows/ci-outpost.yml
vendored
@ -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 }}
|
||||
|
7
.github/workflows/ghcr-retention.yml
vendored
7
.github/workflows/ghcr-retention.yml
vendored
@ -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
|
||||
|
1
.github/workflows/release-publish.yml
vendored
1
.github/workflows/release-publish.yml
vendored
@ -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
|
||||
|
9
.github/workflows/release-tag.yml
vendored
9
.github/workflows/release-tag.yml
vendored
@ -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 }}
|
||||
|
9
.github/workflows/translation-compile.yml
vendored
9
.github/workflows/translation-compile.yml
vendored
@ -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"
|
||||
|
11
.github/workflows/web-api-publish.yml
vendored
11
.github/workflows/web-api-publish.yml
vendored
@ -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 <github-bot@goauthentik.io>
|
||||
- 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
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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]:
|
||||
|
@ -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()
|
||||
|
@ -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(
|
||||
|
@ -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):
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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"]
|
||||
|
||||
|
@ -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]:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -29,4 +29,4 @@ func UserAgent() string {
|
||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||
}
|
||||
|
||||
const VERSION = "2023.5.2"
|
||||
const VERSION = "2023.5.3"
|
||||
|
@ -113,7 +113,7 @@ filterwarnings = [
|
||||
|
||||
[tool.poetry]
|
||||
name = "authentik"
|
||||
version = "2023.5.2"
|
||||
version = "2023.5.3"
|
||||
description = ""
|
||||
authors = ["authentik Team <hello@goauthentik.io>"]
|
||||
|
||||
|
@ -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
|
||||
|
@ -191,8 +191,12 @@ export class OutpostForm extends ModelForm<Outpost, string> {
|
||||
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`<option value=${ifDefined(provider.pk)} ?selected=${selected}>
|
||||
${provider.assignedApplicationName} (${provider.name})
|
||||
${appName} (${provider.name})
|
||||
</option>`;
|
||||
})}
|
||||
</select>
|
||||
|
@ -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 = ";";
|
||||
|
||||
|
@ -39,10 +39,7 @@ export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeRes
|
||||
}
|
||||
|
||||
getURL(): string {
|
||||
if (!this.challenge.to.includes("://")) {
|
||||
return window.location.origin + this.challenge.to;
|
||||
}
|
||||
return this.challenge.to;
|
||||
return new URL(this.challenge.to, document.baseURI).toString();
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
|
Reference in New Issue
Block a user