[WEB-3700] chore: improve authentication redirections (#6836)
* chore: update redirections to be from allowed hosts * chore: update redirection logic * chore: add web url in settings * chore: add next path validation * chore: update typings * chore: update typings * chore: update types --------- Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
parent
adee686ea3
commit
d9e3405f5a
45 changed files with 230 additions and 196 deletions
|
|
@ -39,7 +39,7 @@ from plane.db.models import (
|
|||
UserFavorite,
|
||||
)
|
||||
from plane.utils.analytics_plot import burndown_plot
|
||||
|
||||
from plane.utils.host import base_host
|
||||
from .base import BaseAPIView
|
||||
from plane.bgtasks.webhook_task import model_activity
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ class CycleAPIEndpoint(BaseAPIView):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -331,7 +331,7 @@ class CycleAPIEndpoint(BaseAPIView):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -702,7 +702,7 @@ class CycleIssueAPIEndpoint(BaseAPIView):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
# Return all Cycle Issues
|
||||
return Response(
|
||||
|
|
@ -1176,7 +1176,7 @@ class TransferCycleIssueAPIEndpoint(BaseAPIView):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response({"message": "Success"}, status=status.HTTP_200_OK)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from plane.api.serializers import IntakeIssueSerializer, IssueSerializer
|
|||
from plane.app.permissions import ProjectLitePermission
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.db.models import Intake, IntakeIssue, Issue, Project, ProjectMember, State
|
||||
|
||||
from plane.utils.host import base_host
|
||||
from .base import BaseAPIView
|
||||
|
||||
|
||||
|
|
@ -297,7 +297,7 @@ class IntakeIssueAPIEndpoint(BaseAPIView):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=False,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
intake=str(intake_issue.id),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ from plane.db.models import (
|
|||
from plane.settings.storage import S3Storage
|
||||
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
|
||||
from .base import BaseAPIView
|
||||
from plane.utils.host import base_host
|
||||
|
||||
|
||||
class WorkspaceIssueAPIEndpoint(BaseAPIView):
|
||||
|
|
@ -1048,7 +1049,7 @@ class IssueAttachmentEndpoint(BaseAPIView):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
# Get the storage metadata
|
||||
|
|
@ -1108,7 +1109,7 @@ class IssueAttachmentEndpoint(BaseAPIView):
|
|||
current_instance=json.dumps(serializer.data, cls=DjangoJSONEncoder),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
# Update the attachment
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ from plane.db.models import (
|
|||
|
||||
from .base import BaseAPIView
|
||||
from plane.bgtasks.webhook_task import model_activity
|
||||
from plane.utils.host import base_host
|
||||
|
||||
|
||||
class ModuleAPIEndpoint(BaseAPIView):
|
||||
|
|
@ -174,7 +175,7 @@ class ModuleAPIEndpoint(BaseAPIView):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
module = Module.objects.get(pk=serializer.data["id"])
|
||||
serializer = ModuleSerializer(module)
|
||||
|
|
@ -226,7 +227,7 @@ class ModuleAPIEndpoint(BaseAPIView):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
|
@ -280,6 +281,7 @@ class ModuleAPIEndpoint(BaseAPIView):
|
|||
project_id=str(project_id),
|
||||
current_instance=json.dumps({"module_name": str(module.name)}),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
module.delete()
|
||||
# Delete the module issues
|
||||
|
|
@ -449,6 +451,7 @@ class ModuleIssueAPIEndpoint(BaseAPIView):
|
|||
}
|
||||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response(
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ from plane.db.models import (
|
|||
)
|
||||
from plane.bgtasks.webhook_task import model_activity, webhook_activity
|
||||
from .base import BaseAPIView
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class ProjectAPIEndpoint(BaseAPIView):
|
||||
"""Project Endpoints to create, update, list, retrieve and delete endpoint"""
|
||||
|
|
@ -228,7 +228,7 @@ class ProjectAPIEndpoint(BaseAPIView):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
serializer = ProjectSerializer(project)
|
||||
|
|
@ -297,7 +297,7 @@ class ProjectAPIEndpoint(BaseAPIView):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
serializer = ProjectSerializer(project)
|
||||
|
|
@ -334,7 +334,7 @@ class ProjectAPIEndpoint(BaseAPIView):
|
|||
new_value=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
current_site=request.META.get("HTTP_ORIGIN"),
|
||||
current_site=base_host(request=request, is_app=True),
|
||||
event_id=project.id,
|
||||
old_identifier=None,
|
||||
new_identifier=None,
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@ from plane.db.models import (
|
|||
)
|
||||
from plane.utils.analytics_plot import burndown_plot
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
# Module imports
|
||||
from plane.utils.host import base_host
|
||||
from .. import BaseAPIView, BaseViewSet
|
||||
from plane.bgtasks.webhook_task import model_activity
|
||||
from plane.utils.timezone_converter import convert_to_utc, user_timezone_converter
|
||||
|
|
@ -335,7 +334,7 @@ class CycleViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(cycle, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -428,7 +427,7 @@ class CycleViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response(cycle, status=status.HTTP_200_OK)
|
||||
|
|
@ -541,7 +540,7 @@ class CycleViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
# TODO: Soft delete the cycle break the onetoone relationship with cycle issue
|
||||
cycle.delete()
|
||||
|
|
@ -1080,7 +1079,7 @@ class TransferCycleIssueEndpoint(BaseAPIView):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response({"message": "Success"}, status=status.HTTP_200_OK)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from plane.utils.issue_filters import issue_filters
|
|||
from plane.utils.order_queryset import order_issue_queryset
|
||||
from plane.utils.paginator import GroupedOffsetPaginator, SubGroupedOffsetPaginator
|
||||
from plane.app.permissions import allow_permission, ROLE
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class CycleIssueViewSet(BaseViewSet):
|
||||
serializer_class = CycleIssueSerializer
|
||||
|
|
@ -291,7 +291,7 @@ class CycleIssueViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response({"message": "success"}, status=status.HTTP_201_CREATED)
|
||||
|
||||
|
|
@ -317,7 +317,7 @@ class CycleIssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
cycle_issue.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ from plane.app.serializers import (
|
|||
)
|
||||
from plane.utils.issue_filters import issue_filters
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.utils.host import base_host
|
||||
|
||||
|
||||
class IntakeViewSet(BaseViewSet):
|
||||
|
|
@ -283,7 +284,7 @@ class IntakeIssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
intake=str(intake_issue.id),
|
||||
)
|
||||
intake_issue = (
|
||||
|
|
@ -407,7 +408,7 @@ class IntakeIssueViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
intake=str(intake_issue.id),
|
||||
)
|
||||
issue_serializer.save()
|
||||
|
|
@ -467,7 +468,7 @@ class IntakeIssueViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=False,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
intake=(intake_issue.id),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ from plane.utils.order_queryset import order_issue_queryset
|
|||
from plane.utils.paginator import GroupedOffsetPaginator, SubGroupedOffsetPaginator
|
||||
from plane.app.permissions import allow_permission, ROLE
|
||||
from plane.utils.error_codes import ERROR_CODES
|
||||
|
||||
from plane.utils.host import base_host
|
||||
# Module imports
|
||||
from .. import BaseViewSet, BaseAPIView
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ class IssueArchiveViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
issue.archived_at = timezone.now().date()
|
||||
issue.save()
|
||||
|
|
@ -287,7 +287,7 @@ class IssueArchiveViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
issue.archived_at = None
|
||||
issue.save()
|
||||
|
|
@ -333,7 +333,7 @@ class BulkArchiveIssuesEndpoint(BaseAPIView):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
issue.archived_at = timezone.now().date()
|
||||
bulk_archive_issues.append(issue)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from plane.bgtasks.issue_activities_task import issue_activity
|
|||
from plane.app.permissions import allow_permission, ROLE
|
||||
from plane.settings.storage import S3Storage
|
||||
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class IssueAttachmentEndpoint(BaseAPIView):
|
||||
serializer_class = IssueAttachmentSerializer
|
||||
|
|
@ -48,7 +48,7 @@ class IssueAttachmentEndpoint(BaseAPIView):
|
|||
current_instance=json.dumps(serializer.data, cls=DjangoJSONEncoder),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -67,7 +67,7 @@ class IssueAttachmentEndpoint(BaseAPIView):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
@ -155,7 +155,7 @@ class IssueAttachmentV2Endpoint(BaseAPIView):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
@ -213,7 +213,7 @@ class IssueAttachmentV2Endpoint(BaseAPIView):
|
|||
current_instance=json.dumps(serializer.data, cls=DjangoJSONEncoder),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
# Update the attachment
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ from plane.bgtasks.recent_visited_task import recent_visited_task
|
|||
from plane.utils.global_paginator import paginate
|
||||
from plane.bgtasks.webhook_task import model_activity
|
||||
from plane.bgtasks.issue_description_version_task import issue_description_version_task
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class IssueListEndpoint(BaseAPIView):
|
||||
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
|
||||
|
|
@ -379,7 +379,7 @@ class IssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
issue = (
|
||||
issue_queryset_grouper(
|
||||
|
|
@ -429,7 +429,7 @@ class IssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
# updated issue description version
|
||||
issue_description_version_task.delay(
|
||||
|
|
@ -650,7 +650,7 @@ class IssueViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
model_activity.delay(
|
||||
model_name="issue",
|
||||
|
|
@ -659,7 +659,7 @@ class IssueViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
# updated issue description version
|
||||
issue_description_version_task.delay(
|
||||
|
|
@ -691,8 +691,8 @@ class IssueViewSet(BaseViewSet):
|
|||
current_instance={},
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=base_host(request=request, is_app=True),
|
||||
subscriber=False,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from plane.app.serializers import IssueCommentSerializer, CommentReactionSeriali
|
|||
from plane.app.permissions import allow_permission, ROLE
|
||||
from plane.db.models import IssueComment, ProjectMember, CommentReaction, Project, Issue
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class IssueCommentViewSet(BaseViewSet):
|
||||
serializer_class = IssueCommentSerializer
|
||||
|
|
@ -87,7 +87,7 @@ class IssueCommentViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -121,7 +121,7 @@ class IssueCommentViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -144,7 +144,7 @@ class IssueCommentViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
|
@ -188,7 +188,7 @@ class CommentReactionViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -222,7 +222,7 @@ class CommentReactionViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
comment_reaction.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from plane.app.serializers import IssueLinkSerializer
|
|||
from plane.app.permissions import ProjectEntityPermission
|
||||
from plane.db.models import IssueLink
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class IssueLinkViewSet(BaseViewSet):
|
||||
permission_classes = [ProjectEntityPermission]
|
||||
|
|
@ -52,7 +52,7 @@ class IssueLinkViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -77,7 +77,7 @@ class IssueLinkViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -98,7 +98,7 @@ class IssueLinkViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
issue_link.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from plane.app.serializers import IssueReactionSerializer
|
|||
from plane.app.permissions import allow_permission, ROLE
|
||||
from plane.db.models import IssueReaction
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class IssueReactionViewSet(BaseViewSet):
|
||||
serializer_class = IssueReactionSerializer
|
||||
|
|
@ -53,7 +53,7 @@ class IssueReactionViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
|
@ -78,7 +78,7 @@ class IssueReactionViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
issue_reaction.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from plane.db.models import (
|
|||
)
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.utils.issue_relation_mapper import get_actual_relation
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class IssueRelationViewSet(BaseViewSet):
|
||||
serializer_class = IssueRelationSerializer
|
||||
|
|
@ -253,7 +253,7 @@ class IssueRelationViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
if relation_type in ["blocking", "start_after", "finish_after"]:
|
||||
|
|
@ -290,6 +290,6 @@ class IssueRelationViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ from plane.db.models import Issue, IssueLink, FileAsset, CycleIssue
|
|||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.utils.timezone_converter import user_timezone_converter
|
||||
from collections import defaultdict
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class SubIssuesEndpoint(BaseAPIView):
|
||||
permission_classes = [ProjectEntityPermission]
|
||||
|
|
@ -176,7 +176,7 @@ class SubIssuesEndpoint(BaseAPIView):
|
|||
current_instance=json.dumps({"parent": str(sub_issue_id)}),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
for sub_issue_id in sub_issue_ids
|
||||
]
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ from plane.utils.timezone_converter import user_timezone_converter
|
|||
from plane.bgtasks.webhook_task import model_activity
|
||||
from .. import BaseAPIView, BaseViewSet
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class ModuleViewSet(BaseViewSet):
|
||||
model = Module
|
||||
|
|
@ -376,7 +376,7 @@ class ModuleViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
datetime_fields = ["created_at", "updated_at"]
|
||||
module = user_timezone_converter(
|
||||
|
|
@ -768,7 +768,7 @@ class ModuleViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
datetime_fields = ["created_at", "updated_at"]
|
||||
|
|
@ -795,7 +795,7 @@ class ModuleViewSet(BaseViewSet):
|
|||
current_instance=json.dumps({"module_name": str(module.name)}),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
for issue in module_issues
|
||||
]
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ from plane.utils.paginator import GroupedOffsetPaginator, SubGroupedOffsetPagina
|
|||
|
||||
# Module imports
|
||||
from .. import BaseViewSet
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class ModuleIssueViewSet(BaseViewSet):
|
||||
serializer_class = ModuleIssueSerializer
|
||||
|
|
@ -221,7 +221,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
for issue in issues
|
||||
]
|
||||
|
|
@ -261,7 +261,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
for module in modules
|
||||
]
|
||||
|
|
@ -284,7 +284,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
module_issue.delete()
|
||||
|
||||
|
|
@ -309,7 +309,7 @@ class ModuleIssueViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
module_issue.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ from plane.utils.cache import cache_response
|
|||
from plane.bgtasks.webhook_task import model_activity, webhook_activity
|
||||
from plane.bgtasks.recent_visited_task import recent_visited_task
|
||||
from plane.utils.exception_logger import log_exception
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class ProjectViewSet(BaseViewSet):
|
||||
serializer_class = ProjectListSerializer
|
||||
|
|
@ -331,7 +331,7 @@ class ProjectViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
serializer = ProjectListSerializer(project)
|
||||
|
|
@ -409,7 +409,7 @@ class ProjectViewSet(BaseViewSet):
|
|||
current_instance=current_instance,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
serializer = ProjectListSerializer(project)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
|
@ -454,7 +454,7 @@ class ProjectViewSet(BaseViewSet):
|
|||
new_value=None,
|
||||
actor_id=request.user.id,
|
||||
slug=slug,
|
||||
current_site=request.META.get("HTTP_ORIGIN"),
|
||||
current_site=base_host(request=request, is_app=True),
|
||||
event_id=project.id,
|
||||
old_identifier=None,
|
||||
new_identifier=None,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ from plane.db.models import (
|
|||
IssueUserProperty,
|
||||
)
|
||||
from plane.db.models.project import ProjectNetwork
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class ProjectInvitationsViewset(BaseViewSet):
|
||||
serializer_class = ProjectMemberInviteSerializer
|
||||
|
|
@ -99,7 +99,7 @@ class ProjectInvitationsViewset(BaseViewSet):
|
|||
project_invitations = ProjectMemberInvite.objects.bulk_create(
|
||||
project_invitations, batch_size=10, ignore_conflicts=True
|
||||
)
|
||||
current_site = request.META.get("HTTP_ORIGIN")
|
||||
current_site = base_host(request=request, is_app=True)
|
||||
|
||||
# Send invitations
|
||||
for invitation in project_invitations:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ from plane.db.models import (
|
|||
from .. import BaseViewSet
|
||||
from plane.bgtasks.issue_activities_task import issue_activity
|
||||
from plane.utils.issue_filters import issue_filters
|
||||
|
||||
from plane.utils.host import base_host
|
||||
|
||||
class WorkspaceDraftIssueViewSet(BaseViewSet):
|
||||
model = DraftIssue
|
||||
|
|
@ -241,7 +241,7 @@ class WorkspaceDraftIssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
if request.data.get("cycle_id", None):
|
||||
|
|
@ -270,7 +270,7 @@ class WorkspaceDraftIssueViewSet(BaseViewSet):
|
|||
),
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
|
||||
if request.data.get("module_ids", []):
|
||||
|
|
@ -300,7 +300,7 @@ class WorkspaceDraftIssueViewSet(BaseViewSet):
|
|||
current_instance=None,
|
||||
epoch=int(timezone.now().timestamp()),
|
||||
notification=True,
|
||||
origin=request.META.get("HTTP_ORIGIN"),
|
||||
origin=base_host(request=request, is_app=True),
|
||||
)
|
||||
for module in request.data.get("module_ids", [])
|
||||
]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import jwt
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import validate_email
|
||||
from django.db.models import Count
|
||||
from django.utils import timezone
|
||||
|
||||
# Third party modules
|
||||
|
|
@ -26,7 +25,8 @@ from plane.bgtasks.event_tracking_task import workspace_invite_event
|
|||
from plane.bgtasks.workspace_invitation_task import workspace_invitation
|
||||
from plane.db.models import User, Workspace, WorkspaceMember, WorkspaceMemberInvite
|
||||
from plane.utils.cache import invalidate_cache, invalidate_cache_directly
|
||||
|
||||
from plane.utils.host import base_host
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
from .. import BaseViewSet
|
||||
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ class WorkspaceInvitationsViewset(BaseViewSet):
|
|||
workspace_invitations, batch_size=10, ignore_conflicts=True
|
||||
)
|
||||
|
||||
current_site = request.META.get("HTTP_ORIGIN")
|
||||
current_site = base_host(request=request, is_app=True)
|
||||
|
||||
# Send invitations
|
||||
for invitation in workspace_invitations:
|
||||
|
|
@ -213,7 +213,7 @@ class WorkspaceJoinEndpoint(BaseAPIView):
|
|||
user=user.id if user is not None else None,
|
||||
email=email,
|
||||
user_agent=request.META.get("HTTP_USER_AGENT"),
|
||||
ip=request.META.get("REMOTE_ADDR"),
|
||||
ip=get_client_ip(request=request),
|
||||
event_name="MEMBER_ACCEPTED",
|
||||
accepted_from="EMAIL",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ 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
|
||||
from plane.authentication.utils.host import base_host
|
||||
|
||||
from plane.utils.host import base_host
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
|
||||
class Adapter:
|
||||
"""Common interface for all auth providers"""
|
||||
|
|
@ -108,7 +108,7 @@ class Adapter:
|
|||
user.last_login_medium = self.provider
|
||||
user.last_active = timezone.now()
|
||||
user.last_login_time = timezone.now()
|
||||
user.last_login_ip = self.request.META.get("REMOTE_ADDR")
|
||||
user.last_login_ip = get_client_ip(request=self.request)
|
||||
user.last_login_uagent = self.request.META.get("HTTP_USER_AGENT")
|
||||
user.token_updated_at = timezone.now()
|
||||
# If user is not active, send the activation email and set the user as active
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
# Python imports
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
# Django imports
|
||||
from django.conf import settings
|
||||
from django.http import HttpRequest
|
||||
# Third party imports
|
||||
from rest_framework.request import Request
|
||||
|
||||
# Module imports
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
|
||||
def base_host(request, is_admin=False, is_space=False, is_app=False):
|
||||
def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space: bool = False, is_app: bool = False) -> str:
|
||||
"""Utility function to return host / origin from the request"""
|
||||
# Calculate the base origin from request
|
||||
base_origin = str(
|
||||
request.META.get("HTTP_ORIGIN")
|
||||
or f"{urlsplit(request.META.get('HTTP_REFERER')).scheme}://{urlsplit(request.META.get('HTTP_REFERER')).netloc}"
|
||||
or f"""{"https" if request.is_secure() else "http"}://{request.get_host()}"""
|
||||
)
|
||||
base_origin = settings.WEB_URL or settings.APP_BASE_URL
|
||||
|
||||
# Admin redirections
|
||||
if is_admin:
|
||||
|
|
@ -38,5 +36,5 @@ def base_host(request, is_admin=False, is_space=False, is_app=False):
|
|||
return base_origin
|
||||
|
||||
|
||||
def user_ip(request):
|
||||
return str(request.META.get("REMOTE_ADDR"))
|
||||
def user_ip(request: Request | HttpRequest) -> str:
|
||||
return get_client_ip(request=request)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ from django.contrib.auth import login
|
|||
from django.conf import settings
|
||||
|
||||
# Module imports
|
||||
from plane.authentication.utils.host import base_host
|
||||
|
||||
from plane.utils.host import base_host
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
|
||||
def user_login(request, user, is_app=False, is_admin=False, is_space=False):
|
||||
login(request=request, user=user)
|
||||
|
|
@ -15,7 +15,7 @@ def user_login(request, user, is_app=False, is_admin=False, is_space=False):
|
|||
|
||||
device_info = {
|
||||
"user_agent": request.META.get("HTTP_USER_AGENT", ""),
|
||||
"ip_address": request.META.get("REMOTE_ADDR", ""),
|
||||
"ip_address": get_client_ip(request=request),
|
||||
"domain": base_host(
|
||||
request=request, is_app=is_app, is_admin=is_admin, is_space=is_space
|
||||
),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from plane.authentication.adapter.error import (
|
|||
AuthenticationException,
|
||||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
class SignInAuthEndpoint(View):
|
||||
def post(self, request):
|
||||
|
|
@ -34,7 +34,7 @@ class SignInAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
# Base URL join
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
|
|
@ -58,7 +58,7 @@ class SignInAuthEndpoint(View):
|
|||
params = exc.get_error_dict()
|
||||
# Next path
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -76,7 +76,7 @@ class SignInAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -92,7 +92,7 @@ class SignInAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -111,7 +111,7 @@ class SignInAuthEndpoint(View):
|
|||
user_login(request=request, user=user, is_app=True)
|
||||
# Get the redirection path
|
||||
if next_path:
|
||||
path = str(next_path)
|
||||
path = str(validate_next_path(next_path))
|
||||
else:
|
||||
path = get_redirection_path(user=user)
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ class SignInAuthEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -141,7 +141,7 @@ class SignUpAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -161,7 +161,7 @@ class SignUpAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -179,7 +179,7 @@ class SignUpAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -197,7 +197,7 @@ class SignUpAuthEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -216,7 +216,7 @@ class SignUpAuthEndpoint(View):
|
|||
user_login(request=request, user=user, is_app=True)
|
||||
# Get the redirection path
|
||||
if next_path:
|
||||
path = next_path
|
||||
path = str(validate_next_path(next_path))
|
||||
else:
|
||||
path = get_redirection_path(user=user)
|
||||
# redirect to referer path
|
||||
|
|
@ -225,7 +225,7 @@ class SignUpAuthEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from plane.authentication.adapter.error import (
|
|||
AuthenticationException,
|
||||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
class GitHubOauthInitiateEndpoint(View):
|
||||
def get(self, request):
|
||||
|
|
@ -35,7 +35,7 @@ class GitHubOauthInitiateEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -49,7 +49,7 @@ class GitHubOauthInitiateEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -70,7 +70,7 @@ class GitHubCallbackEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ class GitHubCallbackEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class GitHubCallbackEndpoint(View):
|
|||
user_login(request=request, user=user, is_app=True)
|
||||
# Get the redirection path
|
||||
if next_path:
|
||||
path = next_path
|
||||
path = str(validate_next_path(next_path))
|
||||
else:
|
||||
path = get_redirection_path(user=user)
|
||||
# redirect to referer path
|
||||
|
|
@ -103,6 +103,6 @@ class GitHubCallbackEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from plane.authentication.adapter.error import (
|
|||
AuthenticationException,
|
||||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
class GitLabOauthInitiateEndpoint(View):
|
||||
def get(self, request):
|
||||
|
|
@ -24,7 +24,7 @@ class GitLabOauthInitiateEndpoint(View):
|
|||
request.session["host"] = base_host(request=request, is_app=True)
|
||||
next_path = request.GET.get("next_path")
|
||||
if next_path:
|
||||
request.session["next_path"] = str(next_path)
|
||||
request.session["next_path"] = str(validate_next_path(next_path))
|
||||
|
||||
# Check instance configuration
|
||||
instance = Instance.objects.first()
|
||||
|
|
@ -35,7 +35,7 @@ class GitLabOauthInitiateEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -49,7 +49,7 @@ class GitLabOauthInitiateEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -81,7 +81,7 @@ class GitLabCallbackEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class GitLabCallbackEndpoint(View):
|
|||
user_login(request=request, user=user, is_app=True)
|
||||
# Get the redirection path
|
||||
if next_path:
|
||||
path = next_path
|
||||
path = str(validate_next_path(next_path))
|
||||
else:
|
||||
path = get_redirection_path(user=user)
|
||||
# redirect to referer path
|
||||
|
|
@ -103,6 +103,6 @@ class GitLabCallbackEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from plane.authentication.adapter.error import (
|
|||
AuthenticationException,
|
||||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
class GoogleOauthInitiateEndpoint(View):
|
||||
def get(self, request):
|
||||
|
|
@ -36,7 +36,7 @@ class GoogleOauthInitiateEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -51,7 +51,7 @@ class GoogleOauthInitiateEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -72,7 +72,7 @@ class GoogleCallbackEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
if not code:
|
||||
|
|
@ -82,7 +82,7 @@ class GoogleCallbackEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = next_path
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
try:
|
||||
|
|
@ -95,11 +95,11 @@ class GoogleCallbackEndpoint(View):
|
|||
# Get the redirection path
|
||||
path = get_redirection_path(user=user)
|
||||
# redirect to referer path
|
||||
url = urljoin(base_host, str(next_path) if next_path else path)
|
||||
url = urljoin(base_host, str(validate_next_path(next_path)) if next_path else path)
|
||||
return HttpResponseRedirect(url)
|
||||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(base_host, "?" + urlencode(params))
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from plane.authentication.adapter.error import (
|
|||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
from plane.authentication.rate_limit import AuthenticationThrottle
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
|
||||
class MagicGenerateEndpoint(APIView):
|
||||
|
|
@ -43,14 +44,13 @@ class MagicGenerateEndpoint(APIView):
|
|||
)
|
||||
return Response(exc.get_error_dict(), status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
origin = request.META.get("HTTP_ORIGIN", "/")
|
||||
email = request.data.get("email", "").strip().lower()
|
||||
try:
|
||||
validate_email(email)
|
||||
adapter = MagicCodeProvider(request=request, key=email)
|
||||
key, token = adapter.initiate()
|
||||
# If the smtp is configured send through here
|
||||
magic_link.delay(email, key, token, origin)
|
||||
magic_link.delay(email, key, token)
|
||||
return Response({"key": str(key)}, status=status.HTTP_200_OK)
|
||||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
|
|
@ -73,7 +73,7 @@ class MagicSignInEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -89,7 +89,7 @@ class MagicSignInEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -122,7 +122,7 @@ class MagicSignInEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "sign-in?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -145,7 +145,7 @@ class MagicSignUpEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -159,7 +159,7 @@ class MagicSignUpEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
@ -177,7 +177,7 @@ class MagicSignUpEndpoint(View):
|
|||
user_login(request=request, user=user, is_app=True)
|
||||
# Get the redirection path
|
||||
if next_path:
|
||||
path = str(next_path)
|
||||
path = str(validate_next_path(next_path))
|
||||
else:
|
||||
path = get_redirection_path(user=user)
|
||||
# redirect to referer path
|
||||
|
|
@ -187,7 +187,7 @@ class MagicSignUpEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = urljoin(
|
||||
base_host(request=request, is_app=True), "?" + urlencode(params)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ class ForgotPasswordEndpoint(APIView):
|
|||
if user:
|
||||
# Get the reset token for user
|
||||
uidb64, token = generate_password_token(user=user)
|
||||
current_site = request.META.get("HTTP_ORIGIN")
|
||||
current_site = base_host(request=request, is_app=True)
|
||||
# send the forgot password email
|
||||
forgot_password.delay(
|
||||
user.first_name, user.email, uidb64, token, current_site
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from plane.authentication.adapter.error import (
|
|||
AUTHENTICATION_ERROR_CODES,
|
||||
AuthenticationException,
|
||||
)
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
|
||||
class SignInAuthSpaceEndpoint(View):
|
||||
|
|
@ -32,7 +33,7 @@ class SignInAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ class SignInAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -67,7 +68,7 @@ class SignInAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -82,7 +83,7 @@ class SignInAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -99,7 +100,7 @@ class SignInAuthSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -117,7 +118,7 @@ class SignUpAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -135,7 +136,7 @@ class SignUpAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
# Validate the email
|
||||
|
|
@ -151,7 +152,7 @@ class SignUpAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ class SignUpAuthSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -183,6 +184,6 @@ class SignUpAuthSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from plane.authentication.adapter.error import (
|
|||
AUTHENTICATION_ERROR_CODES,
|
||||
AuthenticationException,
|
||||
)
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
|
||||
class GitHubOauthInitiateSpaceEndpoint(View):
|
||||
|
|
@ -34,7 +35,7 @@ class GitHubOauthInitiateSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -66,7 +67,7 @@ class GitHubCallbackSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -77,7 +78,7 @@ class GitHubCallbackSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -93,6 +94,6 @@ class GitHubCallbackSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from plane.authentication.adapter.error import (
|
|||
AUTHENTICATION_ERROR_CODES,
|
||||
AuthenticationException,
|
||||
)
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
|
||||
class GitLabOauthInitiateSpaceEndpoint(View):
|
||||
|
|
@ -34,7 +35,7 @@ class GitLabOauthInitiateSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -66,7 +67,7 @@ class GitLabCallbackSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -77,7 +78,7 @@ class GitLabCallbackSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -93,6 +94,6 @@ class GitLabCallbackSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from plane.authentication.adapter.error import (
|
|||
AuthenticationException,
|
||||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
|
||||
class GoogleOauthInitiateSpaceEndpoint(View):
|
||||
|
|
@ -33,7 +34,7 @@ class GoogleOauthInitiateSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ class GoogleOauthInitiateSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -65,7 +66,7 @@ class GoogleCallbackSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
if not code:
|
||||
|
|
@ -75,7 +76,7 @@ class GoogleCallbackSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = next_path
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
try:
|
||||
|
|
@ -89,6 +90,6 @@ class GoogleCallbackSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from plane.authentication.adapter.error import (
|
|||
AuthenticationException,
|
||||
AUTHENTICATION_ERROR_CODES,
|
||||
)
|
||||
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
class MagicGenerateSpaceEndpoint(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
|
|
@ -38,14 +38,14 @@ class MagicGenerateSpaceEndpoint(APIView):
|
|||
)
|
||||
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", "").strip().lower()
|
||||
try:
|
||||
validate_email(email)
|
||||
adapter = MagicCodeProvider(request=request, key=email)
|
||||
key, token = adapter.initiate()
|
||||
# If the smtp is configured send through here
|
||||
magic_link.delay(email, key, token, origin)
|
||||
magic_link.delay(email, key, token)
|
||||
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)
|
||||
|
|
@ -67,7 +67,7 @@ class MagicSignInSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ class MagicSignInSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -121,7 +121,7 @@ class MagicSignUpSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
# Existing User
|
||||
|
|
@ -134,7 +134,7 @@ class MagicSignUpSpaceEndpoint(View):
|
|||
)
|
||||
params = exc.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
|
@ -152,6 +152,6 @@ class MagicSignUpSpaceEndpoint(View):
|
|||
except AuthenticationException as e:
|
||||
params = e.get_error_dict()
|
||||
if next_path:
|
||||
params["next_path"] = str(next_path)
|
||||
params["next_path"] = str(validate_next_path(next_path))
|
||||
url = f"{base_host(request=request, is_space=True)}?{urlencode(params)}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ class ForgotPasswordSpaceEndpoint(APIView):
|
|||
if user:
|
||||
# Get the reset token for user
|
||||
uidb64, token = generate_password_token(user=user)
|
||||
current_site = request.META.get("HTTP_ORIGIN")
|
||||
current_site = base_host(request=request, is_space=True)
|
||||
# send the forgot password email
|
||||
forgot_password.delay(
|
||||
user.first_name, user.email, uidb64, token, current_site
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from django.utils import timezone
|
|||
# Module imports
|
||||
from plane.authentication.utils.host import base_host, user_ip
|
||||
from plane.db.models import User
|
||||
from plane.utils.path_validator import validate_next_path
|
||||
|
||||
|
||||
class SignOutAuthSpaceEndpoint(View):
|
||||
|
|
@ -21,8 +22,8 @@ class SignOutAuthSpaceEndpoint(View):
|
|||
user.save()
|
||||
# Log the user out
|
||||
logout(request)
|
||||
url = f"{base_host(request=request, is_space=True)}{next_path}"
|
||||
url = f"{base_host(request=request, is_space=True)}{str(validate_next_path(next_path)) if next_path else ''}"
|
||||
return HttpResponseRedirect(url)
|
||||
except Exception:
|
||||
url = f"{base_host(request=request, is_space=True)}{next_path}"
|
||||
url = f"{base_host(request=request, is_space=True)}{str(validate_next_path(next_path)) if next_path else ''}"
|
||||
return HttpResponseRedirect(url)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from plane.utils.exception_logger import log_exception
|
|||
|
||||
|
||||
@shared_task
|
||||
def magic_link(email, key, token, current_site):
|
||||
def magic_link(email, key, token):
|
||||
try:
|
||||
(
|
||||
EMAIL_HOST,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ from plane.authentication.adapter.error import (
|
|||
AUTHENTICATION_ERROR_CODES,
|
||||
AuthenticationException,
|
||||
)
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
|
||||
|
||||
class InstanceAdminEndpoint(BaseAPIView):
|
||||
|
|
@ -217,7 +218,7 @@ class InstanceAdminSignUpEndpoint(View):
|
|||
user.is_active = True
|
||||
user.last_active = timezone.now()
|
||||
user.last_login_time = timezone.now()
|
||||
user.last_login_ip = request.META.get("REMOTE_ADDR")
|
||||
user.last_login_ip = get_client_ip(request=request)
|
||||
user.last_login_uagent = request.META.get("HTTP_USER_AGENT")
|
||||
user.token_updated_at = timezone.now()
|
||||
user.save()
|
||||
|
|
@ -344,7 +345,7 @@ class InstanceAdminSignInEndpoint(View):
|
|||
user.is_active = True
|
||||
user.last_active = timezone.now()
|
||||
user.last_login_time = timezone.now()
|
||||
user.last_login_ip = request.META.get("REMOTE_ADDR")
|
||||
user.last_login_ip = get_client_ip(request=request)
|
||||
user.last_login_uagent = request.META.get("HTTP_USER_AGENT")
|
||||
user.token_updated_at = timezone.now()
|
||||
user.save()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Module imports
|
||||
from plane.db.models import APIActivityLog
|
||||
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
|
||||
class APITokenLogMiddleware:
|
||||
def __init__(self, get_response):
|
||||
|
|
@ -28,7 +29,7 @@ class APITokenLogMiddleware:
|
|||
response.content.decode("utf-8") if response.content else None
|
||||
),
|
||||
response_code=response.status_code,
|
||||
ip_address=request.META.get("REMOTE_ADDR", None),
|
||||
ip_address=get_client_ip(request=request),
|
||||
user_agent=request.META.get("HTTP_USER_AGENT", None),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ SECRET_KEY = os.environ.get("SECRET_KEY", get_random_secret_key())
|
|||
DEBUG = int(os.environ.get("DEBUG", "0"))
|
||||
|
||||
# Allowed Hosts
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "*").split(",")
|
||||
|
||||
# Application definition
|
||||
INSTALLED_APPS = [
|
||||
|
|
@ -314,7 +314,7 @@ ADMIN_BASE_URL = os.environ.get("ADMIN_BASE_URL", None)
|
|||
SPACE_BASE_URL = os.environ.get("SPACE_BASE_URL", None)
|
||||
APP_BASE_URL = os.environ.get("APP_BASE_URL")
|
||||
LIVE_BASE_URL = os.environ.get("LIVE_BASE_URL")
|
||||
|
||||
WEB_URL = os.environ.get("WEB_URL")
|
||||
|
||||
HARD_DELETE_AFTER_DAYS = int(os.environ.get("HARD_DELETE_AFTER_DAYS", 60))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
# Python imports
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
# Django imports
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.http import HttpRequest
|
||||
|
||||
# Third party imports
|
||||
from rest_framework.request import Request
|
||||
|
||||
def base_host(request, is_admin=False, is_space=False, is_app=False):
|
||||
# Module imports
|
||||
from plane.utils.ip_address import get_client_ip
|
||||
|
||||
def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space: bool = False, is_app: bool = False) -> str:
|
||||
"""Utility function to return host / origin from the request"""
|
||||
# Calculate the base origin from request
|
||||
base_origin = str(
|
||||
request.META.get("HTTP_ORIGIN")
|
||||
or f"{urlsplit(request.META.get('HTTP_REFERER')).scheme}://{urlsplit(request.META.get('HTTP_REFERER')).netloc}"
|
||||
or f"""{"https" if request.is_secure() else "http"}://{request.get_host()}"""
|
||||
)
|
||||
base_origin = settings.WEB_URL or settings.APP_BASE_URL
|
||||
|
||||
if not base_origin:
|
||||
raise ImproperlyConfigured("APP_BASE_URL or WEB_URL is not set")
|
||||
|
||||
# Admin redirections
|
||||
if is_admin:
|
||||
|
|
@ -38,5 +41,5 @@ def base_host(request, is_admin=False, is_space=False, is_app=False):
|
|||
return base_origin
|
||||
|
||||
|
||||
def user_ip(request):
|
||||
return str(request.META.get("REMOTE_ADDR"))
|
||||
def user_ip(request: Request | HttpRequest) -> str:
|
||||
return get_client_ip(request=request)
|
||||
|
|
|
|||
21
apiserver/plane/utils/path_validator.py
Normal file
21
apiserver/plane/utils/path_validator.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Python imports
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
def validate_next_path(next_path: str) -> str:
|
||||
"""Validates that next_path is a valid path and extracts only the path component."""
|
||||
parsed_url = urlparse(next_path)
|
||||
|
||||
# Ensure next_path is not an absolute URL
|
||||
if parsed_url.scheme or parsed_url.netloc:
|
||||
next_path = parsed_url.path # Extract only the path component
|
||||
|
||||
# Ensure it starts with a forward slash (indicating a valid relative path)
|
||||
if not next_path.startswith("/"):
|
||||
return ""
|
||||
|
||||
# Ensure it does not contain dangerous path traversal sequences
|
||||
if ".." in next_path:
|
||||
return ""
|
||||
|
||||
return next_path
|
||||
|
|
@ -51,6 +51,7 @@ x-app-env: &app-env
|
|||
API_KEY_RATE_LIMIT: ${API_KEY_RATE_LIMIT:-60/minute}
|
||||
MINIO_ENDPOINT_SSL: ${MINIO_ENDPOINT_SSL:-0}
|
||||
|
||||
|
||||
services:
|
||||
web:
|
||||
image: ${DOCKERHUB_USER:-makeplane}/plane-frontend:${APP_RELEASE:-stable}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue