Fixed auth flow for KEYWARDEN_AUTH_MODE, native; oidc; hybrid work as intended. no login page for OIDC mode, assumes internal IdP for now. will fix when social login implemented
This commit is contained in:
1 parent
68bbb53976
commit
ea7470231f
5 files changed
+70
-27
No files matched your search
+6
-4
@@ -19,9 +19,9 @@ KEYWARDEN_ADMIN_EMAIL=admin@example.com
|
|||||||
KEYWARDEN_ADMIN_PASSWORD=password
|
KEYWARDEN_ADMIN_PASSWORD=password
|
||||||
|
|
||||||
# Auth mode: native | oidc | hybrid
|
# Auth mode: native | oidc | hybrid
|
||||||
# native: Uses JWT authentication based on Username / Password
|
# native: Uses Keywarden username/password login only. OIDC/social options are hidden and disabled.
|
||||||
# oidc: Disables in-build auth, exclusively uses OIDC configuration
|
# oidc: Disables built-in login and uses OIDC only. Users can be auto-onboarded from IdP claims.
|
||||||
# hybrid: Allows native auth, prefers oidc
|
# hybrid: Supports OIDC + Keywarden native login; login screen prefers OIDC/social options first.
|
||||||
|
|
||||||
KEYWARDEN_AUTH_MODE=native
|
KEYWARDEN_AUTH_MODE=native
|
||||||
|
|
||||||
@@ -41,14 +41,16 @@ KEYWARDEN_AUTH_MODE=native
|
|||||||
# KEYWARDEN_OIDC_EMAIL_CLAIM=email
|
# KEYWARDEN_OIDC_EMAIL_CLAIM=email
|
||||||
# KEYWARDEN_OIDC_EMAIL_VERIFIED_CLAIM=email_verified
|
# KEYWARDEN_OIDC_EMAIL_VERIFIED_CLAIM=email_verified
|
||||||
# KEYWARDEN_OIDC_USERNAME_CLAIM=preferred_username
|
# KEYWARDEN_OIDC_USERNAME_CLAIM=preferred_username
|
||||||
|
# KEYWARDEN_OIDC_ALLOW_AUTO_ONBOARDING=true
|
||||||
# KEYWARDEN_OIDC_GROUPS_CLAIM=groups
|
# KEYWARDEN_OIDC_GROUPS_CLAIM=groups
|
||||||
# KEYWARDEN_OIDC_SYNC_ADMIN_FROM_GROUPS=false
|
# KEYWARDEN_OIDC_SYNC_ADMIN_FROM_GROUPS=true # defaults to true when KEYWARDEN_AUTH_MODE=oidc
|
||||||
# KEYWARDEN_OIDC_ADMIN_GROUPS=authentik Admins
|
# KEYWARDEN_OIDC_ADMIN_GROUPS=authentik Admins
|
||||||
# KEYWARDEN_OIDC_ADMIN_DEMOTE_ON_MISS=false
|
# KEYWARDEN_OIDC_ADMIN_DEMOTE_ON_MISS=false
|
||||||
|
|
||||||
# Social login (optional)
|
# Social login (optional)
|
||||||
# KEYWARDEN_SITE_ID=1
|
# KEYWARDEN_SITE_ID=1
|
||||||
# KEYWARDEN_SOCIAL_REQUIRE_VERIFIED_EMAIL=true
|
# KEYWARDEN_SOCIAL_REQUIRE_VERIFIED_EMAIL=true
|
||||||
|
# KEYWARDEN_SOCIAL_ALLOW_AUTO_ONBOARDING=false
|
||||||
# KEYWARDEN_SOCIAL_GOOGLE_ENABLED=false
|
# KEYWARDEN_SOCIAL_GOOGLE_ENABLED=false
|
||||||
# KEYWARDEN_SOCIAL_GOOGLE_CLIENT_ID=
|
# KEYWARDEN_SOCIAL_GOOGLE_CLIENT_ID=
|
||||||
# KEYWARDEN_SOCIAL_GOOGLE_CLIENT_SECRET=
|
# KEYWARDEN_SOCIAL_GOOGLE_CLIENT_SECRET=
|
||||||
|
|||||||
@@ -61,6 +61,13 @@ class KeywardenSocialAccountAdapter(DefaultSocialAccountAdapter):
|
|||||||
if user:
|
if user:
|
||||||
sociallogin.connect(request, user)
|
sociallogin.connect(request, user)
|
||||||
self._sync_identity(user, sociallogin)
|
self._sync_identity(user, sociallogin)
|
||||||
|
return
|
||||||
|
|
||||||
|
if not getattr(settings, "KEYWARDEN_SOCIAL_ALLOW_AUTO_ONBOARDING", False):
|
||||||
|
self._reject(
|
||||||
|
request,
|
||||||
|
"Social auto-onboarding is disabled. Ask an administrator to create/link your account.",
|
||||||
|
)
|
||||||
|
|
||||||
def populate_user(self, request, sociallogin, data):
|
def populate_user(self, request, sociallogin, data):
|
||||||
user = super().populate_user(request, sociallogin, data)
|
user = super().populate_user(request, sociallogin, data)
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ def profile(request):
|
|||||||
context = {
|
context = {
|
||||||
"user": request.user,
|
"user": request.user,
|
||||||
"auth_mode": getattr(settings, "KEYWARDEN_AUTH_MODE", "hybrid"),
|
"auth_mode": getattr(settings, "KEYWARDEN_AUTH_MODE", "hybrid"),
|
||||||
"oidc_enabled": bool(getattr(settings, "KEYWARDEN_OIDC_ENABLED", False)),
|
"oidc_enabled": bool(getattr(settings, "KEYWARDEN_OIDC_LOGIN_ENABLED", False)),
|
||||||
"oidc_identity": oidc_identity,
|
"oidc_identity": oidc_identity,
|
||||||
"oidc_provider_id": getattr(settings, "KEYWARDEN_OIDC_PROVIDER_ID", "oidc"),
|
"oidc_provider_id": getattr(settings, "KEYWARDEN_OIDC_PROVIDER_ID", "oidc"),
|
||||||
"oidc_issuer": getattr(settings, "KEYWARDEN_OIDC_ISSUER", ""),
|
"oidc_issuer": getattr(settings, "KEYWARDEN_OIDC_ISSUER", ""),
|
||||||
@@ -149,25 +149,32 @@ def profile(request):
|
|||||||
|
|
||||||
def login_view(request):
|
def login_view(request):
|
||||||
auth_mode = getattr(settings, "KEYWARDEN_AUTH_MODE", "hybrid")
|
auth_mode = getattr(settings, "KEYWARDEN_AUTH_MODE", "hybrid")
|
||||||
if auth_mode == "oidc":
|
oidc_login_enabled = bool(getattr(settings, "KEYWARDEN_OIDC_LOGIN_ENABLED", False))
|
||||||
|
social_providers = (
|
||||||
|
getattr(settings, "KEYWARDEN_SOCIAL_LOGIN_PROVIDERS", [])
|
||||||
|
if auth_mode == "hybrid"
|
||||||
|
else []
|
||||||
|
)
|
||||||
|
|
||||||
|
if auth_mode == "oidc" and oidc_login_enabled:
|
||||||
return redirect("/oidc/authenticate/")
|
return redirect("/oidc/authenticate/")
|
||||||
|
|
||||||
has_sso_options = bool(
|
has_sso_options = bool(
|
||||||
getattr(settings, "KEYWARDEN_OIDC_ENABLED", False)
|
oidc_login_enabled
|
||||||
or getattr(settings, "KEYWARDEN_SOCIAL_LOGIN_PROVIDERS", [])
|
or social_providers
|
||||||
)
|
)
|
||||||
show_native_login = (
|
show_native_login = (
|
||||||
request.method == "POST"
|
request.method == "POST"
|
||||||
or request.GET.get("native") == "1"
|
or request.GET.get("native") == "1"
|
||||||
or (auth_mode == "native" and not has_sso_options)
|
or auth_mode == "native"
|
||||||
)
|
)
|
||||||
|
|
||||||
# native or hybrid -> render Django's built-in login view
|
# native or hybrid -> render Django's built-in login view
|
||||||
return auth_views.LoginView.as_view(
|
return auth_views.LoginView.as_view(
|
||||||
template_name="accounts/login.html",
|
template_name="accounts/login.html",
|
||||||
extra_context={
|
extra_context={
|
||||||
"social_providers": getattr(settings, "KEYWARDEN_SOCIAL_LOGIN_PROVIDERS", []),
|
"social_providers": social_providers,
|
||||||
"oidc_enabled": bool(getattr(settings, "KEYWARDEN_OIDC_ENABLED", False)),
|
"oidc_enabled": oidc_login_enabled,
|
||||||
"oidc_login_url": "/oidc/authenticate/",
|
"oidc_login_url": "/oidc/authenticate/",
|
||||||
"oidc_provider_label": _oidc_provider_label(),
|
"oidc_provider_label": _oidc_provider_label(),
|
||||||
"show_native_login": show_native_login,
|
"show_native_login": show_native_login,
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ def env_csv(name: str, default: str = "") -> list[str]:
|
|||||||
return [item.strip() for item in raw.split(",") if item.strip()]
|
return [item.strip() for item in raw.split(",") if item.strip()]
|
||||||
|
|
||||||
|
|
||||||
|
# Auth mode: native | oidc | hybrid
|
||||||
|
KEYWARDEN_AUTH_MODE_REQUESTED = os.getenv("KEYWARDEN_AUTH_MODE", "hybrid").lower()
|
||||||
|
if KEYWARDEN_AUTH_MODE_REQUESTED not in {"native", "oidc", "hybrid"}:
|
||||||
|
KEYWARDEN_AUTH_MODE_REQUESTED = "hybrid"
|
||||||
|
|
||||||
|
|
||||||
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
||||||
|
|
||||||
SECRET_KEY = os.getenv("KEYWARDEN_SECRET_KEY")
|
SECRET_KEY = os.getenv("KEYWARDEN_SECRET_KEY")
|
||||||
@@ -70,12 +76,15 @@ KEYWARDEN_SOCIAL_APPLE_CONFIGURED = bool(
|
|||||||
and KEYWARDEN_SOCIAL_APPLE_CLIENT_SECRET
|
and KEYWARDEN_SOCIAL_APPLE_CLIENT_SECRET
|
||||||
)
|
)
|
||||||
|
|
||||||
KEYWARDEN_SOCIAL_AUTH_ENABLED = any(
|
KEYWARDEN_SOCIAL_AUTH_ENABLED = (
|
||||||
|
KEYWARDEN_AUTH_MODE_REQUESTED == "hybrid"
|
||||||
|
and any(
|
||||||
(
|
(
|
||||||
KEYWARDEN_SOCIAL_GOOGLE_CONFIGURED,
|
KEYWARDEN_SOCIAL_GOOGLE_CONFIGURED,
|
||||||
KEYWARDEN_SOCIAL_GITHUB_CONFIGURED,
|
KEYWARDEN_SOCIAL_GITHUB_CONFIGURED,
|
||||||
KEYWARDEN_SOCIAL_APPLE_CONFIGURED,
|
KEYWARDEN_SOCIAL_APPLE_CONFIGURED,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Default to secure cookies and respect TLS termination headers.
|
# Default to secure cookies and respect TLS termination headers.
|
||||||
@@ -331,7 +340,8 @@ OIDC_OP_JWKS_ENDPOINT = os.getenv("KEYWARDEN_OIDC_JWKS_ENDPOINT")
|
|||||||
OIDC_RP_SIGN_ALGO = os.getenv("KEYWARDEN_OIDC_SIGN_ALGO", "RS256")
|
OIDC_RP_SIGN_ALGO = os.getenv("KEYWARDEN_OIDC_SIGN_ALGO", "RS256")
|
||||||
OIDC_RP_SCOPES = os.getenv("KEYWARDEN_OIDC_SCOPES", "openid email profile")
|
OIDC_RP_SCOPES = os.getenv("KEYWARDEN_OIDC_SCOPES", "openid email profile")
|
||||||
OIDC_STORE_ACCESS_TOKEN = env_bool("KEYWARDEN_OIDC_STORE_ACCESS_TOKEN", default=False)
|
OIDC_STORE_ACCESS_TOKEN = env_bool("KEYWARDEN_OIDC_STORE_ACCESS_TOKEN", default=False)
|
||||||
OIDC_CREATE_USER = True
|
KEYWARDEN_OIDC_ALLOW_AUTO_ONBOARDING = env_bool("KEYWARDEN_OIDC_ALLOW_AUTO_ONBOARDING", default=True)
|
||||||
|
OIDC_CREATE_USER = KEYWARDEN_OIDC_ALLOW_AUTO_ONBOARDING
|
||||||
|
|
||||||
KEYWARDEN_OIDC_PROVIDER_ID = os.getenv("KEYWARDEN_OIDC_PROVIDER_ID", "oidc")
|
KEYWARDEN_OIDC_PROVIDER_ID = os.getenv("KEYWARDEN_OIDC_PROVIDER_ID", "oidc")
|
||||||
KEYWARDEN_OIDC_ISSUER = os.getenv("KEYWARDEN_OIDC_ISSUER", "").strip()
|
KEYWARDEN_OIDC_ISSUER = os.getenv("KEYWARDEN_OIDC_ISSUER", "").strip()
|
||||||
@@ -340,7 +350,10 @@ KEYWARDEN_OIDC_EMAIL_VERIFIED_CLAIM = os.getenv("KEYWARDEN_OIDC_EMAIL_VERIFIED_C
|
|||||||
KEYWARDEN_OIDC_REQUIRE_VERIFIED_EMAIL = env_bool("KEYWARDEN_OIDC_REQUIRE_VERIFIED_EMAIL", default=True)
|
KEYWARDEN_OIDC_REQUIRE_VERIFIED_EMAIL = env_bool("KEYWARDEN_OIDC_REQUIRE_VERIFIED_EMAIL", default=True)
|
||||||
KEYWARDEN_OIDC_USERNAME_CLAIM = os.getenv("KEYWARDEN_OIDC_USERNAME_CLAIM", "preferred_username")
|
KEYWARDEN_OIDC_USERNAME_CLAIM = os.getenv("KEYWARDEN_OIDC_USERNAME_CLAIM", "preferred_username")
|
||||||
KEYWARDEN_OIDC_GROUPS_CLAIM = os.getenv("KEYWARDEN_OIDC_GROUPS_CLAIM", "groups")
|
KEYWARDEN_OIDC_GROUPS_CLAIM = os.getenv("KEYWARDEN_OIDC_GROUPS_CLAIM", "groups")
|
||||||
KEYWARDEN_OIDC_SYNC_ADMIN_FROM_GROUPS = env_bool("KEYWARDEN_OIDC_SYNC_ADMIN_FROM_GROUPS", default=False)
|
KEYWARDEN_OIDC_SYNC_ADMIN_FROM_GROUPS = env_bool(
|
||||||
|
"KEYWARDEN_OIDC_SYNC_ADMIN_FROM_GROUPS",
|
||||||
|
default=(KEYWARDEN_AUTH_MODE_REQUESTED == "oidc"),
|
||||||
|
)
|
||||||
KEYWARDEN_OIDC_ADMIN_DEMOTE_ON_MISS = env_bool("KEYWARDEN_OIDC_ADMIN_DEMOTE_ON_MISS", default=False)
|
KEYWARDEN_OIDC_ADMIN_DEMOTE_ON_MISS = env_bool("KEYWARDEN_OIDC_ADMIN_DEMOTE_ON_MISS", default=False)
|
||||||
KEYWARDEN_OIDC_ADMIN_GROUPS = env_csv("KEYWARDEN_OIDC_ADMIN_GROUPS")
|
KEYWARDEN_OIDC_ADMIN_GROUPS = env_csv("KEYWARDEN_OIDC_ADMIN_GROUPS")
|
||||||
|
|
||||||
@@ -358,16 +371,18 @@ KEYWARDEN_OIDC_ENABLED = bool(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
KEYWARDEN_OIDC_LOGIN_ENABLED = KEYWARDEN_OIDC_ENABLED and KEYWARDEN_AUTH_MODE_REQUESTED in {"oidc", "hybrid"}
|
||||||
|
|
||||||
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS = []
|
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS = []
|
||||||
if KEYWARDEN_SOCIAL_GOOGLE_CONFIGURED:
|
if KEYWARDEN_SOCIAL_AUTH_ENABLED and KEYWARDEN_SOCIAL_GOOGLE_CONFIGURED:
|
||||||
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS.append(
|
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS.append(
|
||||||
{"id": "google", "name": "Google", "login_url": "/accounts/sso/google/login/"}
|
{"id": "google", "name": "Google", "login_url": "/accounts/sso/google/login/"}
|
||||||
)
|
)
|
||||||
if KEYWARDEN_SOCIAL_GITHUB_CONFIGURED:
|
if KEYWARDEN_SOCIAL_AUTH_ENABLED and KEYWARDEN_SOCIAL_GITHUB_CONFIGURED:
|
||||||
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS.append(
|
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS.append(
|
||||||
{"id": "github", "name": "GitHub", "login_url": "/accounts/sso/github/login/"}
|
{"id": "github", "name": "GitHub", "login_url": "/accounts/sso/github/login/"}
|
||||||
)
|
)
|
||||||
if KEYWARDEN_SOCIAL_APPLE_CONFIGURED:
|
if KEYWARDEN_SOCIAL_AUTH_ENABLED and KEYWARDEN_SOCIAL_APPLE_CONFIGURED:
|
||||||
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS.append(
|
KEYWARDEN_SOCIAL_LOGIN_PROVIDERS.append(
|
||||||
{"id": "apple", "name": "Apple", "login_url": "/accounts/sso/apple/login/"}
|
{"id": "apple", "name": "Apple", "login_url": "/accounts/sso/apple/login/"}
|
||||||
)
|
)
|
||||||
@@ -378,7 +393,8 @@ if KEYWARDEN_SOCIAL_AUTH_ENABLED:
|
|||||||
ACCOUNT_UNIQUE_EMAIL = True
|
ACCOUNT_UNIQUE_EMAIL = True
|
||||||
ACCOUNT_USERNAME_REQUIRED = False
|
ACCOUNT_USERNAME_REQUIRED = False
|
||||||
ACCOUNT_AUTHENTICATION_METHOD = "email"
|
ACCOUNT_AUTHENTICATION_METHOD = "email"
|
||||||
SOCIALACCOUNT_AUTO_SIGNUP = True
|
KEYWARDEN_SOCIAL_ALLOW_AUTO_ONBOARDING = env_bool("KEYWARDEN_SOCIAL_ALLOW_AUTO_ONBOARDING", default=False)
|
||||||
|
SOCIALACCOUNT_AUTO_SIGNUP = KEYWARDEN_SOCIAL_ALLOW_AUTO_ONBOARDING
|
||||||
SOCIALACCOUNT_EMAIL_AUTHENTICATION = False
|
SOCIALACCOUNT_EMAIL_AUTHENTICATION = False
|
||||||
SOCIALACCOUNT_ADAPTER = "apps.accounts.social_auth.KeywardenSocialAccountAdapter"
|
SOCIALACCOUNT_ADAPTER = "apps.accounts.social_auth.KeywardenSocialAccountAdapter"
|
||||||
SOCIALACCOUNT_LOGIN_ON_GET = True
|
SOCIALACCOUNT_LOGIN_ON_GET = True
|
||||||
@@ -426,28 +442,37 @@ KEYWARDEN_SOCIAL_REQUIRE_VERIFIED_EMAIL = env_bool(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Auth mode: native | oidc | hybrid
|
# Auth mode: native | oidc | hybrid
|
||||||
AUTH_MODE = os.getenv("KEYWARDEN_AUTH_MODE", "hybrid").lower()
|
AUTH_MODE = KEYWARDEN_AUTH_MODE_REQUESTED
|
||||||
if AUTH_MODE not in {"native", "oidc", "hybrid"}:
|
|
||||||
AUTH_MODE = "hybrid"
|
|
||||||
if AUTH_MODE == "oidc" and not KEYWARDEN_OIDC_ENABLED:
|
if AUTH_MODE == "oidc" and not KEYWARDEN_OIDC_ENABLED:
|
||||||
AUTH_MODE = "native"
|
AUTH_MODE = "native"
|
||||||
KEYWARDEN_AUTH_MODE = AUTH_MODE
|
KEYWARDEN_AUTH_MODE = AUTH_MODE
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = [
|
if AUTH_MODE == "oidc":
|
||||||
|
AUTHENTICATION_BACKENDS = [
|
||||||
|
"apps.accounts.oidc.KeywardenOIDCAuthenticationBackend",
|
||||||
|
"guardian.backends.ObjectPermissionBackend",
|
||||||
|
]
|
||||||
|
elif AUTH_MODE == "hybrid":
|
||||||
|
AUTHENTICATION_BACKENDS = [
|
||||||
"django.contrib.auth.backends.ModelBackend",
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
"guardian.backends.ObjectPermissionBackend",
|
"guardian.backends.ObjectPermissionBackend",
|
||||||
]
|
]
|
||||||
if KEYWARDEN_SOCIAL_AUTH_ENABLED:
|
if KEYWARDEN_SOCIAL_AUTH_ENABLED:
|
||||||
AUTHENTICATION_BACKENDS.append("allauth.account.auth_backends.AuthenticationBackend")
|
AUTHENTICATION_BACKENDS.append("allauth.account.auth_backends.AuthenticationBackend")
|
||||||
if KEYWARDEN_OIDC_ENABLED:
|
if KEYWARDEN_OIDC_ENABLED:
|
||||||
AUTHENTICATION_BACKENDS.append("apps.accounts.oidc.KeywardenOIDCAuthenticationBackend")
|
AUTHENTICATION_BACKENDS.append("apps.accounts.oidc.KeywardenOIDCAuthenticationBackend")
|
||||||
|
else:
|
||||||
|
AUTHENTICATION_BACKENDS = [
|
||||||
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
|
"guardian.backends.ObjectPermissionBackend",
|
||||||
|
]
|
||||||
|
|
||||||
if AUTH_MODE == "oidc":
|
if AUTH_MODE == "oidc":
|
||||||
# OIDC-only: enforce identity provider logins.
|
# OIDC-only: enforce identity provider logins.
|
||||||
LOGIN_URL = "/oidc/authenticate/"
|
LOGIN_URL = "/oidc/authenticate/"
|
||||||
else:
|
else:
|
||||||
LOGIN_URL = "/accounts/login/"
|
LOGIN_URL = "/accounts/login/"
|
||||||
LOGOUT_URL = "/oidc/logout/" if KEYWARDEN_OIDC_ENABLED else "/accounts/logout/"
|
LOGOUT_URL = "/oidc/logout/" if AUTH_MODE in {"oidc", "hybrid"} and KEYWARDEN_OIDC_ENABLED else "/accounts/logout/"
|
||||||
LOGIN_REDIRECT_URL = "/servers/"
|
LOGIN_REDIRECT_URL = "/servers/"
|
||||||
LOGOUT_REDIRECT_URL = "/"
|
LOGOUT_REDIRECT_URL = "/"
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ from keywarden.api import api as ninja_api, api_v1 as ninja_api_v1
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("oidc/", include("mozilla_django_oidc.urls")),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if getattr(settings, "KEYWARDEN_OIDC_LOGIN_ENABLED", False):
|
||||||
|
urlpatterns.append(path("oidc/", include("mozilla_django_oidc.urls")))
|
||||||
|
|
||||||
if getattr(settings, "KEYWARDEN_SOCIAL_AUTH_ENABLED", False):
|
if getattr(settings, "KEYWARDEN_SOCIAL_AUTH_ENABLED", False):
|
||||||
urlpatterns.append(path("accounts/sso/", include("allauth.urls")))
|
urlpatterns.append(path("accounts/sso/", include("allauth.urls")))
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user