Skip to content

Commit

Permalink
Merge branch 'main' into web/enhance/better-empty-app-search
Browse files Browse the repository at this point in the history
* main: (97 commits)
  web: bump API Client version (#10252)
  website/docs: update geoip and asn example to use the proper syntax (cherry-pick #10249) (#10250)
  website/docs: update the Welcome page (#10222)
  website/docs: update geoip and asn example to use the proper syntax (#10249)
  security: update supported versions (cherry-pick #10247) (#10248)
  security: update supported versions (#10247)
  website/docs: remove RC disclaimer from 2024.6 release notes (cherry-pick #10245) (#10246)
  website/docs: remove RC disclaimer from 2024.6 release notes (#10245)
  website/docs: update 2024.6 release notes with latest changes (cherry-pick #10228) (#10243)
  website/docs: update 2024.4 release notes with latest changes (#10231)
  website/docs: update 2024.2 release notes with security fixes (#10232)
  website/docs: update 2024.6 release notes with latest changes (#10228)
  release: 2024.6.0
  security: fix CVE-2024-37905 (cherry-pick #10230) (#10237)
  core: bump pdoc from 14.5.0 to 14.5.1 (#10221)
  web: bump chromedriver from 126.0.3 to 126.0.4 in /tests/wdio (#10223)
  core: bump webauthn from 2.1.0 to 2.2.0 (#10224)
  web: bump @sentry/browser from 8.11.0 to 8.12.0 in /web in the sentry group (#10226)
  core: bump debugpy from 1.8.1 to 1.8.2 (#10225)
  security: fix CVE-2024-37905 (#10230)
  ...
  • Loading branch information
kensternberg-authentik committed Jun 26, 2024
2 parents 01320f0 + 632f098 commit db67d36
Show file tree
Hide file tree
Showing 138 changed files with 1,559 additions and 1,095 deletions.
4 changes: 3 additions & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2024.4.2
current_version = 2024.6.0
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 All @@ -17,6 +17,8 @@ optional_value = final

[bumpversion:file:pyproject.toml]

[bumpversion:file:package.json]

[bumpversion:file:docker-compose.yml]

[bumpversion:file:schema.yml]
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 @@ -240,7 +240,7 @@ jobs:
- name: generate ts client
run: make gen-client-ts
- name: Build Docker Image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
secrets: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-outpost.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
- name: Generate API
run: make gen-client-go
- name: Build Docker Image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
tags: ${{ steps.ev.outputs.imageTags }}
file: ${{ matrix.type }}.Dockerfile
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
mkdir -p ./gen-ts-api
mkdir -p ./gen-go-api
- name: Build Docker Image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
push: true
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Docker Image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
push: true
tags: ${{ steps.ev.outputs.imageTags }}
Expand Down Expand Up @@ -155,8 +155,8 @@ jobs:
- uses: actions/checkout@v4
- name: Run test suite in final docker images
run: |
echo "PG_PASS=$(openssl rand 32 | base64)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64)" >> .env
echo "PG_PASS=$(openssl rand 32 | base64 -w 0)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64 -w 0)" >> .env
docker compose pull -q
docker compose up --no-start
docker compose start postgresql redis
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
- uses: actions/checkout@v4
- name: Pre-release test
run: |
echo "PG_PASS=$(openssl rand 32 | base64)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64)" >> .env
echo "PG_PASS=$(openssl rand 32 | base64 -w 0)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64 -w 0)" >> .env
docker buildx install
mkdir -p ./gen-ts-api
docker build -t testing:latest .
Expand Down
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ RUN npm run build-bundled
# Stage 2: Build webui
FROM --platform=${BUILDPLATFORM} docker.io/node:22 as web-builder

ARG GIT_BUILD_HASH
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
ENV NODE_ENV=production

WORKDIR /work/web
Expand All @@ -31,6 +33,7 @@ RUN --mount=type=bind,target=/work/web/package.json,src=./web/package.json \
--mount=type=cache,id=npm-web,sharing=shared,target=/root/.npm \
npm ci --include=dev

COPY ./package.json /work
COPY ./web /work/web/
COPY ./website /work/website/
COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
Expand Down
10 changes: 6 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ test-go:
go test -timeout 0 -v -race -cover ./...

test-docker: ## Run all tests in a docker-compose
echo "PG_PASS=$(shell openssl rand 32 | base64)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(shell openssl rand 32 | base64)" >> .env
echo "PG_PASS=$(shell openssl rand 32 | base64 -w 0)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(shell openssl rand 32 | base64 -w 0)" >> .env
docker compose pull -q
docker compose up --no-start
docker compose start postgresql redis
Expand All @@ -60,9 +60,11 @@ test: ## Run the server tests and produce a coverage report (locally)
coverage html
coverage report

lint-fix: ## Lint and automatically fix errors in the python source code. Reports spelling errors.
lint-fix: lint-codespell ## Lint and automatically fix errors in the python source code. Reports spelling errors.
black $(PY_SOURCES)
ruff check --fix $(PY_SOURCES)

lint-codespell: ## Reports spelling errors.
codespell -w $(CODESPELL_ARGS)

lint: ## Lint the python and golang sources
Expand Down Expand Up @@ -239,7 +241,7 @@ website: website-lint-fix website-build ## Automatically fix formatting issues
website-install:
cd website && npm ci

website-lint-fix:
website-lint-fix: lint-codespell
cd website && npm run prettier

website-build:
Expand Down
8 changes: 4 additions & 4 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni

(.x being the latest patch release for each version)

| Version | Supported |
| --------- | --------- |
| 2023.10.x ||
| 2024.2.x ||
| Version | Supported |
| -------- | --------- |
| 2024.4.x ||
| 2024.6.x ||

## Reporting a Vulnerability

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.4.2"
__version__ = "2024.6.0"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"


Expand Down
2 changes: 1 addition & 1 deletion authentik/admin/api/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class RuntimeDict(TypedDict):
platform: str
uname: str
openssl_version: str
openssl_fips_mode: bool | None
openssl_fips_enabled: bool | None
authentik_version: str


Expand Down
4 changes: 2 additions & 2 deletions authentik/api/templates/api/browser.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{% extends "base/skeleton.html" %}

{% load static %}
{% load authentik_core %}

{% block title %}
API Browser - {{ brand.branding_title }}
{% endblock %}

{% block head %}
<script src="{% static 'dist/standalone/api-browser/index.js' %}?version={{ version }}" type="module"></script>
{% versioned_script "dist/standalone/api-browser/index-%v.js" %}
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#151515" media="(prefers-color-scheme: dark)">
{% endblock %}
Expand Down
3 changes: 1 addition & 2 deletions authentik/brands/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
from rest_framework.permissions import AllowAny
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.validators import UniqueValidator
from rest_framework.viewsets import ModelViewSet

from authentik.api.authorization import SecretKeyFilter
from authentik.brands.models import Brand
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import PassiveSerializer
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
from authentik.tenants.utils import get_current_tenant


Expand Down
2 changes: 1 addition & 1 deletion authentik/core/api/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from rest_framework.parsers import MultiPartParser
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from structlog.stdlib import get_logger

Expand All @@ -26,6 +25,7 @@
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
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
Expand Down
2 changes: 1 addition & 1 deletion authentik/core/api/authenticated_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
from rest_framework.fields import SerializerMethodField
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.request import Request
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from ua_parser import user_agent_parser

from authentik.api.authorization import OwnerSuperuserPermissions
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import ModelSerializer
from authentik.core.models import AuthenticatedSession
from authentik.events.context_processors.asn import ASN_CONTEXT_PROCESSOR, ASNDict
from authentik.events.context_processors.geoip import GEOIP_CONTEXT_PROCESSOR, GeoIPDict
Expand Down
4 changes: 2 additions & 2 deletions authentik/core/api/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
from rest_framework.fields import CharField, IntegerField, SerializerMethodField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ListSerializer, ModelSerializer, ValidationError
from rest_framework.serializers import ListSerializer, ValidationError
from rest_framework.validators import UniqueValidator
from rest_framework.viewsets import ModelViewSet

from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import JSONDictField, PassiveSerializer
from authentik.core.api.utils import JSONDictField, ModelSerializer, PassiveSerializer
from authentik.core.models import Group, User
from authentik.rbac.api.roles import RoleSerializer
from authentik.rbac.decorators import permission_required
Expand Down
4 changes: 2 additions & 2 deletions authentik/core/api/property_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
from rest_framework import mixins
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework.fields import BooleanField, CharField
from rest_framework.fields import BooleanField, CharField, SerializerMethodField
from rest_framework.relations import PrimaryKeyRelatedField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.viewsets import GenericViewSet

from authentik.blueprints.api import ManagedSerializer
from authentik.core.api.object_types import TypesMixin
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import (
MetaNameSerializer,
ModelSerializer,
PassiveSerializer,
)
from authentik.core.expression.evaluator import PropertyMappingEvaluator
Expand Down
5 changes: 2 additions & 3 deletions authentik/core/api/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
from django_filters.filters import BooleanFilter
from django_filters.filterset import FilterSet
from rest_framework import mixins
from rest_framework.fields import ReadOnlyField
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from rest_framework.fields import ReadOnlyField, SerializerMethodField
from rest_framework.viewsets import GenericViewSet

from authentik.core.api.object_types import TypesMixin
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer
from authentik.core.api.utils import MetaNameSerializer, ModelSerializer
from authentik.core.models import Provider


Expand Down
3 changes: 1 addition & 2 deletions authentik/core/api/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
from rest_framework.parsers import MultiPartParser
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from structlog.stdlib import get_logger

from authentik.api.authorization import OwnerFilter, OwnerSuperuserPermissions
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.core.api.object_types import TypesMixin
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer
from authentik.core.api.utils import MetaNameSerializer, ModelSerializer
from authentik.core.models import Source, UserSourceConnection
from authentik.core.types import UserSettingSerializer
from authentik.lib.utils.file import (
Expand Down
10 changes: 8 additions & 2 deletions authentik/core/api/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@
from rest_framework.filters import OrderingFilter, SearchFilter
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet

from authentik.api.authorization import OwnerSuperuserPermissions
from authentik.blueprints.api import ManagedSerializer
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
from authentik.core.models import (
USER_ATTRIBUTE_TOKEN_EXPIRING,
USER_ATTRIBUTE_TOKEN_MAXIMUM_LIFETIME,
Expand All @@ -45,6 +44,13 @@ def __init__(self, *args, **kwargs) -> None:
if SERIALIZER_CONTEXT_BLUEPRINT in self.context:
self.fields["key"] = CharField(required=False)

def validate_user(self, user: User):
"""Ensure user of token cannot be changed"""
if self.instance and self.instance.user_id:
if user.pk != self.instance.user_id:
raise ValidationError("User cannot be changed")
return user

def validate(self, attrs: dict[Any, str]) -> dict[Any, str]:
"""Ensure only API or App password tokens are created."""
request: Request = self.context.get("request")
Expand Down
8 changes: 6 additions & 2 deletions authentik/core/api/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
BooleanField,
DateTimeField,
ListSerializer,
ModelSerializer,
PrimaryKeyRelatedField,
ValidationError,
)
Expand All @@ -52,7 +51,12 @@
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT
from authentik.brands.models import Brand
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import JSONDictField, LinkSerializer, PassiveSerializer
from authentik.core.api.utils import (
JSONDictField,
LinkSerializer,
ModelSerializer,
PassiveSerializer,
)
from authentik.core.middleware import (
SESSION_KEY_IMPERSONATE_ORIGINAL_USER,
SESSION_KEY_IMPERSONATE_USER,
Expand Down
36 changes: 36 additions & 0 deletions authentik/core/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
JSONField,
SerializerMethodField,
)
from rest_framework.serializers import ModelSerializer as BaseModelSerializer
from rest_framework.serializers import (
Serializer,
ValidationError,
model_meta,
raise_errors_on_nested_writes,
)


Expand All @@ -25,6 +28,39 @@ def is_dict(value: Any):
raise ValidationError("Value must be a dictionary, and not have any duplicate keys.")


class ModelSerializer(BaseModelSerializer):

def update(self, instance: Model, validated_data):
raise_errors_on_nested_writes("update", self, validated_data)
info = model_meta.get_field_info(instance)

# Simply set each attribute on the instance, and then save it.
# Note that unlike `.create()` we don't need to treat many-to-many
# relationships as being a special case. During updates we already
# have an instance pk for the relationships to be associated with.
m2m_fields = []
for attr, value in validated_data.items():
if attr in info.relations and info.relations[attr].to_many:
m2m_fields.append((attr, value))
else:
setattr(instance, attr, value)

instance.save()

# Note that many-to-many fields are set after updating instance.
# Setting m2m fields triggers signals which could potentially change
# updated instance and we do not want it to collide with .update()
for attr, value in m2m_fields:
field = getattr(instance, attr)
# We can't check for inheritance here as m2m managers are generated dynamically
if field.__class__.__name__ == "RelatedManager":
field.set(value, bulk=False)
else:
field.set(value)

return instance


class JSONDictField(JSONField):
"""JSON Field which only allows dictionaries"""

Expand Down
Loading

0 comments on commit db67d36

Please sign in to comment.