Compare commits

...

5 Commits

Author SHA1 Message Date
pablohashescobar
7bb157971d dev: permission check 2023-11-09 18:52:08 +05:30
pablohashescobar
16d26a41f4 dev: update the project template 2023-11-09 18:46:50 +05:30
pablohashescobar
009eec4692 dev: update the domain url 2023-11-09 18:41:13 +05:30
pablohashescobar
1496af99b7 dev: fix project invitation workflow 2023-11-09 18:31:14 +05:30
pablohashescobar
112c418047 dev: project invite workflow 2023-11-09 18:28:12 +05:30
2 changed files with 50 additions and 35 deletions

View File

@ -352,7 +352,17 @@ class InviteProjectEndpoint(BaseAPIView):
def post(self, request, slug, project_id):
email = request.data.get("email", False)
role = request.data.get("role", False)
role = request.data.get("role", 15)
requested_user_role = ProjectMember.objects.get(
workspace__slug=slug, project_id=project_id, member_id=request.user.id
)
if int(role) > int(requested_user_role.role):
return Response(
{"error": "You cannot invite a user with higher role."},
status=status.HTTP_400_BAD_REQUEST,
)
# Check if email is provided
if not email:
@ -361,50 +371,55 @@ class InviteProjectEndpoint(BaseAPIView):
)
validate_email(email)
# Check if user is already a member of workspace
if ProjectMember.objects.filter(
project_id=project_id,
# If the user is also part of workspace directly add him to project
if WorkspaceMember.objects.filter(
member__email=email,
member__is_bot=False,
).exists():
return Response(
{"error": "User is already member of workspace"},
status=status.HTTP_400_BAD_REQUEST,
)
user = User.objects.filter(email=email).first()
if user is None:
token = jwt.encode(
{"email": email, "timestamp": datetime.now().timestamp()},
settings.SECRET_KEY,
algorithm="HS256",
)
project_invitation_obj = ProjectMemberInvite.objects.create(
email=email.strip().lower(),
# Check if user is already a member of project
if ProjectMember.objects.filter(
project_id=project_id,
token=token,
role=role,
)
domain = settings.WEB_URL
project_invitation.delay(email, project_id, token, domain)
member__email=email,
member__is_bot=False,
).exists():
return Response(
{"error": "User is already member of project"},
status=status.HTTP_400_BAD_REQUEST,
)
# Add that user
user = User.objects.get(emai=email)
# Else create the user and return
project_member = ProjectMember.objects.create(
member=user, project_id=project_id, role=role
)
_ = IssueProperty.objects.create(user=user, project_id=project_id)
return Response(
{
"message": "Email sent successfully",
"id": project_invitation_obj.id,
},
status=status.HTTP_200_OK,
ProjectMemberSerializer(project_member).data, status=status.HTTP_200_OK
)
project_member = ProjectMember.objects.create(
member=user, project_id=project_id, role=role
# If the user doesn't exist
token = jwt.encode(
{"email": email, "timestamp": datetime.now().timestamp()},
settings.SECRET_KEY,
algorithm="HS256",
)
_ = IssueProperty.objects.create(user=user, project_id=project_id)
project_invitation_obj = ProjectMemberInvite.objects.create(
email=email.strip().lower(),
project_id=project_id,
token=token,
role=role,
)
domain = f"{request.scheme}://{request.get_host()}"
project_invitation.delay(email, project_id, token, domain)
return Response(
ProjectMemberSerializer(project_member).data, status=status.HTTP_200_OK
{
"message": "Email sent successfully",
"id": project_invitation_obj.id,
},
status=status.HTTP_200_OK,
)

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="format-detection" content="telephone=no">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ Inviter }} invited you to join {{ Workspace-Name }} on Plane</title>
<title>{{ first_name }} invited you to join {{ project_name }} on Plane</title>
<style type="text/css" emogrify="no">#outlook a { padding:0; } .ExternalClass { width:100%; } .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%; } table td { border-collapse: collapse; mso-line-height-rule: exactly; } .editable.image { font-size: 0 !important; line-height: 0 !important; } .nl2go_preheader { display: none !important; mso-hide:all !important; mso-line-height-rule: exactly; visibility: hidden !important; line-height: 0px !important; font-size: 0px !important; } body { width:100% !important; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%; margin:0; padding:0; } img { outline:none; text-decoration:none; -ms-interpolation-mode: bicubic; } a img { border:none; } table { border-collapse:collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; } th { font-weight: normal; text-align: left; } *[class="gmail-fix"] { display: none !important; } </style>
<style type="text/css" emogrify="no"> @media (max-width: 600px) { .gmx-killpill { content: ' \03D1';} } </style>
<style type="text/css" emogrify="no">@media (max-width: 600px) { .gmx-killpill { content: ' \03D1';} .r0-c { box-sizing: border-box !important; text-align: center !important; valign: top !important; width: 320px !important } .r1-o { border-style: solid !important; margin: 0 auto 0 auto !important; width: 320px !important } .r2-i { background-color: #ffffff !important } .r3-c { box-sizing: border-box !important; text-align: center !important; valign: top !important; width: 100% !important } .r4-o { border-style: solid !important; margin: 0 auto 0 auto !important; margin-top: 20px !important; width: 100% !important } .r5-i { background-color: #f8f9fa !important; padding-bottom: 20px !important; padding-left: 10px !important; padding-right: 10px !important; padding-top: 20px !important } .r6-c { box-sizing: border-box !important; display: block !important; valign: top !important; width: 100% !important } .r7-o { border-style: solid !important; width: 100% !important } .r8-i { padding-left: 0px !important; padding-right: 0px !important } .r9-o { border-style: solid !important; margin: 0 auto 0 auto !important; width: 100% !important } .r10-i { padding-bottom: 35px !important; padding-top: 15px !important } .r11-c { box-sizing: border-box !important; text-align: left !important; valign: top !important; width: 100% !important } .r12-o { border-style: solid !important; margin: 0 auto 0 0 !important; width: 100% !important } .r13-i { padding-left: 20px !important; padding-right: 20px !important; padding-top: 0px !important; text-align: center !important } .r14-o { border-style: solid !important; margin: 0 auto 0 auto !important; margin-bottom: 20px !important; margin-top: 20px !important; width: 100% !important } .r15-i { text-align: center !important } .r16-r { background-color: #ffffff !important; border-color: #3f76ff !important; border-radius: 4px !important; border-width: 1px !important; box-sizing: border-box; height: initial !important; padding-bottom: 7px !important; padding-left: 20px !important; padding-right: 20px !important; padding-top: 7px !important; text-align: center !important; width: 100% !important } .r17-i { padding-bottom: 15px !important; padding-left: 20px !important; padding-right: 20px !important; padding-top: 15px !important; text-align: left !important } .r18-i { background-color: #eff2f7 !important; padding-bottom: 20px !important; padding-left: 15px !important; padding-right: 15px !important; padding-top: 20px !important } .r19-i { padding-bottom: 15px !important; padding-top: 15px !important } .r20-i { color: #3b3f44 !important; padding-bottom: 0px !important; padding-top: 0px !important; text-align: center !important } .r21-c { box-sizing: border-box !important; text-align: center !important; width: 100% !important } .r22-c { box-sizing: border-box !important; width: 100% !important } .r23-i { font-size: 0px !important; padding-bottom: 15px !important; padding-left: 65px !important; padding-right: 65px !important; padding-top: 15px !important } .r24-c { box-sizing: border-box !important; width: 32px !important } .r25-o { border-style: solid !important; margin-right: 8px !important; width: 32px !important } .r26-i { padding-bottom: 5px !important; padding-top: 5px !important } .r27-o { border-style: solid !important; margin-right: 0px !important; width: 32px !important } .r28-i { color: #3b3f44 !important; padding-bottom: 15px !important; padding-top: 15px !important; text-align: center !important } .r29-i { padding-bottom: 15px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important } .r30-c { box-sizing: border-box !important; text-align: center !important; valign: top !important; width: 129px !important } .r31-o { border-style: solid !important; margin: 0 auto 0 auto !important; width: 129px !important } body { -webkit-text-size-adjust: none } .nl2go-responsive-hide { display: none } .nl2go-body-table { min-width: unset !important } .mobshow { height: auto !important; overflow: visible !important; max-height: unset !important; visibility: visible !important; border: none !important } .resp-table { display: inline-table !important } .magic-resp { display: table-cell !important } } </style>