mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Fix: use PAPERLESS_URL if set for pw reset emails (#5902)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from urllib.parse import quote
|
||||
|
||||
from allauth.account.adapter import DefaultAccountAdapter
|
||||
from allauth.core import context
|
||||
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
|
||||
@@ -45,6 +47,20 @@ class CustomAccountAdapter(DefaultAccountAdapter):
|
||||
|
||||
return url_has_allowed_host_and_scheme(url, allowed_hosts=allowed_hosts)
|
||||
|
||||
def get_reset_password_from_key_url(self, key):
|
||||
"""
|
||||
Return the URL to reset a password e.g. in reset email.
|
||||
"""
|
||||
if settings.PAPERLESS_URL is None:
|
||||
return super().get_reset_password_from_key_url(key)
|
||||
else:
|
||||
path = reverse(
|
||||
"account_reset_password_from_key",
|
||||
kwargs={"uidb36": "UID", "key": "KEY"},
|
||||
)
|
||||
path = path.replace("UID-KEY", quote(key))
|
||||
return settings.PAPERLESS_URL + path
|
||||
|
||||
|
||||
class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
|
||||
def is_open_for_signup(self, request, sociallogin):
|
||||
|
@@ -437,6 +437,8 @@ SOCIALACCOUNT_PROVIDERS = json.loads(
|
||||
os.getenv("PAPERLESS_SOCIALACCOUNT_PROVIDERS", "{}"),
|
||||
)
|
||||
|
||||
ACCOUNT_EMAIL_SUBJECT_PREFIX = "[Paperless-ngx] "
|
||||
|
||||
DISABLE_REGULAR_LOGIN = __get_boolean("PAPERLESS_DISABLE_REGULAR_LOGIN")
|
||||
|
||||
AUTO_LOGIN_USERNAME = os.getenv("PAPERLESS_AUTO_LOGIN_USERNAME")
|
||||
@@ -498,18 +500,23 @@ if DEBUG:
|
||||
CORS_ALLOWED_ORIGINS.append("http://localhost:4200")
|
||||
|
||||
ALLOWED_HOSTS = __get_list("PAPERLESS_ALLOWED_HOSTS", ["*"])
|
||||
|
||||
_paperless_url = os.getenv("PAPERLESS_URL")
|
||||
if _paperless_url:
|
||||
_paperless_uri = urlparse(_paperless_url)
|
||||
CSRF_TRUSTED_ORIGINS.append(_paperless_url)
|
||||
CORS_ALLOWED_ORIGINS.append(_paperless_url)
|
||||
|
||||
if ["*"] != ALLOWED_HOSTS:
|
||||
# always allow localhost. Necessary e.g. for healthcheck in docker.
|
||||
ALLOWED_HOSTS.append("localhost")
|
||||
if _paperless_url:
|
||||
ALLOWED_HOSTS.append(_paperless_uri.hostname)
|
||||
|
||||
|
||||
def _parse_paperless_url():
|
||||
global CSRF_TRUSTED_ORIGINS, CORS_ALLOWED_ORIGINS, ALLOWED_HOSTS
|
||||
url = os.getenv("PAPERLESS_URL")
|
||||
if url:
|
||||
CSRF_TRUSTED_ORIGINS.append(url)
|
||||
CORS_ALLOWED_ORIGINS.append(url)
|
||||
ALLOWED_HOSTS.append(urlparse(url).hostname)
|
||||
|
||||
return url
|
||||
|
||||
|
||||
PAPERLESS_URL = _parse_paperless_url()
|
||||
|
||||
# For use with trusted proxies
|
||||
TRUSTED_PROXIES = __get_list("PAPERLESS_TRUSTED_PROXIES")
|
||||
@@ -1126,3 +1133,6 @@ DEFAULT_FROM_EMAIL: Final[str] = os.getenv("PAPERLESS_EMAIL_FROM", EMAIL_HOST_US
|
||||
EMAIL_USE_TLS: Final[bool] = __get_boolean("PAPERLESS_EMAIL_USE_TLS")
|
||||
EMAIL_USE_SSL: Final[bool] = __get_boolean("PAPERLESS_EMAIL_USE_SSL")
|
||||
EMAIL_SUBJECT_PREFIX: Final[str] = "[Paperless-ngx] "
|
||||
if DEBUG: # pragma: no cover
|
||||
EMAIL_BACKEND = "django.core.mail.backends.filebased.EmailBackend"
|
||||
EMAIL_FILE_PATH = BASE_DIR / "sent_emails"
|
||||
|
@@ -61,6 +61,27 @@ class TestCustomAccountAdapter(TestCase):
|
||||
with self.assertRaises(ValidationError):
|
||||
adapter.pre_authenticate(request)
|
||||
|
||||
def test_get_reset_password_from_key_url(self):
|
||||
request = HttpRequest()
|
||||
request.get_host = mock.Mock(return_value="foo.org")
|
||||
with context.request_context(request):
|
||||
adapter = get_adapter()
|
||||
|
||||
# Test when PAPERLESS_URL is None
|
||||
expected_url = f"https://foo.org{reverse('account_reset_password_from_key', kwargs={'uidb36': 'UID', 'key': 'KEY'})}"
|
||||
self.assertEqual(
|
||||
adapter.get_reset_password_from_key_url("UID-KEY"),
|
||||
expected_url,
|
||||
)
|
||||
|
||||
# Test when PAPERLESS_URL is not None
|
||||
with override_settings(PAPERLESS_URL="https://bar.com"):
|
||||
expected_url = f"https://bar.com{reverse('account_reset_password_from_key', kwargs={'uidb36': 'UID', 'key': 'KEY'})}"
|
||||
self.assertEqual(
|
||||
adapter.get_reset_password_from_key_url("UID-KEY"),
|
||||
expected_url,
|
||||
)
|
||||
|
||||
|
||||
class TestCustomSocialAccountAdapter(TestCase):
|
||||
def test_is_open_for_signup(self):
|
||||
|
@@ -8,6 +8,7 @@ from celery.schedules import crontab
|
||||
from paperless.settings import _parse_beat_schedule
|
||||
from paperless.settings import _parse_db_settings
|
||||
from paperless.settings import _parse_ignore_dates
|
||||
from paperless.settings import _parse_paperless_url
|
||||
from paperless.settings import _parse_redis_url
|
||||
from paperless.settings import default_threads_per_worker
|
||||
|
||||
@@ -349,3 +350,27 @@ class TestDBSettings(TestCase):
|
||||
},
|
||||
databases["sqlite"]["OPTIONS"],
|
||||
)
|
||||
|
||||
|
||||
class TestPaperlessURLSettings(TestCase):
|
||||
def test_paperless_url(self):
|
||||
"""
|
||||
GIVEN:
|
||||
- PAPERLESS_URL is set
|
||||
WHEN:
|
||||
- The URL is parsed
|
||||
THEN:
|
||||
- The URL is returned and present in related settings
|
||||
"""
|
||||
with mock.patch.dict(
|
||||
os.environ,
|
||||
{
|
||||
"PAPERLESS_URL": "https://example.com",
|
||||
},
|
||||
):
|
||||
url = _parse_paperless_url()
|
||||
self.assertEqual("https://example.com", url)
|
||||
from django.conf import settings
|
||||
|
||||
self.assertIn(url, settings.CSRF_TRUSTED_ORIGINS)
|
||||
self.assertIn(url, settings.CORS_ALLOWED_ORIGINS)
|
||||
|
Reference in New Issue
Block a user