Merge pull request #3516 from ajgon/fix/http-remote-user-api

Fix: KeyError error on unauthenticated API calls
This commit is contained in:
shamoon 2023-06-03 09:05:50 -07:00 committed by GitHub
commit 569165371c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 14 deletions

View File

@ -1,6 +1,6 @@
from django.conf import settings from django.conf import settings
from django.contrib import auth from django.contrib import auth
from django.contrib.auth.middleware import RemoteUserMiddleware from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils.deprecation import MiddlewareMixin from django.utils.deprecation import MiddlewareMixin
from rest_framework import authentication from rest_framework import authentication
@ -37,7 +37,7 @@ class AngularApiAuthenticationOverride(authentication.BaseAuthentication):
return None return None
class HttpRemoteUserMiddleware(RemoteUserMiddleware): class HttpRemoteUserMiddleware(PersistentRemoteUserMiddleware):
"""This class allows authentication via HTTP_REMOTE_USER which is set for """This class allows authentication via HTTP_REMOTE_USER which is set for
example by certain SSO applications. example by certain SSO applications.
""" """

View File

@ -12,22 +12,21 @@ def handle_failed_login(sender, credentials, request, **kwargs):
client_ip, _ = ipware.get_client_ip( client_ip, _ = ipware.get_client_ip(
meta=request.META, meta=request.META,
) )
username = credentials.get("username")
log_output = (
"No authentication provided"
if username is None
else f"Login failed for user `{username}`"
)
if client_ip is None: if client_ip is None:
logger.info( log_output += ". Unable to determine IP address."
f"Login failed for user `{credentials['username']}`."
" Unable to determine IP address.",
)
else: else:
if client_ip.is_global: if client_ip.is_global:
# We got the client's IP address # We got the client's IP address
logger.info( log_output += f" from IP `{client_ip}.`"
f"Login failed for user `{credentials['username']}`"
f" from IP `{client_ip}.`",
)
else: else:
# The client's IP address is private # The client's IP address is private
logger.info( log_output += f" from private IP `{client_ip}.`"
f"Login failed for user `{credentials['username']}`"
f" from private IP `{client_ip}.`", logger.info(log_output)
)

View File

@ -12,6 +12,26 @@ class TestFailedLoginLogging(TestCase):
"username": "john lennon", "username": "john lennon",
} }
def test_unauthenticated(self):
"""
GIVEN:
- Request with no authentication provided
WHEN:
- Request provided to signal handler
THEN:
- Unable to determine logged for unauthenticated user
"""
request = HttpRequest()
request.META = {}
with self.assertLogs("paperless.auth") as logs:
handle_failed_login(None, {}, request)
self.assertEqual(
logs.output,
[
"INFO:paperless.auth:No authentication provided. Unable to determine IP address.",
],
)
def test_none(self): def test_none(self):
""" """
GIVEN: GIVEN: