chore: formatting changes

This commit is contained in:
sriram veeraghanta 2024-11-21 17:42:44 +05:30
parent a446bc043e
commit 0dbd4cfe97
267 changed files with 2478 additions and 7981 deletions

View file

@ -11,11 +11,7 @@ from django.core.exceptions import ValidationError
from zxcvbn import zxcvbn
# Module imports
from plane.db.models import (
Profile,
User,
WorkspaceMemberInvite,
)
from plane.db.models import Profile, User, WorkspaceMemberInvite
from plane.license.utils.instance_value import get_configuration_value
from .error import AuthenticationException, AUTHENTICATION_ERROR_CODES
from plane.bgtasks.user_activation_email_task import user_activation_email
@ -90,20 +86,13 @@ class Adapter:
# Get configuration value
(ENABLE_SIGNUP,) = get_configuration_value(
[
{
"key": "ENABLE_SIGNUP",
"default": os.environ.get("ENABLE_SIGNUP", "1"),
},
]
[{"key": "ENABLE_SIGNUP", "default": os.environ.get("ENABLE_SIGNUP", "1")}]
)
# Check if sign up is disabled and invite is present or not
if (
ENABLE_SIGNUP == "0"
and not WorkspaceMemberInvite.objects.filter(
email=email,
).exists()
and not WorkspaceMemberInvite.objects.filter(email=email).exists()
):
# Raise exception
raise AuthenticationException(
@ -124,9 +113,7 @@ class Adapter:
user.token_updated_at = timezone.now()
# If user is not active, send the activation email and set the user as active
if not user.is_active:
user_activation_email.delay(
base_host(request=self.request), user.id
)
user_activation_email.delay(base_host(request=self.request), user.id)
# Set user as active
user.is_active = True
user.save()
@ -182,11 +169,7 @@ class Adapter:
# Call callback if present
if self.callback:
self.callback(
user,
is_signup,
self.request,
)
self.callback(user, is_signup, self.request)
# Create or update account if token data is present
if self.token_data:

View file

@ -67,7 +67,6 @@ AUTHENTICATION_ERROR_CODES = {
class AuthenticationException(Exception):
error_code = None
error_message = None
payload = {}
@ -78,10 +77,7 @@ class AuthenticationException(Exception):
self.payload = payload
def get_error_dict(self):
error = {
"error_code": self.error_code,
"error_message": self.error_message,
}
error = {"error_code": self.error_code, "error_message": self.error_message}
for key in self.payload:
error[key] = self.payload[key]

View file

@ -4,7 +4,10 @@ from rest_framework.exceptions import NotAuthenticated
from rest_framework.exceptions import Throttled
# Module imports
from plane.authentication.adapter.error import AuthenticationException, AUTHENTICATION_ERROR_CODES
from plane.authentication.adapter.error import (
AuthenticationException,
AUTHENTICATION_ERROR_CODES,
)
def auth_exception_handler(exc, context):
@ -22,6 +25,6 @@ def auth_exception_handler(exc, context):
)
response.data = exc.get_error_dict()
response.status_code = 429
# Return the response that is generated by the default exception handler.
return response

View file

@ -68,31 +68,25 @@ class OauthAdapter(Adapter):
def get_user_token(self, data, headers=None):
try:
headers = headers or {}
response = requests.post(
self.get_token_url(), data=data, headers=headers
)
response = requests.post(self.get_token_url(), data=data, headers=headers)
response.raise_for_status()
return response.json()
except requests.RequestException:
code = self.authentication_error_code()
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[code],
error_message=str(code),
error_code=AUTHENTICATION_ERROR_CODES[code], error_message=str(code)
)
def get_user_response(self):
try:
headers = {
"Authorization": f"Bearer {self.token_data.get('access_token')}"
}
headers = {"Authorization": f"Bearer {self.token_data.get('access_token')}"}
response = requests.get(self.get_user_info_url(), headers=headers)
response.raise_for_status()
return response.json()
except requests.RequestException:
code = self.authentication_error_code()
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[code],
error_message=str(code),
error_code=AUTHENTICATION_ERROR_CODES[code], error_message=str(code)
)
def set_user_data(self, data):
@ -104,16 +98,12 @@ class OauthAdapter(Adapter):
account = Account.objects.filter(
user=user,
provider=self.provider,
provider_account_id=self.user_data.get("user").get(
"provider_id"
),
provider_account_id=self.user_data.get("user").get("provider_id"),
).first()
# Update the account if it exists
if account:
account.access_token = self.token_data.get("access_token")
account.refresh_token = self.token_data.get(
"refresh_token", None
)
account.refresh_token = self.token_data.get("refresh_token", None)
account.access_token_expired_at = self.token_data.get(
"access_token_expired_at"
)

View file

@ -17,9 +17,7 @@ class SessionMiddleware(MiddlewareMixin):
def process_request(self, request):
if "instances" in request.path:
session_key = request.COOKIES.get(
settings.ADMIN_SESSION_COOKIE_NAME
)
session_key = request.COOKIES.get(settings.ADMIN_SESSION_COOKIE_NAME)
else:
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
request.session = self.SessionStore(session_key)

View file

@ -12,20 +12,10 @@ from plane.license.utils.instance_value import get_configuration_value
class EmailProvider(CredentialAdapter):
provider = "email"
def __init__(
self,
request,
key=None,
code=None,
is_signup=False,
callback=None,
):
super().__init__(
request=request, provider=self.provider, callback=callback
)
def __init__(self, request, key=None, code=None, is_signup=False, callback=None):
super().__init__(request=request, provider=self.provider, callback=callback)
self.key = key
self.code = code
self.is_signup = is_signup
@ -35,7 +25,7 @@ class EmailProvider(CredentialAdapter):
{
"key": "ENABLE_EMAIL_PASSWORD",
"default": os.environ.get("ENABLE_EMAIL_PASSWORD"),
},
}
]
)
@ -53,9 +43,7 @@ class EmailProvider(CredentialAdapter):
if User.objects.filter(email=self.key).exists():
raise AuthenticationException(
error_message="USER_ALREADY_EXIST",
error_code=AUTHENTICATION_ERROR_CODES[
"USER_ALREADY_EXIST"
],
error_code=AUTHENTICATION_ERROR_CODES["USER_ALREADY_EXIST"],
)
super().set_user_data(
@ -72,20 +60,14 @@ class EmailProvider(CredentialAdapter):
)
return
else:
user = User.objects.filter(
email=self.key,
).first()
user = User.objects.filter(email=self.key).first()
# User does not exists
if not user:
raise AuthenticationException(
error_message="USER_DOES_NOT_EXIST",
error_code=AUTHENTICATION_ERROR_CODES[
"USER_DOES_NOT_EXIST"
],
payload={
"email": self.key,
},
error_code=AUTHENTICATION_ERROR_CODES["USER_DOES_NOT_EXIST"],
payload={"email": self.key},
)
# Check user password

View file

@ -17,26 +17,12 @@ from plane.db.models import User
class MagicCodeProvider(CredentialAdapter):
provider = "magic-code"
def __init__(
self,
request,
key,
code=None,
callback=None,
):
(
EMAIL_HOST,
ENABLE_MAGIC_LINK_LOGIN,
) = get_configuration_value(
def __init__(self, request, key, code=None, callback=None):
(EMAIL_HOST, ENABLE_MAGIC_LINK_LOGIN) = get_configuration_value(
[
{
"key": "EMAIL_HOST",
"default": os.environ.get("EMAIL_HOST"),
},
{"key": "EMAIL_HOST", "default": os.environ.get("EMAIL_HOST")},
{
"key": "ENABLE_MAGIC_LINK_LOGIN",
"default": os.environ.get("ENABLE_MAGIC_LINK_LOGIN", "1"),
@ -53,16 +39,12 @@ class MagicCodeProvider(CredentialAdapter):
if ENABLE_MAGIC_LINK_LOGIN == "0":
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"MAGIC_LINK_LOGIN_DISABLED"
],
error_code=AUTHENTICATION_ERROR_CODES["MAGIC_LINK_LOGIN_DISABLED"],
error_message="MAGIC_LINK_LOGIN_DISABLED",
payload={"email": str(key)},
)
super().__init__(
request=request, provider=self.provider, callback=callback
)
super().__init__(request=request, provider=self.provider, callback=callback)
self.key = key
self.code = code
@ -164,17 +146,13 @@ class MagicCodeProvider(CredentialAdapter):
email = str(self.key).replace("magic_", "", 1)
if User.objects.filter(email=email).exists():
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"EXPIRED_MAGIC_CODE_SIGN_IN"
],
error_code=AUTHENTICATION_ERROR_CODES["EXPIRED_MAGIC_CODE_SIGN_IN"],
error_message="EXPIRED_MAGIC_CODE_SIGN_IN",
payload={"email": str(email)},
)
else:
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"EXPIRED_MAGIC_CODE_SIGN_UP"
],
error_code=AUTHENTICATION_ERROR_CODES["EXPIRED_MAGIC_CODE_SIGN_UP"],
error_message="EXPIRED_MAGIC_CODE_SIGN_UP",
payload={"email": str(email)},
)

View file

@ -16,14 +16,12 @@ from plane.authentication.adapter.error import (
class GitHubOAuthProvider(OauthAdapter):
token_url = "https://github.com/login/oauth/access_token"
userinfo_url = "https://api.github.com/user"
provider = "github"
scope = "read:user user:email"
def __init__(self, request, code=None, state=None, callback=None):
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET = get_configuration_value(
[
{
@ -53,9 +51,7 @@ class GitHubOAuthProvider(OauthAdapter):
"scope": self.scope,
"state": state,
}
auth_url = (
f"https://github.com/login/oauth/authorize?{urlencode(url_params)}"
)
auth_url = f"https://github.com/login/oauth/authorize?{urlencode(url_params)}"
super().__init__(
request,
self.provider,
@ -86,16 +82,14 @@ class GitHubOAuthProvider(OauthAdapter):
"refresh_token": token_response.get("refresh_token", None),
"access_token_expired_at": (
datetime.fromtimestamp(
token_response.get("expires_in"),
tz=pytz.utc,
token_response.get("expires_in"), tz=pytz.utc
)
if token_response.get("expires_in")
else None
),
"refresh_token_expired_at": (
datetime.fromtimestamp(
token_response.get("refresh_token_expired_at"),
tz=pytz.utc,
token_response.get("refresh_token_expired_at"), tz=pytz.utc
)
if token_response.get("refresh_token_expired_at")
else None
@ -110,19 +104,12 @@ class GitHubOAuthProvider(OauthAdapter):
emails_url = "https://api.github.com/user/emails"
emails_response = requests.get(emails_url, headers=headers).json()
email = next(
(
email["email"]
for email in emails_response
if email["primary"]
),
None,
(email["email"] for email in emails_response if email["primary"]), None
)
return email
except requests.RequestException:
raise AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITHUB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITHUB_OAUTH_PROVIDER_ERROR"],
error_message="GITHUB_OAUTH_PROVIDER_ERROR",
)

View file

@ -15,31 +15,25 @@ from plane.authentication.adapter.error import (
class GitLabOAuthProvider(OauthAdapter):
provider = "gitlab"
scope = "read_user"
def __init__(self, request, code=None, state=None, callback=None):
GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET, GITLAB_HOST = (
get_configuration_value(
[
{
"key": "GITLAB_CLIENT_ID",
"default": os.environ.get("GITLAB_CLIENT_ID"),
},
{
"key": "GITLAB_CLIENT_SECRET",
"default": os.environ.get("GITLAB_CLIENT_SECRET"),
},
{
"key": "GITLAB_HOST",
"default": os.environ.get(
"GITLAB_HOST", "https://gitlab.com"
),
},
]
)
GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET, GITLAB_HOST = get_configuration_value(
[
{
"key": "GITLAB_CLIENT_ID",
"default": os.environ.get("GITLAB_CLIENT_ID"),
},
{
"key": "GITLAB_CLIENT_SECRET",
"default": os.environ.get("GITLAB_CLIENT_SECRET"),
},
{
"key": "GITLAB_HOST",
"default": os.environ.get("GITLAB_HOST", "https://gitlab.com"),
},
]
)
self.host = GITLAB_HOST
@ -104,8 +98,7 @@ class GitLabOAuthProvider(OauthAdapter):
),
"refresh_token_expired_at": (
datetime.fromtimestamp(
token_response.get("refresh_token_expired_at"),
tz=pytz.utc,
token_response.get("refresh_token_expired_at"), tz=pytz.utc
)
if token_response.get("refresh_token_expired_at")
else None

View file

@ -53,7 +53,9 @@ class GoogleOAuthProvider(OauthAdapter):
"prompt": "consent",
"state": state,
}
auth_url = f"https://accounts.google.com/o/oauth2/v2/auth?{urlencode(url_params)}"
auth_url = (
f"https://accounts.google.com/o/oauth2/v2/auth?{urlencode(url_params)}"
)
super().__init__(
request,
@ -84,16 +86,14 @@ class GoogleOAuthProvider(OauthAdapter):
"refresh_token": token_response.get("refresh_token", None),
"access_token_expired_at": (
datetime.fromtimestamp(
token_response.get("expires_in"),
tz=pytz.utc,
token_response.get("expires_in"), tz=pytz.utc
)
if token_response.get("expires_in")
else None
),
"refresh_token_expired_at": (
datetime.fromtimestamp(
token_response.get("refresh_token_expired_at"),
tz=pytz.utc,
token_response.get("refresh_token_expired_at"), tz=pytz.utc
)
if token_response.get("refresh_token_expired_at")
else None

View file

@ -2,7 +2,6 @@ from rest_framework.authentication import SessionAuthentication
class BaseSessionAuthentication(SessionAuthentication):
# Disable csrf for the rest apis
def enforce_csrf(self, request):
return

View file

@ -40,64 +40,20 @@ from .views import (
urlpatterns = [
# credentials
path(
"sign-in/",
SignInAuthEndpoint.as_view(),
name="sign-in",
),
path(
"sign-up/",
SignUpAuthEndpoint.as_view(),
name="sign-up",
),
path(
"spaces/sign-in/",
SignInAuthSpaceEndpoint.as_view(),
name="sign-in",
),
path(
"spaces/sign-up/",
SignUpAuthSpaceEndpoint.as_view(),
name="sign-in",
),
path("sign-in/", SignInAuthEndpoint.as_view(), name="sign-in"),
path("sign-up/", SignUpAuthEndpoint.as_view(), name="sign-up"),
path("spaces/sign-in/", SignInAuthSpaceEndpoint.as_view(), name="sign-in"),
path("spaces/sign-up/", SignUpAuthSpaceEndpoint.as_view(), name="sign-in"),
# signout
path(
"sign-out/",
SignOutAuthEndpoint.as_view(),
name="sign-out",
),
path(
"spaces/sign-out/",
SignOutAuthSpaceEndpoint.as_view(),
name="sign-out",
),
path("sign-out/", SignOutAuthEndpoint.as_view(), name="sign-out"),
path("spaces/sign-out/", SignOutAuthSpaceEndpoint.as_view(), name="sign-out"),
# csrf token
path(
"get-csrf-token/",
CSRFTokenEndpoint.as_view(),
name="get_csrf_token",
),
path("get-csrf-token/", CSRFTokenEndpoint.as_view(), name="get_csrf_token"),
# Magic sign in
path(
"magic-generate/",
MagicGenerateEndpoint.as_view(),
name="magic-generate",
),
path(
"magic-sign-in/",
MagicSignInEndpoint.as_view(),
name="magic-sign-in",
),
path(
"magic-sign-up/",
MagicSignUpEndpoint.as_view(),
name="magic-sign-up",
),
path(
"get-csrf-token/",
CSRFTokenEndpoint.as_view(),
name="get_csrf_token",
),
path("magic-generate/", MagicGenerateEndpoint.as_view(), name="magic-generate"),
path("magic-sign-in/", MagicSignInEndpoint.as_view(), name="magic-sign-in"),
path("magic-sign-up/", MagicSignUpEndpoint.as_view(), name="magic-sign-up"),
path("get-csrf-token/", CSRFTokenEndpoint.as_view(), name="get_csrf_token"),
path(
"spaces/magic-generate/",
MagicGenerateSpaceEndpoint.as_view(),
@ -114,16 +70,8 @@ urlpatterns = [
name="magic-sign-up",
),
## Google Oauth
path(
"google/",
GoogleOauthInitiateEndpoint.as_view(),
name="google-initiate",
),
path(
"google/callback/",
GoogleCallbackEndpoint.as_view(),
name="google-callback",
),
path("google/", GoogleOauthInitiateEndpoint.as_view(), name="google-initiate"),
path("google/callback/", GoogleCallbackEndpoint.as_view(), name="google-callback"),
path(
"spaces/google/",
GoogleOauthInitiateSpaceEndpoint.as_view(),
@ -135,16 +83,8 @@ urlpatterns = [
name="google-callback",
),
## Github Oauth
path(
"github/",
GitHubOauthInitiateEndpoint.as_view(),
name="github-initiate",
),
path(
"github/callback/",
GitHubCallbackEndpoint.as_view(),
name="github-callback",
),
path("github/", GitHubOauthInitiateEndpoint.as_view(), name="github-initiate"),
path("github/callback/", GitHubCallbackEndpoint.as_view(), name="github-callback"),
path(
"spaces/github/",
GitHubOauthInitiateSpaceEndpoint.as_view(),
@ -156,16 +96,8 @@ urlpatterns = [
name="github-callback",
),
## Gitlab Oauth
path(
"gitlab/",
GitLabOauthInitiateEndpoint.as_view(),
name="gitlab-initiate",
),
path(
"gitlab/callback/",
GitLabCallbackEndpoint.as_view(),
name="gitlab-callback",
),
path("gitlab/", GitLabOauthInitiateEndpoint.as_view(), name="gitlab-initiate"),
path("gitlab/callback/", GitLabCallbackEndpoint.as_view(), name="gitlab-callback"),
path(
"spaces/gitlab/",
GitLabOauthInitiateSpaceEndpoint.as_view(),
@ -177,22 +109,10 @@ urlpatterns = [
name="gitlab-callback",
),
# Email Check
path(
"email-check/",
EmailCheckEndpoint.as_view(),
name="email-check",
),
path(
"spaces/email-check/",
EmailCheckSpaceEndpoint.as_view(),
name="email-check",
),
path("email-check/", EmailCheckEndpoint.as_view(), name="email-check"),
path("spaces/email-check/", EmailCheckSpaceEndpoint.as_view(), name="email-check"),
# Password
path(
"forgot-password/",
ForgotPasswordEndpoint.as_view(),
name="forgot-password",
),
path("forgot-password/", ForgotPasswordEndpoint.as_view(), name="forgot-password"),
path(
"reset-password/<uidb64>/<token>/",
ResetPasswordEndpoint.as_view(),
@ -208,14 +128,6 @@ urlpatterns = [
ResetPasswordSpaceEndpoint.as_view(),
name="forgot-password",
),
path(
"change-password/",
ChangePasswordEndpoint.as_view(),
name="forgot-password",
),
path(
"set-password/",
SetUserPasswordEndpoint.as_view(),
name="set-password",
),
path("change-password/", ChangePasswordEndpoint.as_view(), name="forgot-password"),
path("set-password/", SetUserPasswordEndpoint.as_view(), name="set-password"),
]

View file

@ -17,10 +17,7 @@ def user_login(request, user, is_app=False, is_admin=False, is_space=False):
"user_agent": request.META.get("HTTP_USER_AGENT", ""),
"ip_address": request.META.get("REMOTE_ADDR", ""),
"domain": base_host(
request=request,
is_app=is_app,
is_admin=is_admin,
is_space=is_space,
request=request, is_app=is_app, is_admin=is_admin, is_space=is_space
),
}
request.session["device_info"] = device_info

View file

@ -27,8 +27,7 @@ def get_redirection_path(user):
fallback_workspace = (
Workspace.objects.filter(
workspace_member__member_id=user.id,
workspace_member__is_active=True,
workspace_member__member_id=user.id, workspace_member__is_active=True
)
.order_by("created_at")
.first()

View file

@ -1,9 +1,5 @@
from .workspace_project_join import process_workspace_project_invitations
def post_user_auth_workflow(
user,
is_signup,
request,
):
def post_user_auth_workflow(user, is_signup, request):
process_workspace_project_invitations(user=user)

View file

@ -1,52 +1,23 @@
from .common import (
ChangePasswordEndpoint,
CSRFTokenEndpoint,
SetUserPasswordEndpoint,
)
from .common import ChangePasswordEndpoint, CSRFTokenEndpoint, SetUserPasswordEndpoint
from .app.check import EmailCheckEndpoint
from .app.email import (
SignInAuthEndpoint,
SignUpAuthEndpoint,
)
from .app.github import (
GitHubCallbackEndpoint,
GitHubOauthInitiateEndpoint,
)
from .app.gitlab import (
GitLabCallbackEndpoint,
GitLabOauthInitiateEndpoint,
)
from .app.google import (
GoogleCallbackEndpoint,
GoogleOauthInitiateEndpoint,
)
from .app.magic import (
MagicGenerateEndpoint,
MagicSignInEndpoint,
MagicSignUpEndpoint,
)
from .app.email import SignInAuthEndpoint, SignUpAuthEndpoint
from .app.github import GitHubCallbackEndpoint, GitHubOauthInitiateEndpoint
from .app.gitlab import GitLabCallbackEndpoint, GitLabOauthInitiateEndpoint
from .app.google import GoogleCallbackEndpoint, GoogleOauthInitiateEndpoint
from .app.magic import MagicGenerateEndpoint, MagicSignInEndpoint, MagicSignUpEndpoint
from .app.signout import SignOutAuthEndpoint
from .space.email import SignInAuthSpaceEndpoint, SignUpAuthSpaceEndpoint
from .space.github import (
GitHubCallbackSpaceEndpoint,
GitHubOauthInitiateSpaceEndpoint,
)
from .space.github import GitHubCallbackSpaceEndpoint, GitHubOauthInitiateSpaceEndpoint
from .space.gitlab import (
GitLabCallbackSpaceEndpoint,
GitLabOauthInitiateSpaceEndpoint,
)
from .space.gitlab import GitLabCallbackSpaceEndpoint, GitLabOauthInitiateSpaceEndpoint
from .space.google import (
GoogleCallbackSpaceEndpoint,
GoogleOauthInitiateSpaceEndpoint,
)
from .space.google import GoogleCallbackSpaceEndpoint, GoogleOauthInitiateSpaceEndpoint
from .space.magic import (
MagicGenerateSpaceEndpoint,
@ -62,7 +33,4 @@ from .space.password_management import (
ForgotPasswordSpaceEndpoint,
ResetPasswordSpaceEndpoint,
)
from .app.password_management import (
ForgotPasswordEndpoint,
ResetPasswordEndpoint,
)
from .app.password_management import ForgotPasswordEndpoint, ResetPasswordEndpoint

View file

@ -19,42 +19,27 @@ from plane.authentication.adapter.error import (
AUTHENTICATION_ERROR_CODES,
)
from plane.authentication.rate_limit import AuthenticationThrottle
from plane.license.utils.instance_value import (
get_configuration_value,
)
from plane.license.utils.instance_value import get_configuration_value
class EmailCheckEndpoint(APIView):
permission_classes = [AllowAny]
permission_classes = [
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
throttle_classes = [AuthenticationThrottle]
def post(self, request):
# Check instance configuration
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
(EMAIL_HOST, ENABLE_MAGIC_LINK_LOGIN) = get_configuration_value(
[
{
"key": "EMAIL_HOST",
"default": os.environ.get("EMAIL_HOST", ""),
},
{"key": "EMAIL_HOST", "default": os.environ.get("EMAIL_HOST", "")},
{
"key": "ENABLE_MAGIC_LINK_LOGIN",
"default": os.environ.get("ENABLE_MAGIC_LINK_LOGIN", "1"),
@ -73,10 +58,7 @@ class EmailCheckEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["EMAIL_REQUIRED"],
error_message="EMAIL_REQUIRED",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Validate email
try:
@ -86,10 +68,7 @@ class EmailCheckEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_EMAIL"],
error_message="INVALID_EMAIL",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Check if a user already exists with the given email
existing_user = User.objects.filter(email=email).first()

View file

@ -13,9 +13,7 @@ from plane.authentication.utils.login import user_login
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
from plane.authentication.utils.redirection_path import get_redirection_path
from plane.authentication.utils.user_auth_workflow import (
post_user_auth_workflow,
)
from plane.authentication.utils.user_auth_workflow import post_user_auth_workflow
from plane.db.models import User
from plane.authentication.adapter.error import (
AuthenticationException,
@ -24,7 +22,6 @@ from plane.authentication.adapter.error import (
class SignInAuthEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")
# Check instance configuration
@ -32,9 +29,7 @@ class SignInAuthEndpoint(View):
if instance is None or not instance.is_setup_done:
# Redirection params
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
@ -42,8 +37,7 @@ class SignInAuthEndpoint(View):
params["next_path"] = str(next_path)
# Base URL join
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -66,8 +60,7 @@ class SignInAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -85,8 +78,7 @@ class SignInAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -102,8 +94,7 @@ class SignInAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -132,14 +123,12 @@ class SignInAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
class SignUpAuthEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")
# Check instance configuration
@ -147,17 +136,14 @@ class SignUpAuthEndpoint(View):
if instance is None or not instance.is_setup_done:
# Redirection params
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -177,8 +163,7 @@ class SignUpAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
# Validate the email
@ -196,8 +181,7 @@ class SignUpAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -215,8 +199,7 @@ class SignUpAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -244,7 +227,6 @@ class SignUpAuthEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)

View file

@ -9,9 +9,7 @@ from django.views import View
from plane.authentication.provider.oauth.github import GitHubOAuthProvider
from plane.authentication.utils.login import user_login
from plane.authentication.utils.redirection_path import get_redirection_path
from plane.authentication.utils.user_auth_workflow import (
post_user_auth_workflow,
)
from plane.authentication.utils.user_auth_workflow import post_user_auth_workflow
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
from plane.authentication.adapter.error import (
@ -21,7 +19,6 @@ from plane.authentication.adapter.error import (
class GitHubOauthInitiateEndpoint(View):
def get(self, request):
# Get host and next path
request.session["host"] = base_host(request=request, is_app=True)
@ -33,17 +30,14 @@ class GitHubOauthInitiateEndpoint(View):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
try:
@ -57,14 +51,12 @@ class GitHubOauthInitiateEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
class GitHubCallbackEndpoint(View):
def get(self, request):
code = request.GET.get("code")
state = request.GET.get("state")
@ -73,41 +65,29 @@ class GitHubCallbackEndpoint(View):
if state != request.session.get("state", ""):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITHUB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITHUB_OAUTH_PROVIDER_ERROR"],
error_message="GITHUB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)
if not code:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITHUB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITHUB_OAUTH_PROVIDER_ERROR"],
error_message="GITHUB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)
try:
provider = GitHubOAuthProvider(
request=request,
code=code,
callback=post_user_auth_workflow,
request=request, code=code, callback=post_user_auth_workflow
)
user = provider.authenticate()
# Login the user and record his device info
@ -124,8 +104,5 @@ class GitHubCallbackEndpoint(View):
params = e.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)

View file

@ -9,9 +9,7 @@ from django.views import View
from plane.authentication.provider.oauth.gitlab import GitLabOAuthProvider
from plane.authentication.utils.login import user_login
from plane.authentication.utils.redirection_path import get_redirection_path
from plane.authentication.utils.user_auth_workflow import (
post_user_auth_workflow,
)
from plane.authentication.utils.user_auth_workflow import post_user_auth_workflow
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
from plane.authentication.adapter.error import (
@ -21,7 +19,6 @@ from plane.authentication.adapter.error import (
class GitLabOauthInitiateEndpoint(View):
def get(self, request):
# Get host and next path
request.session["host"] = base_host(request=request, is_app=True)
@ -33,17 +30,14 @@ class GitLabOauthInitiateEndpoint(View):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
try:
@ -57,14 +51,12 @@ class GitLabOauthInitiateEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
class GitLabCallbackEndpoint(View):
def get(self, request):
code = request.GET.get("code")
state = request.GET.get("state")
@ -73,41 +65,29 @@ class GitLabCallbackEndpoint(View):
if state != request.session.get("state", ""):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITLAB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITLAB_OAUTH_PROVIDER_ERROR"],
error_message="GITLAB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)
if not code:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITLAB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITLAB_OAUTH_PROVIDER_ERROR"],
error_message="GITLAB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)
try:
provider = GitLabOAuthProvider(
request=request,
code=code,
callback=post_user_auth_workflow,
request=request, code=code, callback=post_user_auth_workflow
)
user = provider.authenticate()
# Login the user and record his device info
@ -124,8 +104,5 @@ class GitLabCallbackEndpoint(View):
params = e.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)

View file

@ -11,9 +11,7 @@ from django.views import View
from plane.authentication.provider.oauth.google import GoogleOAuthProvider
from plane.authentication.utils.login import user_login
from plane.authentication.utils.redirection_path import get_redirection_path
from plane.authentication.utils.user_auth_workflow import (
post_user_auth_workflow,
)
from plane.authentication.utils.user_auth_workflow import post_user_auth_workflow
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
from plane.authentication.adapter.error import (
@ -33,17 +31,14 @@ class GoogleOauthInitiateEndpoint(View):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -58,8 +53,7 @@ class GoogleOauthInitiateEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -73,39 +67,27 @@ class GoogleCallbackEndpoint(View):
if state != request.session.get("state", ""):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GOOGLE_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GOOGLE_OAUTH_PROVIDER_ERROR"],
error_message="GOOGLE_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)
if not code:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GOOGLE_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GOOGLE_OAUTH_PROVIDER_ERROR"],
error_message="GOOGLE_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
if next_path:
params["next_path"] = next_path
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)
try:
provider = GoogleOAuthProvider(
request=request,
code=code,
callback=post_user_auth_workflow,
request=request, code=code, callback=post_user_auth_workflow
)
user = provider.authenticate()
# Login the user and record his device info
@ -119,8 +101,5 @@ class GoogleCallbackEndpoint(View):
params = e.get_error_dict()
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host,
"?" + urlencode(params),
)
url = urljoin(base_host, "?" + urlencode(params))
return HttpResponseRedirect(url)

View file

@ -13,14 +13,10 @@ from rest_framework.response import Response
from rest_framework.views import APIView
# Module imports
from plane.authentication.provider.credentials.magic_code import (
MagicCodeProvider,
)
from plane.authentication.provider.credentials.magic_code import MagicCodeProvider
from plane.authentication.utils.login import user_login
from plane.authentication.utils.redirection_path import get_redirection_path
from plane.authentication.utils.user_auth_workflow import (
post_user_auth_workflow,
)
from plane.authentication.utils.user_auth_workflow import post_user_auth_workflow
from plane.bgtasks.magic_link_code_task import magic_link
from plane.license.models import Instance
from plane.authentication.utils.host import base_host
@ -33,28 +29,19 @@ from plane.authentication.rate_limit import AuthenticationThrottle
class MagicGenerateEndpoint(APIView):
permission_classes = [AllowAny]
permission_classes = [
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
throttle_classes = [AuthenticationThrottle]
def post(self, request):
# Check if instance is configured
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
return Response(
exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
origin = request.META.get("HTTP_ORIGIN", "/")
email = request.data.get("email", False)
@ -69,16 +56,11 @@ class MagicGenerateEndpoint(APIView):
return Response({"key": str(key)}, status=status.HTTP_200_OK)
except AuthenticationException as e:
params = e.get_error_dict()
return Response(
params,
status=status.HTTP_400_BAD_REQUEST,
)
return Response(params, status=status.HTTP_400_BAD_REQUEST)
class MagicSignInEndpoint(View):
def post(self, request):
# set the referer as session to redirect after login
code = request.POST.get("code", "").strip()
email = request.POST.get("email", "").strip().lower()
@ -95,8 +77,7 @@ class MagicSignInEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -112,8 +93,7 @@ class MagicSignInEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -146,16 +126,13 @@ class MagicSignInEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"sign-in?" + urlencode(params),
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
)
return HttpResponseRedirect(url)
class MagicSignUpEndpoint(View):
def post(self, request):
# set the referer as session to redirect after login
code = request.POST.get("code", "").strip()
email = request.POST.get("email", "").strip().lower()
@ -172,8 +149,7 @@ class MagicSignUpEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
# Existing user
@ -187,8 +163,7 @@ class MagicSignUpEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)
@ -216,7 +191,6 @@ class MagicSignUpEndpoint(View):
if next_path:
params["next_path"] = str(next_path)
url = urljoin(
base_host(request=request, is_app=True),
"?" + urlencode(params),
base_host(request=request, is_app=True), "?" + urlencode(params)
)
return HttpResponseRedirect(url)

View file

@ -14,11 +14,7 @@ from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.http import HttpResponseRedirect
from django.utils.encoding import (
DjangoUnicodeDecodeError,
smart_bytes,
smart_str,
)
from django.utils.encoding import DjangoUnicodeDecodeError, smart_bytes, smart_str
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.views import View
@ -34,6 +30,7 @@ from plane.authentication.adapter.error import (
)
from plane.authentication.rate_limit import AuthenticationThrottle
def generate_password_token(user):
uidb64 = urlsafe_base64_encode(smart_bytes(user.id))
token = PasswordResetTokenGenerator().make_token(user)
@ -42,13 +39,9 @@ def generate_password_token(user):
class ForgotPasswordEndpoint(APIView):
permission_classes = [
AllowAny,
]
permission_classes = [AllowAny]
throttle_classes = [
AuthenticationThrottle,
]
throttle_classes = [AuthenticationThrottle]
def post(self, request):
email = request.data.get("email")
@ -57,23 +50,13 @@ class ForgotPasswordEndpoint(APIView):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
(EMAIL_HOST,) = get_configuration_value(
[
{
"key": "EMAIL_HOST",
"default": os.environ.get("EMAIL_HOST"),
},
]
[{"key": "EMAIL_HOST", "default": os.environ.get("EMAIL_HOST")}]
)
if not (EMAIL_HOST):
@ -81,10 +64,7 @@ class ForgotPasswordEndpoint(APIView):
error_message="SMTP_NOT_CONFIGURED",
error_code=AUTHENTICATION_ERROR_CODES["SMTP_NOT_CONFIGURED"],
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
try:
validate_email(email)
@ -93,10 +73,7 @@ class ForgotPasswordEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_EMAIL"],
error_message="INVALID_EMAIL",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Get the user
user = User.objects.filter(email=email).first()
@ -116,14 +93,10 @@ class ForgotPasswordEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["USER_DOES_NOT_EXIST"],
error_message="USER_DOES_NOT_EXIST",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
class ResetPasswordEndpoint(View):
def post(self, request, uidb64, token):
try:
# Decode the id from the uidb64
@ -133,9 +106,7 @@ class ResetPasswordEndpoint(View):
# check if the token is valid for the user
if not PasswordResetTokenGenerator().check_token(user, token):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INVALID_PASSWORD_TOKEN"
],
error_code=AUTHENTICATION_ERROR_CODES["INVALID_PASSWORD_TOKEN"],
error_message="INVALID_PASSWORD_TOKEN",
)
params = exc.get_error_dict()
@ -154,8 +125,7 @@ class ResetPasswordEndpoint(View):
)
url = urljoin(
base_host(request=request, is_app=True),
"accounts/reset-password?"
+ urlencode(exc.get_error_dict()),
"accounts/reset-password?" + urlencode(exc.get_error_dict()),
)
return HttpResponseRedirect(url)
@ -168,8 +138,7 @@ class ResetPasswordEndpoint(View):
)
url = urljoin(
base_host(request=request, is_app=True),
"accounts/reset-password?"
+ urlencode(exc.get_error_dict()),
"accounts/reset-password?" + urlencode(exc.get_error_dict()),
)
return HttpResponseRedirect(url)
@ -185,9 +154,7 @@ class ResetPasswordEndpoint(View):
return HttpResponseRedirect(url)
except DjangoUnicodeDecodeError:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"EXPIRED_PASSWORD_TOKEN"
],
error_code=AUTHENTICATION_ERROR_CODES["EXPIRED_PASSWORD_TOKEN"],
error_message="EXPIRED_PASSWORD_TOKEN",
)
url = urljoin(

View file

@ -10,7 +10,6 @@ from plane.db.models import User
class SignOutAuthEndpoint(View):
def post(self, request):
# Get user
try:
@ -20,10 +19,6 @@ class SignOutAuthEndpoint(View):
user.save()
# Log the user out
logout(request)
return HttpResponseRedirect(
base_host(request=request, is_app=True)
)
return HttpResponseRedirect(base_host(request=request, is_app=True))
except Exception:
return HttpResponseRedirect(
base_host(request=request, is_app=True)
)
return HttpResponseRedirect(base_host(request=request, is_app=True))

View file

@ -9,9 +9,7 @@ from rest_framework.views import APIView
from zxcvbn import zxcvbn
## Module imports
from plane.app.serializers import (
UserSerializer,
)
from plane.app.serializers import UserSerializer
from plane.authentication.utils.login import user_login
from plane.db.models import User
from plane.authentication.adapter.error import (
@ -22,24 +20,24 @@ from django.middleware.csrf import get_token
from plane.utils.cache import invalidate_cache
from plane.authentication.utils.host import base_host
class CSRFTokenEndpoint(APIView):
permission_classes = [
AllowAny,
]
class CSRFTokenEndpoint(APIView):
permission_classes = [AllowAny]
def get(self, request):
# Generate a CSRF token
csrf_token = get_token(request)
# Return the CSRF token in a JSON response
return Response(
{"csrf_token": str(csrf_token)}, status=status.HTTP_200_OK
)
return Response({"csrf_token": str(csrf_token)}, status=status.HTTP_200_OK)
def csrf_failure(request, reason=""):
"""Custom CSRF failure view"""
return render(request, "csrf_failure.html", {"reason": reason, "root_url": base_host(request=request)})
return render(
request,
"csrf_failure.html",
{"reason": reason, "root_url": base_host(request=request)},
)
class ChangePasswordEndpoint(APIView):
@ -55,23 +53,15 @@ class ChangePasswordEndpoint(APIView):
error_message="MISSING_PASSWORD",
payload={"error": "Old or new password is missing"},
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
if not user.check_password(old_password):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INCORRECT_OLD_PASSWORD"
],
error_code=AUTHENTICATION_ERROR_CODES["INCORRECT_OLD_PASSWORD"],
error_message="INCORRECT_OLD_PASSWORD",
payload={"error": "Old password is not correct"},
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# check the password score
results = zxcvbn(new_password)
@ -80,10 +70,7 @@ class ChangePasswordEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_NEW_PASSWORD"],
error_message="INVALID_NEW_PASSWORD",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# set_password also hashes the password that the user will get
user.set_password(new_password)
@ -91,13 +78,11 @@ class ChangePasswordEndpoint(APIView):
user.save()
user_login(user=user, request=request, is_app=True)
return Response(
{"message": "Password updated successfully"},
status=status.HTTP_200_OK,
{"message": "Password updated successfully"}, status=status.HTTP_200_OK
)
class SetUserPasswordEndpoint(APIView):
@invalidate_cache("/api/users/me/")
def post(self, request):
user = User.objects.get(pk=request.user.id)
@ -112,10 +97,7 @@ class SetUserPasswordEndpoint(APIView):
"error": "Your password is already set please change your password from profile"
},
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Check password validation
if not password:
@ -123,10 +105,7 @@ class SetUserPasswordEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_PASSWORD"],
error_message="INVALID_PASSWORD",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
results = zxcvbn(password)
if results["score"] < 3:
@ -134,10 +113,7 @@ class SetUserPasswordEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_PASSWORD"],
error_message="INVALID_PASSWORD",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Set the user password
user.set_password(password)

View file

@ -23,36 +23,23 @@ from plane.license.utils.instance_value import get_configuration_value
class EmailCheckSpaceEndpoint(APIView):
permission_classes = [AllowAny]
permission_classes = [
AllowAny,
]
throttle_classes = [
AuthenticationThrottle,
]
throttle_classes = [AuthenticationThrottle]
def post(self, request):
# Check instance configuration
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
(EMAIL_HOST, ENABLE_MAGIC_LINK_LOGIN) = get_configuration_value(
[
{
"key": "EMAIL_HOST",
"default": os.environ.get("EMAIL_HOST", ""),
},
{"key": "EMAIL_HOST", "default": os.environ.get("EMAIL_HOST", "")},
{
"key": "ENABLE_MAGIC_LINK_LOGIN",
"default": os.environ.get("ENABLE_MAGIC_LINK_LOGIN", "1"),
@ -71,10 +58,7 @@ class EmailCheckSpaceEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["EMAIL_REQUIRED"],
error_message="EMAIL_REQUIRED",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Validate email
try:
@ -84,10 +68,7 @@ class EmailCheckSpaceEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_EMAIL"],
error_message="INVALID_EMAIL",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Check if a user already exists with the given email
existing_user = User.objects.filter(email=email).first()

View file

@ -20,7 +20,6 @@ from plane.authentication.adapter.error import (
class SignInAuthSpaceEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")
# Check instance configuration
@ -28,9 +27,7 @@ class SignInAuthSpaceEndpoint(View):
if instance is None or not instance.is_setup_done:
# Redirection params
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
@ -108,7 +105,6 @@ class SignInAuthSpaceEndpoint(View):
class SignUpAuthSpaceEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")
# Check instance configuration
@ -116,9 +112,7 @@ class SignUpAuthSpaceEndpoint(View):
if instance is None or not instance.is_setup_done:
# Redirection params
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()

View file

@ -18,7 +18,6 @@ from plane.authentication.adapter.error import (
class GitHubOauthInitiateSpaceEndpoint(View):
def get(self, request):
# Get host and next path
request.session["host"] = base_host(request=request, is_space=True)
@ -30,9 +29,7 @@ class GitHubOauthInitiateSpaceEndpoint(View):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
@ -56,7 +53,6 @@ class GitHubOauthInitiateSpaceEndpoint(View):
class GitHubCallbackSpaceEndpoint(View):
def get(self, request):
code = request.GET.get("code")
state = request.GET.get("state")
@ -65,9 +61,7 @@ class GitHubCallbackSpaceEndpoint(View):
if state != request.session.get("state", ""):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITHUB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITHUB_OAUTH_PROVIDER_ERROR"],
error_message="GITHUB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
@ -78,9 +72,7 @@ class GitHubCallbackSpaceEndpoint(View):
if not code:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITHUB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITHUB_OAUTH_PROVIDER_ERROR"],
error_message="GITHUB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
@ -90,10 +82,7 @@ class GitHubCallbackSpaceEndpoint(View):
return HttpResponseRedirect(url)
try:
provider = GitHubOAuthProvider(
request=request,
code=code,
)
provider = GitHubOAuthProvider(request=request, code=code)
user = provider.authenticate()
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)

View file

@ -18,7 +18,6 @@ from plane.authentication.adapter.error import (
class GitLabOauthInitiateSpaceEndpoint(View):
def get(self, request):
# Get host and next path
request.session["host"] = base_host(request=request, is_space=True)
@ -30,9 +29,7 @@ class GitLabOauthInitiateSpaceEndpoint(View):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
@ -56,7 +53,6 @@ class GitLabOauthInitiateSpaceEndpoint(View):
class GitLabCallbackSpaceEndpoint(View):
def get(self, request):
code = request.GET.get("code")
state = request.GET.get("state")
@ -65,9 +61,7 @@ class GitLabCallbackSpaceEndpoint(View):
if state != request.session.get("state", ""):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITLAB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITLAB_OAUTH_PROVIDER_ERROR"],
error_message="GITLAB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
@ -78,9 +72,7 @@ class GitLabCallbackSpaceEndpoint(View):
if not code:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GITLAB_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GITLAB_OAUTH_PROVIDER_ERROR"],
error_message="GITLAB_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
@ -90,10 +82,7 @@ class GitLabCallbackSpaceEndpoint(View):
return HttpResponseRedirect(url)
try:
provider = GitLabOAuthProvider(
request=request,
code=code,
)
provider = GitLabOAuthProvider(request=request, code=code)
user = provider.authenticate()
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)

View file

@ -28,9 +28,7 @@ class GoogleOauthInitiateSpaceEndpoint(View):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
params = exc.get_error_dict()
@ -62,9 +60,7 @@ class GoogleCallbackSpaceEndpoint(View):
if state != request.session.get("state", ""):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GOOGLE_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GOOGLE_OAUTH_PROVIDER_ERROR"],
error_message="GOOGLE_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
@ -74,9 +70,7 @@ class GoogleCallbackSpaceEndpoint(View):
return HttpResponseRedirect(url)
if not code:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"GOOGLE_OAUTH_PROVIDER_ERROR"
],
error_code=AUTHENTICATION_ERROR_CODES["GOOGLE_OAUTH_PROVIDER_ERROR"],
error_message="GOOGLE_OAUTH_PROVIDER_ERROR",
)
params = exc.get_error_dict()
@ -85,10 +79,7 @@ class GoogleCallbackSpaceEndpoint(View):
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
return HttpResponseRedirect(url)
try:
provider = GoogleOAuthProvider(
request=request,
code=code,
)
provider = GoogleOAuthProvider(request=request, code=code)
user = provider.authenticate()
# Login the user and record his device info
user_login(request=request, user=user, is_space=True)

View file

@ -13,9 +13,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView
# Module imports
from plane.authentication.provider.credentials.magic_code import (
MagicCodeProvider,
)
from plane.authentication.provider.credentials.magic_code import MagicCodeProvider
from plane.authentication.utils.login import user_login
from plane.bgtasks.magic_link_code_task import magic_link
from plane.license.models import Instance
@ -28,24 +26,17 @@ from plane.authentication.adapter.error import (
class MagicGenerateSpaceEndpoint(APIView):
permission_classes = [
AllowAny,
]
permission_classes = [AllowAny]
def post(self, request):
# Check if instance is configured
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
return Response(
exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
origin = base_host(request=request, is_space=True)
email = request.data.get("email", False)
@ -59,16 +50,11 @@ class MagicGenerateSpaceEndpoint(APIView):
magic_link.delay(email, key, token, origin)
return Response({"key": str(key)}, status=status.HTTP_200_OK)
except AuthenticationException as e:
return Response(
e.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(e.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
class MagicSignInSpaceEndpoint(View):
def post(self, request):
# set the referer as session to redirect after login
code = request.POST.get("code", "").strip()
email = request.POST.get("email", "").strip().lower()
@ -122,9 +108,7 @@ class MagicSignInSpaceEndpoint(View):
class MagicSignUpSpaceEndpoint(View):
def post(self, request):
# set the referer as session to redirect after login
code = request.POST.get("code", "").strip()
email = request.POST.get("email", "").strip().lower()

View file

@ -14,11 +14,7 @@ from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.http import HttpResponseRedirect
from django.utils.encoding import (
DjangoUnicodeDecodeError,
smart_bytes,
smart_str,
)
from django.utils.encoding import DjangoUnicodeDecodeError, smart_bytes, smart_str
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.views import View
@ -43,13 +39,9 @@ def generate_password_token(user):
class ForgotPasswordSpaceEndpoint(APIView):
permission_classes = [
AllowAny,
]
permission_classes = [AllowAny]
throttle_classes = [
AuthenticationThrottle,
]
throttle_classes = [AuthenticationThrottle]
def post(self, request):
email = request.data.get("email")
@ -58,33 +50,23 @@ class ForgotPasswordSpaceEndpoint(APIView):
instance = Instance.objects.first()
if instance is None or not instance.is_setup_done:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INSTANCE_NOT_CONFIGURED"
],
error_code=AUTHENTICATION_ERROR_CODES["INSTANCE_NOT_CONFIGURED"],
error_message="INSTANCE_NOT_CONFIGURED",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
(EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD) = (
get_configuration_value(
[
{
"key": "EMAIL_HOST",
"default": os.environ.get("EMAIL_HOST"),
},
{
"key": "EMAIL_HOST_USER",
"default": os.environ.get("EMAIL_HOST_USER"),
},
{
"key": "EMAIL_HOST_PASSWORD",
"default": os.environ.get("EMAIL_HOST_PASSWORD"),
},
]
)
(EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD) = get_configuration_value(
[
{"key": "EMAIL_HOST", "default": os.environ.get("EMAIL_HOST")},
{
"key": "EMAIL_HOST_USER",
"default": os.environ.get("EMAIL_HOST_USER"),
},
{
"key": "EMAIL_HOST_PASSWORD",
"default": os.environ.get("EMAIL_HOST_PASSWORD"),
},
]
)
if not (EMAIL_HOST):
@ -92,10 +74,7 @@ class ForgotPasswordSpaceEndpoint(APIView):
error_message="SMTP_NOT_CONFIGURED",
error_code=AUTHENTICATION_ERROR_CODES["SMTP_NOT_CONFIGURED"],
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
try:
validate_email(email)
@ -104,10 +83,7 @@ class ForgotPasswordSpaceEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["INVALID_EMAIL"],
error_message="INVALID_EMAIL",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
# Get the user
user = User.objects.filter(email=email).first()
@ -127,14 +103,10 @@ class ForgotPasswordSpaceEndpoint(APIView):
error_code=AUTHENTICATION_ERROR_CODES["USER_DOES_NOT_EXIST"],
error_message="USER_DOES_NOT_EXIST",
)
return Response(
exc.get_error_dict(),
status=status.HTTP_400_BAD_REQUEST,
)
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
class ResetPasswordSpaceEndpoint(View):
def post(self, request, uidb64, token):
try:
# Decode the id from the uidb64
@ -144,9 +116,7 @@ class ResetPasswordSpaceEndpoint(View):
# check if the token is valid for the user
if not PasswordResetTokenGenerator().check_token(user, token):
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"INVALID_PASSWORD_TOKEN"
],
error_code=AUTHENTICATION_ERROR_CODES["INVALID_PASSWORD_TOKEN"],
error_message="INVALID_PASSWORD_TOKEN",
)
params = exc.get_error_dict()
@ -178,14 +148,10 @@ class ResetPasswordSpaceEndpoint(View):
user.is_password_autoset = False
user.save()
return HttpResponseRedirect(
base_host(request=request, is_space=True)
)
return HttpResponseRedirect(base_host(request=request, is_space=True))
except DjangoUnicodeDecodeError:
exc = AuthenticationException(
error_code=AUTHENTICATION_ERROR_CODES[
"EXPIRED_PASSWORD_TOKEN"
],
error_code=AUTHENTICATION_ERROR_CODES["EXPIRED_PASSWORD_TOKEN"],
error_message="EXPIRED_PASSWORD_TOKEN",
)
url = f"{base_host(request=request, is_space=True)}/accounts/reset-password/?{urlencode(exc.get_error_dict())}"

View file

@ -10,7 +10,6 @@ from plane.db.models import User
class SignOutAuthSpaceEndpoint(View):
def post(self, request):
next_path = request.POST.get("next_path")