Skip to content

Commit

Permalink
Merge branch 'main' into kerberos-source-reworked
Browse files Browse the repository at this point in the history
  • Loading branch information
rissson committed Oct 17, 2024
2 parents c66602b + 89f251d commit 0e4596a
Show file tree
Hide file tree
Showing 620 changed files with 22,451 additions and 39,622 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2024.8.2
current_version = 2024.8.3
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*))?
Expand Down
6 changes: 3 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ updates:
- package-ecosystem: npm
directories:
- "/web"
- "/tests/wdio"
- "/web/sfe"
schedule:
interval: daily
Expand All @@ -44,10 +43,11 @@ updates:
- "babel-*"
eslint:
patterns:
- "@eslint/*"
- "@typescript-eslint/*"
- "eslint"
- "eslint-*"
- "@eslint/*"
- "eslint"
- "typescript-eslint"
storybook:
patterns:
- "@storybook/*"
Expand Down
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!--
👋 Hi there! Welcome.
Please check the Contributing guidelines: https://goauthentik.io/developer-docs/#how-can-i-contribute
Please check the Contributing guidelines: https://docs.goauthentik.io/docs/developer-docs/#how-can-i-contribute
-->

## Details
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ jobs:
uses: ./.github/actions/setup
- name: Setup e2e env (chrome, etc)
run: |
docker compose -f tests/e2e/docker-compose.yml up -d
docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
- id: cache-web
uses: actions/cache@v4
with:
Expand Down
21 changes: 7 additions & 14 deletions .github/workflows/ci-web.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,11 @@ jobs:
- prettier-check
project:
- web
- tests/wdio
include:
- command: tsc
project: web
- command: lit-analyse
project: web
exclude:
- command: lint:lockfile
project: tests/wdio
- command: tsc
project: tests/wdio
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -50,15 +44,7 @@ jobs:
- name: Lint
working-directory: ${{ matrix.project }}/
run: npm run ${{ matrix.command }}
ci-web-mark:
needs:
- lint
runs-on: ubuntu-latest
steps:
- run: echo mark
build:
needs:
- ci-web-mark
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -74,6 +60,13 @@ jobs:
- name: build
working-directory: web/
run: npm run build
ci-web-mark:
needs:
- build
- lint
runs-on: ubuntu-latest
steps:
- run: echo mark
test:
needs:
- ci-web-mark
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"

# Stage 5: Python dependencies
FROM ghcr.io/goauthentik/fips-python:3.12.6-slim-bookworm-fips-full AS python-deps
FROM ghcr.io/goauthentik/fips-python:3.12.7-slim-bookworm-fips-full AS python-deps

ARG TARGETARCH
ARG TARGETVARIANT
Expand Down Expand Up @@ -124,7 +124,7 @@ RUN --mount=type=bind,target=./pyproject.toml,src=./pyproject.toml \
pip install --force-reinstall /wheels/*"

# Stage 6: Run
FROM ghcr.io/goauthentik/fips-python:3.12.6-slim-bookworm-fips-full AS final-image
FROM ghcr.io/goauthentik/fips-python:3.12.7-slim-bookworm-fips-full AS final-image

ARG VERSION
ARG GIT_BUILD_HASH
Expand Down
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ pg_name := $(shell python -m authentik.lib.config postgresql.name 2>/dev/null)
CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \
-I .github/codespell-words.txt \
-S 'web/src/locales/**' \
-S 'website/developer-docs/api/reference/**' \
-S 'website/docs/developer-docs/api/reference/**' \
authentik \
internal \
cmd \
web/src \
website/src \
website/blog \
website/developer-docs \
website/docs \
website/integrations \
website/src
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ For bigger setups, there is a Helm Chart [here](https://github.com/goauthentik/h

## Development

See [Developer Documentation](https://goauthentik.io/developer-docs/?utm_source=github)
See [Developer Documentation](https://docs.goauthentik.io/docs/developer-docs/?utm_source=github)

## Security

Expand Down
2 changes: 1 addition & 1 deletion authentik/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from os import environ

__version__ = "2024.8.2"
__version__ = "2024.8.3"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"


Expand Down
6 changes: 4 additions & 2 deletions authentik/blueprints/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,11 @@ def validate_content(self, content: str) -> str:
context = self.instance.context if self.instance else {}
valid, logs = Importer.from_string(content, context).validate()
if not valid:
text_logs = "\n".join([x["event"] for x in logs])
raise ValidationError(
_("Failed to validate blueprint: {logs}".format_map({"logs": text_logs}))
[
_("Failed to validate blueprint"),
*[f"- {x.event}" for x in logs],
]
)
return content

Expand Down
4 changes: 1 addition & 3 deletions authentik/blueprints/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ def check_blueprint_v1_file(BlueprintInstance: type, db_alias, path: Path):
if version != 1:
return
blueprint_file.seek(0)
instance: BlueprintInstance = (
BlueprintInstance.objects.using(db_alias).filter(path=path).first()
)
instance = BlueprintInstance.objects.using(db_alias).filter(path=path).first()
rel_path = path.relative_to(Path(CONFIG.get("blueprints_dir")))
meta = None
if metadata:
Expand Down
2 changes: 1 addition & 1 deletion authentik/blueprints/tests/test_v1_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,5 @@ def test_api_content(self):
self.assertEqual(res.status_code, 400)
self.assertJSONEqual(
res.content.decode(),
{"content": ["Failed to validate blueprint: Invalid blueprint version"]},
{"content": ["Failed to validate blueprint", "- Invalid blueprint version"]},
)
4 changes: 2 additions & 2 deletions authentik/blueprints/v1/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
from authentik.tenants.models import Tenant

# Context set when the serializer is created in a blueprint context
# Update website/developer-docs/blueprints/v1/models.md when used
# Update website/docs/customize/blueprints/v1/models.md when used
SERIALIZER_CONTEXT_BLUEPRINT = "blueprint_entry"


Expand Down Expand Up @@ -429,7 +429,7 @@ def validate(self, raise_validation_errors=False) -> tuple[bool, list[LogEvent]]
orig_import = deepcopy(self._import)
if self._import.version != 1:
self.logger.warning("Invalid blueprint version")
return False, [{"event": "Invalid blueprint version"}]
return False, [LogEvent("Invalid blueprint version", log_level="warning", logger=None)]
with (
transaction_rollback(),
capture_logs() as logs,
Expand Down
8 changes: 8 additions & 0 deletions authentik/core/api/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from authentik.core.api.utils import MetaNameSerializer
from authentik.stages.authenticator import device_classes, devices_for_user
from authentik.stages.authenticator.models import Device
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice


class DeviceSerializer(MetaNameSerializer):
Expand All @@ -29,11 +30,18 @@ class DeviceSerializer(MetaNameSerializer):
created = DateTimeField(read_only=True)
last_updated = DateTimeField(read_only=True)
last_used = DateTimeField(read_only=True, allow_null=True)
extra_description = SerializerMethodField()

def get_type(self, instance: Device) -> str:
"""Get type of device"""
return instance._meta.label

def get_extra_description(self, instance: Device) -> str:
"""Get extra description"""
if isinstance(instance, WebAuthnDevice):
return instance.device_type.description
return ""


class DeviceViewSet(ViewSet):
"""Viewset for authenticator devices"""
Expand Down
2 changes: 2 additions & 0 deletions authentik/core/api/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Meta:
"name",
"authentication_flow",
"authorization_flow",
"invalidation_flow",
"property_mappings",
"component",
"assigned_application_slug",
Expand All @@ -50,6 +51,7 @@ class Meta:
]
extra_kwargs = {
"authorization_flow": {"required": True, "allow_null": False},
"invalidation_flow": {"required": True, "allow_null": False},
}


Expand Down
5 changes: 4 additions & 1 deletion authentik/core/api/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,10 @@ def impersonate(self, request: Request, pk: int) -> Response:
LOGGER.debug("User attempted to impersonate", user=request.user)
return Response(status=401)
user_to_be = self.get_object()
if not request.user.has_perm("impersonate", user_to_be):
# Check both object-level perms and global perms
if not request.user.has_perm(
"authentik_core.impersonate", user_to_be
) and not request.user.has_perm("authentik_core.impersonate"):
LOGGER.debug("User attempted to impersonate without permissions", user=request.user)
return Response(status=401)
if user_to_be.pk == self.request.user.pk:
Expand Down
55 changes: 55 additions & 0 deletions authentik/core/migrations/0040_provider_invalidation_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by Django 5.0.9 on 2024-10-02 11:35

import django.db.models.deletion
from django.db import migrations, models

from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor


def migrate_invalidation_flow_default(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
from authentik.flows.models import FlowDesignation, FlowAuthenticationRequirement

db_alias = schema_editor.connection.alias

Flow = apps.get_model("authentik_flows", "Flow")
Provider = apps.get_model("authentik_core", "Provider")

# So this flow is managed via a blueprint, bue we're in a migration so we don't want to rely on that
# since the blueprint is just an empty flow we can just create it here
# and let it be managed by the blueprint later
flow, _ = Flow.objects.using(db_alias).update_or_create(
slug="default-provider-invalidation-flow",
defaults={
"name": "Logged out of application",
"title": "You've logged out of %(app)s.",
"authentication": FlowAuthenticationRequirement.NONE,
"designation": FlowDesignation.INVALIDATION,
},
)
Provider.objects.using(db_alias).filter(invalidation_flow=None).update(invalidation_flow=flow)


class Migration(migrations.Migration):

dependencies = [
("authentik_core", "0039_source_group_matching_mode_alter_group_name_and_more"),
("authentik_flows", "0027_auto_20231028_1424"),
]

operations = [
migrations.AddField(
model_name="provider",
name="invalidation_flow",
field=models.ForeignKey(
default=None,
help_text="Flow used ending the session from a provider.",
null=True,
on_delete=django.db.models.deletion.SET_DEFAULT,
related_name="provider_invalidation",
to="authentik_flows.flow",
),
),
migrations.RunPython(migrate_invalidation_flow_default),
]
11 changes: 10 additions & 1 deletion authentik/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,14 +393,23 @@ class Provider(SerializerModel):
),
related_name="provider_authentication",
)

authorization_flow = models.ForeignKey(
"authentik_flows.Flow",
# Set to cascade even though null is allowed, since most providers
# still require an authorization flow set
on_delete=models.CASCADE,
null=True,
help_text=_("Flow used when authorizing this provider."),
related_name="provider_authorization",
)
invalidation_flow = models.ForeignKey(
"authentik_flows.Flow",
on_delete=models.SET_DEFAULT,
default=None,
null=True,
help_text=_("Flow used ending the session from a provider."),
related_name="provider_invalidation",
)

property_mappings = models.ManyToManyField("PropertyMapping", default=None, blank=True)

Expand Down
43 changes: 0 additions & 43 deletions authentik/core/templates/if/end_session.html

This file was deleted.

2 changes: 2 additions & 0 deletions authentik/core/tests/test_applications_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def test_list(self):
"assigned_application_name": "allowed",
"assigned_application_slug": "allowed",
"authentication_flow": None,
"invalidation_flow": None,
"authorization_flow": str(self.provider.authorization_flow.pk),
"component": "ak-provider-oauth2-form",
"meta_model_name": "authentik_providers_oauth2.oauth2provider",
Expand Down Expand Up @@ -186,6 +187,7 @@ def test_list_superuser_full_list(self):
"assigned_application_name": "allowed",
"assigned_application_slug": "allowed",
"authentication_flow": None,
"invalidation_flow": None,
"authorization_flow": str(self.provider.authorization_flow.pk),
"component": "ak-provider-oauth2-form",
"meta_model_name": "authentik_providers_oauth2.oauth2provider",
Expand Down
Loading

0 comments on commit 0e4596a

Please sign in to comment.