mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Log failed login attempts
This commit is contained in:
parent
9893ae9880
commit
668b068bb5
1
Pipfile
1
Pipfile
@ -67,6 +67,7 @@ djangorestframework-guardian = "*"
|
||||
# Locked version until https://github.com/django/channels_redis/issues/332
|
||||
# is resolved
|
||||
channels-redis = "==3.4.1"
|
||||
django-ipware = "*"
|
||||
|
||||
|
||||
[dev-packages]
|
||||
|
10
Pipfile.lock
generated
10
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "99f415c5ce96020dc3fcb137dc15d47cc5431686bdce1ca42e6254a2719060a8"
|
||||
"sha256": "0e1a26c5e9acb1d745f951f92d00d60272f83406467d90551e558972697b53cd"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@ -480,6 +480,14 @@
|
||||
"index": "pypi",
|
||||
"version": "==2.4.0"
|
||||
},
|
||||
"django-ipware": {
|
||||
"hashes": [
|
||||
"sha256:602a58325a4808bd19197fef2676a0b2da2df40d0ecf21be414b2ff48c72ad05",
|
||||
"sha256:878dbb06a87e25550798e9ef3204ed70a200dd8b15e47dcef848cf08244f04c9"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.2"
|
||||
},
|
||||
"djangorestframework": {
|
||||
"hashes": [
|
||||
"sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8",
|
||||
|
@ -262,6 +262,14 @@ do CORS calls. Set this to your public domain name.
|
||||
|
||||
Defaults to "<http://localhost:8000>".
|
||||
|
||||
`PAPERLESS_TRUSTED_PROXIES=<comma-separated-list>`
|
||||
|
||||
: This may be needed to prevent IP address spoofing if you are using e.g.
|
||||
fail2ban with log entries for failed authorization attempts. Value should be
|
||||
IP address(es).
|
||||
|
||||
Defaults to empty string.
|
||||
|
||||
`PAPERLESS_FORCE_SCRIPT_NAME=<path>`
|
||||
|
||||
: To host paperless under a subpath url like example.com/paperless you
|
||||
|
15
src/paperless/apps.py
Normal file
15
src/paperless/apps.py
Normal file
@ -0,0 +1,15 @@
|
||||
from django.apps import AppConfig
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from paperless.signals import handle_failed_login
|
||||
|
||||
|
||||
class PaperlessConfig(AppConfig):
|
||||
name = "paperless"
|
||||
|
||||
verbose_name = _("Paperless")
|
||||
|
||||
def ready(self):
|
||||
from django.contrib.auth.signals import user_login_failed
|
||||
|
||||
user_login_failed.connect(handle_failed_login)
|
||||
AppConfig.ready(self)
|
@ -416,6 +416,13 @@ if _paperless_url:
|
||||
# always allow localhost. Necessary e.g. for healthcheck in docker.
|
||||
ALLOWED_HOSTS = [_paperless_uri.hostname] + ["localhost"]
|
||||
|
||||
# For use with trusted proxies
|
||||
_trusted_proxies = os.getenv("PAPERLESS_TRUSTED_PROXIES")
|
||||
if _trusted_proxies:
|
||||
TRUSTED_PROXIES = _trusted_proxies.split(",")
|
||||
else:
|
||||
TRUSTED_PROXIES = []
|
||||
|
||||
# The secret key has a default that should be fine so long as you're hosting
|
||||
# Paperless on a closed network. However, if you're putting this anywhere
|
||||
# public, you should change the key to something unique and verbose.
|
||||
|
32
src/paperless/signals.py
Normal file
32
src/paperless/signals.py
Normal file
@ -0,0 +1,32 @@
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from ipware import get_client_ip
|
||||
|
||||
logger = logging.getLogger("paperless.auth")
|
||||
|
||||
|
||||
# https://docs.djangoproject.com/en/4.1/ref/contrib/auth/#django.contrib.auth.signals.user_login_failed
|
||||
def handle_failed_login(sender, credentials, request, **kwargs):
|
||||
client_ip, is_routable = get_client_ip(
|
||||
request,
|
||||
proxy_trusted_ips=settings.TRUSTED_PROXIES,
|
||||
)
|
||||
if client_ip is None:
|
||||
logger.info(
|
||||
f"Login failed for user `{credentials['username']}`."
|
||||
+ " Unable to determine IP address.",
|
||||
)
|
||||
else:
|
||||
if is_routable:
|
||||
# We got the client's IP address
|
||||
logger.info(
|
||||
f"Login failed for user `{credentials['username']}`"
|
||||
+ f" from IP `{client_ip}.`",
|
||||
)
|
||||
else:
|
||||
# The client's IP address is private
|
||||
logger.info(
|
||||
f"Login failed for user `{credentials['username']}`"
|
||||
+ f" from private IP `{client_ip}.`",
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user