-
Notifications
You must be signed in to change notification settings - Fork 3.6k
feat: added external api endpoints for creating users and adding attachments to issues #5193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6c877ee
4644470
98f23f1
808ff5b
6e95180
acdfb99
62bfa78
6f59aca
f341573
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| from django.urls import path | ||
|
|
||
| from plane.api.views import ( | ||
| WorkspaceMemberAPIEndpoint, | ||
| ) | ||
|
|
||
| urlpatterns = [ | ||
| path( | ||
| "workspaces/<str:slug>/members/", | ||
| WorkspaceMemberAPIEndpoint.as_view(), | ||
| name="users", | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |||
| IssueLinkAPIEndpoint, | ||||
| IssueCommentAPIEndpoint, | ||||
| IssueActivityAPIEndpoint, | ||||
| IssueAttachmentEndpoint, | ||||
| ) | ||||
|
|
||||
| from .cycle import ( | ||||
|
|
@@ -24,4 +25,6 @@ | |||
| ModuleArchiveUnarchiveAPIEndpoint, | ||||
| ) | ||||
|
|
||||
| from .member import WorkspaceMemberAPIEndpoint | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Address the unused import warning for The static analysis tool flagged this import as unused. Ensure it is used or consider removing it. - from .member import WorkspaceMemberAPIEndpointCommittable suggestion
Suggested change
ToolsRuff
|
||||
|
|
||||
| from .inbox import InboxIssueAPIEndpoint | ||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| # Python imports | ||
| import uuid | ||
|
|
||
| # Django imports | ||
| from django.contrib.auth.hashers import make_password | ||
| from django.core.validators import validate_email | ||
| from django.core.exceptions import ValidationError | ||
|
|
||
| # Third Party imports | ||
| from rest_framework.response import Response | ||
| from rest_framework import status | ||
|
|
||
| # Module imports | ||
| from .base import BaseAPIView | ||
| from plane.api.serializers import UserLiteSerializer | ||
| from plane.db.models import ( | ||
| User, | ||
| Workspace, | ||
| Project, | ||
| WorkspaceMember, | ||
| ProjectMember, | ||
| ) | ||
|
|
||
|
|
||
| # API endpoint to get and insert users inside the workspace | ||
| class WorkspaceMemberAPIEndpoint(BaseAPIView): | ||
| # Get all the users that are present inside the workspace | ||
| def get(self, request, slug): | ||
| # Check if the workspace exists | ||
| if not Workspace.objects.filter(slug=slug).exists(): | ||
| return Response( | ||
| {"error": "Provided workspace does not exist"}, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| ) | ||
|
|
||
| # Get the workspace members that are present inside the workspace | ||
| workspace_members = WorkspaceMember.objects.filter( | ||
| workspace__slug=slug | ||
| ) | ||
|
|
||
| # Get all the users that are present inside the workspace | ||
| users = UserLiteSerializer( | ||
| User.objects.filter( | ||
| id__in=workspace_members.values_list("member_id", flat=True) | ||
| ), | ||
| many=True, | ||
| ).data | ||
|
|
||
| return Response(users, status=status.HTTP_200_OK) | ||
|
|
||
| # Insert a new user inside the workspace, and assign the user to the project | ||
| def post(self, request, slug): | ||
| # Check if user with email already exists, and send bad request if it's | ||
| # not present, check for workspace and valid project mandat | ||
| # ------------------- Validation ------------------- | ||
| if ( | ||
| request.data.get("email") is None | ||
| or request.data.get("display_name") is None | ||
| or request.data.get("project_id") is None | ||
| ): | ||
| return Response( | ||
| { | ||
| "error": "Expected email, display_name, workspace_slug, project_id, one or more of the fields are missing." | ||
| }, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| ) | ||
|
|
||
| email = request.data.get("email") | ||
|
|
||
| try: | ||
| validate_email(email) | ||
| except ValidationError: | ||
| return Response( | ||
| {"error": "Invalid email provided"}, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| ) | ||
|
|
||
| workspace = Workspace.objects.filter(slug=slug).first() | ||
| project = Project.objects.filter( | ||
| pk=request.data.get("project_id") | ||
| ).first() | ||
|
|
||
| if not all([workspace, project]): | ||
| return Response( | ||
| {"error": "Provided workspace or project does not exist"}, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| ) | ||
|
|
||
| # Check if user exists | ||
| user = User.objects.filter(email=email).first() | ||
| workspace_member = None | ||
| project_member = None | ||
|
|
||
| if user: | ||
| # Check if user is part of the workspace | ||
| workspace_member = WorkspaceMember.objects.filter( | ||
| workspace=workspace, member=user | ||
| ).first() | ||
| if workspace_member: | ||
| # Check if user is part of the project | ||
| project_member = ProjectMember.objects.filter( | ||
| project=project, member=user | ||
| ).first() | ||
| if project_member: | ||
| return Response( | ||
| { | ||
| "error": "User is already part of the workspace and project" | ||
| }, | ||
| status=status.HTTP_400_BAD_REQUEST, | ||
| ) | ||
|
|
||
| # If user does not exist, create the user | ||
| if not user: | ||
| user = User.objects.create( | ||
| email=email, | ||
| display_name=request.data.get("display_name"), | ||
| first_name=request.data.get("first_name", ""), | ||
| last_name=request.data.get("last_name", ""), | ||
| username=uuid.uuid4().hex, | ||
| password=make_password(uuid.uuid4().hex), | ||
| is_password_autoset=True, | ||
| is_active=False, | ||
| ) | ||
| user.save() | ||
|
|
||
| # Create a workspace member for the user if not already a member | ||
| if not workspace_member: | ||
| workspace_member = WorkspaceMember.objects.create( | ||
| workspace=workspace, | ||
| member=user, | ||
| role=request.data.get("role", 10), | ||
| ) | ||
| workspace_member.save() | ||
|
|
||
| # Create a project member for the user if not already a member | ||
| if not project_member: | ||
| project_member = ProjectMember.objects.create( | ||
| project=project, | ||
| member=user, | ||
| role=request.data.get("role", 10), | ||
| ) | ||
| project_member.save() | ||
|
|
||
| # Serialize the user and return the response | ||
| user_data = UserLiteSerializer(user).data | ||
|
|
||
| return Response(user_data, status=status.HTTP_201_CREATED) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address the unused import warning for
IssueAttachmentEndpoint.The static analysis tool flagged this import as unused. Ensure it is used or consider removing it.
- IssueAttachmentEndpoint,Committable suggestion
Tools
Ruff