]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Feature: automatic sso redirect (#7168)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Mon, 8 Jul 2024 22:38:23 +0000 (15:38 -0700)
committerGitHub <noreply@github.com>
Mon, 8 Jul 2024 22:38:23 +0000 (22:38 +0000)
docs/advanced_usage.md
docs/configuration.md
src/documents/context_processors.py
src/documents/templates/account/login.html
src/documents/templates/paperless-ngx/base.html
src/documents/templates/socialaccount/login.html
src/paperless/settings.py
src/paperless/tests/test_settings.py

index 14f2e49ab43296a7f8a6757131524b8922833e5c..d2c47209ec82866018c59aea011d874ffa328f5b 100644 (file)
@@ -687,4 +687,5 @@ More details about configuration option for various providers can be found in th
 
 ### Disabling Regular Login
 
-Once external auth is set up, 'regular' login can be disabled with the [PAPERLESS_DISABLE_REGULAR_LOGIN](configuration.md#PAPERLESS_DISABLE_REGULAR_LOGIN) setting.
+Once external auth is set up, 'regular' login can be disabled with the [PAPERLESS_DISABLE_REGULAR_LOGIN](configuration.md#PAPERLESS_DISABLE_REGULAR_LOGIN) setting and / or users can be automatically
+redirected with the [PAPERLESS_REDIRECT_LOGIN_TO_SSO](configuration.md#PAPERLESS_REDIRECT_LOGIN_TO_SSO) setting.
index d16943c37f90ab2190c1c80d2f908b4ab6188517..63c2c76107e799b8274d292d069290bc9df8c7f3 100644 (file)
@@ -596,6 +596,14 @@ system. See the corresponding
 
 : Disables the regular frontend username / password login, i.e. once you have setup SSO. Note that this setting does not disable the Django admin login. To prevent logins directly to Django, consider blocking `/admin/` in your [web server or reverse proxy configuration](https://github.com/paperless-ngx/paperless-ngx/wiki/Using-a-Reverse-Proxy-with-Paperless-ngx).
 
+You can optionally also automatically redirect users to the SSO login with [PAPERLESS_REDIRECT_LOGIN_TO_SSO](#PAPERLESS_REDIRECT_LOGIN_TO_SSO)
+
+    Defaults to False
+
+#### ['PAPERLESS_REDIRECT_LOGIN_TO_SSO=<bool>`](#PAPERLESS_REDIRECT_LOGIN_TO_SSO) {#PAPERLESS_REDIRECT_LOGIN_TO_SSO}
+
+: When this setting is enabled users will automatically be redirected (using javascript) to the first SSO provider login. You may still want to disable the frontend login form for clarity.
+
     Defaults to False
 
 #### [`PAPERLESS_ACCOUNT_SESSION_REMEMBER=<bool>`](#PAPERLESS_ACCOUNT_SESSION_REMEMBER) {#PAPERLESS_ACCOUNT_SESSION_REMEMBER}
index 91a7ce39103c8e593e6cdf094b537b2574f6d59a..a9200ac11cdb0ed3aa385030c831be629063f073 100644 (file)
@@ -21,6 +21,7 @@ def settings(request):
         "EMAIL_ENABLED": django_settings.EMAIL_HOST != "localhost"
         or django_settings.EMAIL_HOST_USER != "",
         "DISABLE_REGULAR_LOGIN": django_settings.DISABLE_REGULAR_LOGIN,
+        "REDIRECT_LOGIN_TO_SSO": django_settings.REDIRECT_LOGIN_TO_SSO,
         "ACCOUNT_ALLOW_SIGNUPS": django_settings.ACCOUNT_ALLOW_SIGNUPS,
         "domain": getattr(django_settings, "PAPERLESS_URL", request.get_host()),
         "APP_TITLE": app_title,
index 5613b98459c31a86b9333648c692a666079c0d9b..e3e9ec40a4144e4461bc10251781d3cfcc5f112e 100644 (file)
                 {% if provider.id == "openid" %}
                     {% for brand in provider.get_brands %}
                         {% provider_login_url provider openid=brand.openid_url process=process as href %}
-                    <li class="d-grid mt-3"><a class="btn btn-secondary" href="{{ href }}">{{ brand.name }}</a></li>
+                    <li class="d-grid mt-3"><a class="btn btn-secondary oidc-url" href="{{ href }}">{{ brand.name }}</a></li>
                     {% endfor %}
                 {% else %}
-                {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %}
-                <li class="d-grid mt-3">
-                  <form class="d-grid" method="POST" action="{{ href }}">
-                    {% csrf_token %}
-                    <button type="submit" class="btn btn-secondary">{{ provider.name }}</button>
-                  </form>
-                </li>
+                    {% provider_login_url provider process=process scope=scope auth_params=auth_params as href %}
+                        <li class="d-grid mt-3">
+                            <form id="social-login" class="d-grid" method="POST" action="{{ href }}">
+                                {% csrf_token %}
+                                <button type="submit" class="btn btn-secondary">{{ provider.name }}</button>
+                            </form>
+                        </li>
+                    {% if REDIRECT_LOGIN_TO_SSO and forloop.counter0 == 0 and request.GET.loggedout != '1' %}
+                        <script type="text/javascript">
+                            const form = document.getElementById('social-login');
+                            if (form) {
+                                form.submit();
+                            } else {
+                                if (document.getElementsByClassName('oidc-url').length > 0) {
+                                    document.getElementsByClassName('oidc-url')[0].click();
+                                }
+                            }
+                        </script>
+                    {% endif %}
                 {% endif %}
             {% endfor %}
         </ul>
index 49fc0edf469ca351cf614220d5871615378e7f5f..4b9a91120749d04ee98fcae1a21a905ba69a2605 100644 (file)
@@ -18,7 +18,7 @@
 
     <body class="text-center">
         <div class="position-absolute top-50 start-50 translate-middle">
-            <form class="form-accounts" method="post">
+            <form class="form-accounts" id="form-account" method="post">
                 {% csrf_token %}
                 {% if not APP_LOGO and not APP_TITLE %}
                     {% include "paperless-ngx/snippets/svg_logo.html" with extra_attrs="width='300' class='logo mb-4'" %}
index ce67362d17c095956ee5533f707ce8067e67702d..70c71ced2475d04f659adfe7d4dbf2ee46065bf0 100644 (file)
     <div class="d-grid mt-3">
         <button class="btn btn-lg btn-primary" type="submit">{% translate "Continue" %}</button>
     </div>
+
+    {% if REDIRECT_LOGIN_TO_SSO %}
+        <script type="text/javascript">
+            const form = document.getElementById('form-account');
+            if (form) {
+                form.submit();
+            }
+        </script>
+    {% endif %}
 {% endblock form_content %}
index e2aab9dbb08801b35862bf9905db4dd14c40e62c..fe7caebb83bb36f082d49d125915eb9c0e98967a 100644 (file)
@@ -369,7 +369,10 @@ def _parse_base_paths() -> tuple[str, str, str, str, str]:
     base_url = (script_name or "") + "/"
     login_url = base_url + "accounts/login/"
     login_redirect_url = base_url + "dashboard"
-    logout_redirect_url = os.getenv("PAPERLESS_LOGOUT_REDIRECT_URL", base_url)
+    logout_redirect_url = os.getenv(
+        "PAPERLESS_LOGOUT_REDIRECT_URL",
+        login_url + "?loggedout=1",
+    )
     return script_name, base_url, login_url, login_redirect_url, logout_redirect_url
 
 
@@ -460,6 +463,7 @@ SOCIALACCOUNT_PROVIDERS = json.loads(
 ACCOUNT_EMAIL_SUBJECT_PREFIX = "[Paperless-ngx] "
 
 DISABLE_REGULAR_LOGIN = __get_boolean("PAPERLESS_DISABLE_REGULAR_LOGIN")
+REDIRECT_LOGIN_TO_SSO = __get_boolean("PAPERLESS_REDIRECT_LOGIN_TO_SSO")
 
 AUTO_LOGIN_USERNAME = os.getenv("PAPERLESS_AUTO_LOGIN_USERNAME")
 
index 511148523375432cae0324b0177b7e9b731931a8..5c257a08c57e99cf5d06aeaaede49ab8e4d7e9c6 100644 (file)
@@ -410,7 +410,10 @@ class TestPathSettings(TestCase):
         self.assertEqual("/", base_paths[1])  # BASE_URL
         self.assertEqual("/accounts/login/", base_paths[2])  # LOGIN_URL
         self.assertEqual("/dashboard", base_paths[3])  # LOGIN_REDIRECT_URL
-        self.assertEqual("/", base_paths[4])  # LOGOUT_REDIRECT_URL
+        self.assertEqual(
+            "/accounts/login/?loggedout=1",
+            base_paths[4],
+        )  # LOGOUT_REDIRECT_URL
 
     @mock.patch("os.environ", {"PAPERLESS_FORCE_SCRIPT_NAME": "/paperless"})
     def test_subpath(self):
@@ -427,7 +430,10 @@ class TestPathSettings(TestCase):
         self.assertEqual("/paperless/", base_paths[1])  # BASE_URL
         self.assertEqual("/paperless/accounts/login/", base_paths[2])  # LOGIN_URL
         self.assertEqual("/paperless/dashboard", base_paths[3])  # LOGIN_REDIRECT_URL
-        self.assertEqual("/paperless/", base_paths[4])  # LOGOUT_REDIRECT_URL
+        self.assertEqual(
+            "/paperless/accounts/login/?loggedout=1",
+            base_paths[4],
+        )  # LOGOUT_REDIRECT_URL
 
     @mock.patch(
         "os.environ",