Skip to content

Commit

Permalink
Merge branch 'web/bug/fix-wdio-and-lint' into web/element/ak-select-t…
Browse files Browse the repository at this point in the history
…able

* web/bug/fix-wdio-and-lint:
  Forgot to run prettier.
  web: small fixes for wdio and lint
  providers/oauth2: improve indexes on tokens (#11543)
  web: bump API Client version (#11544)
  release: 2024.8.3 (#11542)
  package-lock.json update
  website: update release notes for 2024.8.3 and 2024.6.5 (#11541)
  website/docs: added a Docs banner to announce new docs structure (#11525)
  security: fix CVE-2024-47070 (#11536)
  security: fix CVE-2024-47077 (#11535)
  sources/ldap: fix ms_ad userAccountControl not checking for lockout (#11532)
  web: Fix missing integrity fields in package-lock.json (#11509)
  core, web: update translations (#11527)
  core: bump ruff from 0.6.7 to 0.6.8 (#11528)
  web: bump the wdio group across 2 directories with 3 updates (#11529)
  web: bump @patternfly/elements from 4.0.1 to 4.0.2 in /web (#11530)
  web: bump @types/node from 22.7.2 to 22.7.3 in /web (#11531)
  • Loading branch information
kensternberg-authentik committed Sep 27, 2024
2 parents 325b1df + 4302787 commit a9bb71a
Show file tree
Hide file tree
Showing 35 changed files with 4,803 additions and 2,194 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
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
16 changes: 16 additions & 0 deletions authentik/lib/tests/test_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ def test_forward_for(self):
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="127.0.0.2")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.2")

def test_forward_for_invalid(self):
"""Test invalid forward for"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="foobar")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), ClientIPMiddleware.default_ip)

def test_fake_outpost(self):
"""Test faked IP which is overridden by an outpost"""
token = Token.objects.create(
Expand All @@ -53,6 +58,17 @@ def test_fake_outpost(self):
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Invalid, not a real IP
self.user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT
self.user.save()
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "foobar",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Valid
self.user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT
self.user.save()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 5.0.9 on 2024-09-27 14:50

from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("authentik_providers_oauth2", "0019_accesstoken_authentik_p_token_4bc870_idx_and_more"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.RemoveIndex(
model_name="accesstoken",
name="authentik_p_token_4bc870_idx",
),
migrations.RemoveIndex(
model_name="refreshtoken",
name="authentik_p_token_1a841f_idx",
),
migrations.AddIndex(
model_name="accesstoken",
index=models.Index(fields=["token", "provider"], name="authentik_p_token_f99422_idx"),
),
migrations.AddIndex(
model_name="refreshtoken",
index=models.Index(fields=["token", "provider"], name="authentik_p_token_a1d921_idx"),
),
]
4 changes: 2 additions & 2 deletions authentik/providers/oauth2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class AccessToken(SerializerModel, ExpiringModel, BaseGrantModel):

class Meta:
indexes = [
models.Index(fields=["token"]),
models.Index(fields=["token", "provider"]),
]
verbose_name = _("OAuth2 Access Token")
verbose_name_plural = _("OAuth2 Access Tokens")
Expand Down Expand Up @@ -423,7 +423,7 @@ class RefreshToken(SerializerModel, ExpiringModel, BaseGrantModel):

class Meta:
indexes = [
models.Index(fields=["token"]),
models.Index(fields=["token", "provider"]),
]
verbose_name = _("OAuth2 Refresh Token")
verbose_name_plural = _("OAuth2 Refresh Tokens")
Expand Down
36 changes: 35 additions & 1 deletion authentik/providers/oauth2/tests/test_introspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def setUp(self) -> None:
self.app = Application.objects.create(
name=generate_id(), slug=generate_id(), provider=self.provider
)
self.app.save()
self.user = create_test_admin_user()
self.auth = b64encode(
f"{self.provider.client_id}:{self.provider.client_secret}".encode()
Expand Down Expand Up @@ -114,6 +113,41 @@ def test_introspect_invalid_token(self):
},
)

def test_introspect_invalid_provider(self):
"""Test introspection (mismatched provider and token)"""
provider: OAuth2Provider = OAuth2Provider.objects.create(
name=generate_id(),
authorization_flow=create_test_flow(),
redirect_uris="",
signing_key=create_test_cert(),
)
auth = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode()

token: AccessToken = AccessToken.objects.create(
provider=self.provider,
user=self.user,
token=generate_id(),
auth_time=timezone.now(),
_scope="openid user profile",
_id_token=json.dumps(
asdict(
IDToken("foo", "bar"),
)
),
)
res = self.client.post(
reverse("authentik_providers_oauth2:token-introspection"),
HTTP_AUTHORIZATION=f"Basic {auth}",
data={"token": token.token},
)
self.assertEqual(res.status_code, 200)
self.assertJSONEqual(
res.content.decode(),
{
"active": False,
},
)

def test_introspect_invalid_auth(self):
"""Test introspect (invalid auth)"""
res = self.client.post(
Expand Down
4 changes: 2 additions & 2 deletions authentik/providers/oauth2/views/introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ def from_request(request: HttpRequest) -> "TokenIntrospectionParams":
if not provider:
raise TokenIntrospectionError

access_token = AccessToken.objects.filter(token=raw_token).first()
access_token = AccessToken.objects.filter(token=raw_token, provider=provider).first()
if access_token:
return TokenIntrospectionParams(access_token, provider)
refresh_token = RefreshToken.objects.filter(token=raw_token).first()
refresh_token = RefreshToken.objects.filter(token=raw_token, provider=provider).first()
if refresh_token:
return TokenIntrospectionParams(refresh_token, provider)
LOGGER.debug("Token does not exist", token=raw_token)
Expand Down
23 changes: 17 additions & 6 deletions authentik/root/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from collections.abc import Callable
from hashlib import sha512
from ipaddress import ip_address
from time import perf_counter, time
from typing import Any

Expand Down Expand Up @@ -174,6 +175,7 @@ class ClientIPMiddleware:

def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
self.get_response = get_response
self.logger = get_logger().bind()

def _get_client_ip_from_meta(self, meta: dict[str, Any]) -> str:
"""Attempt to get the client's IP by checking common HTTP Headers.
Expand All @@ -185,11 +187,16 @@ def _get_client_ip_from_meta(self, meta: dict[str, Any]) -> str:
"HTTP_X_FORWARDED_FOR",
"REMOTE_ADDR",
)
for _header in headers:
if _header in meta:
ips: list[str] = meta.get(_header).split(",")
return ips[0].strip()
return self.default_ip
try:
for _header in headers:
if _header in meta:
ips: list[str] = meta.get(_header).split(",")
# Ensure the IP parses as a valid IP
return str(ip_address(ips[0].strip()))
return self.default_ip
except ValueError as exc:
self.logger.debug("Invalid remote IP", exc=exc)
return self.default_ip

# FIXME: this should probably not be in `root` but rather in a middleware in `outposts`
# but for now it's fine
Expand Down Expand Up @@ -226,7 +233,11 @@ def _get_outpost_override_ip(self, request: HttpRequest) -> str | None:
Scope.get_isolation_scope().set_user(sentry_user)
# Set the outpost service account on the request
setattr(request, self.request_attr_outpost_user, user)
return delegated_ip
try:
return str(ip_address(delegated_ip))
except ValueError as exc:
self.logger.debug("Invalid remote IP from Outpost", exc=exc)
return None

def _get_client_ip(self, request: HttpRequest | None) -> str:
"""Attempt to get the client's IP by checking common HTTP Headers.
Expand Down
4 changes: 3 additions & 1 deletion authentik/sources/ldap/sync/vendor/ms_ad.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ def ms_check_uac(self, attributes: dict[str, Any], user: User):
# /useraccountcontrol-manipulate-account-properties
uac_bit = attributes.get("userAccountControl", 512)
uac = UserAccountControl(uac_bit)
is_active = UserAccountControl.ACCOUNTDISABLE not in uac
is_active = (
UserAccountControl.ACCOUNTDISABLE not in uac and UserAccountControl.LOCKOUT not in uac
)
if is_active != user.is_active:
user.is_active = is_active
user.save()
2 changes: 2 additions & 0 deletions blueprints/default/flow-default-authentication-flow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,5 @@ entries:
order: 10
target: !KeyOf default-authentication-flow-password-binding
policy: !KeyOf default-authentication-flow-password-optional
attrs:
failure_result: true
2 changes: 1 addition & 1 deletion blueprints/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object",
"title": "authentik 2024.8.2 Blueprint schema",
"title": "authentik 2024.8.3 Blueprint schema",
"required": [
"version",
"entries"
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.3}
restart: unless-stopped
command: server
environment:
Expand All @@ -52,7 +52,7 @@ services:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.2}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.3}
restart: unless-stopped
command: worker
environment:
Expand Down
2 changes: 1 addition & 1 deletion internal/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion())
}

const VERSION = "2024.8.2"
const VERSION = "2024.8.3"
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@goauthentik/authentik",
"version": "2024.8.2",
"version": "2024.8.3",
"private": true
}
38 changes: 19 additions & 19 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "authentik"
version = "2024.8.2"
version = "2024.8.3"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]

Expand Down
2 changes: 1 addition & 1 deletion schema.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2024.8.2
version: 2024.8.3
description: Making authentication simple.
contact:
email: hello@goauthentik.io
Expand Down
Loading

0 comments on commit a9bb71a

Please sign in to comment.