lib: add user attribute "goauthentik.io/user/override-ips" to allow overriding of client ips

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-05-08 21:42:31 +02:00
parent f1fd223bc7
commit d751a7fc4c
3 changed files with 24 additions and 1 deletions

View File

@ -3,6 +3,9 @@ from typing import Any, Optional
from django.http import HttpRequest from django.http import HttpRequest
OUTPOST_REMOTE_IP_HEADER = "HTTP_X_AUTHENTIK_REMOTE_IP"
USER_ATTRIBUTE_CAN_OVERRIDE_IP = "goauthentik.io/user/override-ips"
def _get_client_ip_from_meta(meta: dict[str, Any]) -> Optional[str]: def _get_client_ip_from_meta(meta: dict[str, Any]) -> Optional[str]:
"""Attempt to get the client's IP by checking common HTTP Headers. """Attempt to get the client's IP by checking common HTTP Headers.
@ -18,9 +21,27 @@ def _get_client_ip_from_meta(meta: dict[str, Any]) -> Optional[str]:
return None return None
def _get_outpost_override_ip(request: HttpRequest) -> Optional[str]:
"""Get the actual remote IP when set by an outpost. Only
allowed when the request is authenticated, by a user with USER_ATTRIBUTE_CAN_OVERRIDE_IP set
to outpost"""
if not hasattr(request, "user"):
return None
if not request.user.is_authenticated:
return None
if OUTPOST_REMOTE_IP_HEADER not in request.META:
return None
if request.user.attributes.get(USER_ATTRIBUTE_CAN_OVERRIDE_IP, False):
return None
return request.META[OUTPOST_REMOTE_IP_HEADER]
def get_client_ip(request: Optional[HttpRequest]) -> Optional[str]: def get_client_ip(request: Optional[HttpRequest]) -> Optional[str]:
"""Attempt to get the client's IP by checking common HTTP Headers. """Attempt to get the client's IP by checking common HTTP Headers.
Returns none if no IP Could be found""" Returns none if no IP Could be found"""
if request: if request:
override = _get_outpost_override_ip(request)
if override:
return override
return _get_client_ip_from_meta(request.META) return _get_client_ip_from_meta(request.META)
return None return None

View File

@ -32,6 +32,7 @@ from authentik.crypto.models import CertificateKeyPair
from authentik.lib.config import CONFIG from authentik.lib.config import CONFIG
from authentik.lib.models import InheritanceForeignKey from authentik.lib.models import InheritanceForeignKey
from authentik.lib.sentry import SentryIgnoredException from authentik.lib.sentry import SentryIgnoredException
from authentik.lib.utils.http import USER_ATTRIBUTE_CAN_OVERRIDE_IP
from authentik.outposts.docker_tls import DockerInlineTLS from authentik.outposts.docker_tls import DockerInlineTLS
OUR_VERSION = parse(__version__) OUR_VERSION = parse(__version__)
@ -330,6 +331,7 @@ class Outpost(models.Model):
if not users.exists(): if not users.exists():
user: User = User.objects.create(username=self.user_identifier) user: User = User.objects.create(username=self.user_identifier)
user.attributes[USER_ATTRIBUTE_SA] = True user.attributes[USER_ATTRIBUTE_SA] = True
user.attributes[USER_ATTRIBUTE_CAN_OVERRIDE_IP] = True
user.set_unusable_password() user.set_unusable_password()
user.save() user.save()
else: else:

View File

@ -70,7 +70,7 @@ export class EventListPage extends TablePage<Event> {
renderExpanded(item: Event): TemplateResult { renderExpanded(item: Event): TemplateResult {
return html` return html`
<td role="cell" colspan="1"> <td role="cell" colspan="3">
<div class="pf-c-table__expandable-row-content"> <div class="pf-c-table__expandable-row-content">
<ak-event-info .event=${item as EventWithContext}></ak-event-info> <ak-event-info .event=${item as EventWithContext}></ak-event-info>
</div> </div>