From 209d4250765afce3087cf9edf11ab299fdef21a3 Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Wed, 22 Nov 2023 16:08:00 +0530 Subject: [PATCH 1/2] dev: default values for environment variables --- apiserver/plane/app/views/external.py | 8 +-- .../plane/bgtasks/analytic_plot_export.py | 57 +++++++++++++++--- .../plane/bgtasks/email_verification_task.py | 58 ++++++++++++++++--- .../plane/bgtasks/forgot_password_task.py | 54 ++++++++++++++--- .../plane/bgtasks/magic_link_code_task.py | 58 ++++++++++++++++--- .../plane/bgtasks/project_invitation_task.py | 55 +++++++++++++++--- .../bgtasks/workspace_invitation_task.py | 44 +++++++++++--- 7 files changed, 281 insertions(+), 53 deletions(-) diff --git a/apiserver/plane/app/views/external.py b/apiserver/plane/app/views/external.py index 34f21d00e..b9f8a0cf0 100644 --- a/apiserver/plane/app/views/external.py +++ b/apiserver/plane/app/views/external.py @@ -27,8 +27,8 @@ class GPTIntegrationEndpoint(BaseAPIView): # Get the configuration value instance_configuration = InstanceConfiguration.objects.values("key", "value") - api_key = get_configuration_value(instance_configuration, "OPENAI_API_KEY") - gpt_engine = get_configuration_value(instance_configuration, "GPT_ENGINE") + api_key = get_configuration_value(instance_configuration, "OPENAI_API_KEY", os.environ.get("OPENAI_API_KEY")) + gpt_engine = get_configuration_value(instance_configuration, "GPT_ENGINE", os.environ.get("GPT_ENGINE", "gpt-3.5-turbo")) # Check the keys if not api_key or not gpt_engine: @@ -47,10 +47,6 @@ class GPTIntegrationEndpoint(BaseAPIView): final_text = task + "\n" + prompt - instance_configuration = InstanceConfiguration.objects.values("key", "value") - - gpt_engine = get_configuration_value(instance_configuration, "GPT_ENGINE") - client = OpenAI( api_key=api_key, ) diff --git a/apiserver/plane/bgtasks/analytic_plot_export.py b/apiserver/plane/bgtasks/analytic_plot_export.py index 8cccc2299..c67399adf 100644 --- a/apiserver/plane/bgtasks/analytic_plot_export.py +++ b/apiserver/plane/bgtasks/analytic_plot_export.py @@ -1,6 +1,7 @@ # Python imports import csv import io +import os # Django imports from django.core.mail import EmailMultiAlternatives, get_connection @@ -32,7 +33,7 @@ row_mapping = { "priority": "Priority", "estimate": "Estimate", "issue_cycle__cycle_id": "Cycle", - "issue_module__module_id": "Module" + "issue_module__module_id": "Module", } ASSIGNEE_ID = "assignees__id" @@ -51,17 +52,55 @@ def send_export_email(email, slug, csv_buffer): csv_buffer.seek(0) # Configure email connection from the database - instance_configuration = InstanceConfiguration.objects.filter(key__startswith='EMAIL_').values("key", "value") + instance_configuration = InstanceConfiguration.objects.filter( + key__startswith="EMAIL_" + ).values("key", "value") connection = get_connection( - host=get_configuration_value(instance_configuration, "EMAIL_HOST"), - port=int(get_configuration_value(instance_configuration, "EMAIL_PORT", "587")), - username=get_configuration_value(instance_configuration, "EMAIL_HOST_USER"), - password=get_configuration_value(instance_configuration, "EMAIL_HOST_PASSWORD"), - use_tls=bool(get_configuration_value(instance_configuration, "EMAIL_USE_TLS", "1")), - use_ssl=bool(get_configuration_value(instance_configuration, "EMAIL_USE_SSL", "0")), + host=get_configuration_value( + instance_configuration, "EMAIL_HOST", os.environ.get("EMAIL_HOST") + ), + port=int( + get_configuration_value( + instance_configuration, "EMAIL_PORT", os.environ.get("EMAIL_PORT") + ) + ), + username=get_configuration_value( + instance_configuration, + "EMAIL_HOST_USER", + os.environ.get("EMAIL_HOST_USER"), + ), + password=get_configuration_value( + instance_configuration, + "EMAIL_HOST_PASSWORD", + os.environ.get("EMAIL_HOST_PASSWORD"), + ), + use_tls=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_TLS", + os.environ.get("EMAIL_USE_TLS", "1"), + ) + ), + use_ssl=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_SSL", + os.environ.get("EMAIL_USE_SSL", "0"), + ) + ), ) - msg = EmailMultiAlternatives(subject=subject, body=text_content, from_email=get_configuration_value(instance_configuration, "EMAIL_FROM"), to=[email], connection=connection) + msg = EmailMultiAlternatives( + subject=subject, + body=text_content, + from_email=get_configuration_value( + instance_configuration, + "EMAIL_FROM", + os.environ.get("EMAIL_FROM", "Team Plane "), + ), + to=[email], + connection=connection, + ) msg.attach(f"{slug}-analytics.csv", csv_buffer.getvalue()) msg.send(fail_silently=False) diff --git a/apiserver/plane/bgtasks/email_verification_task.py b/apiserver/plane/bgtasks/email_verification_task.py index 3a9f52a68..650b73eac 100644 --- a/apiserver/plane/bgtasks/email_verification_task.py +++ b/apiserver/plane/bgtasks/email_verification_task.py @@ -1,3 +1,6 @@ +# Python imports +import os + # Django imports from django.core.mail import EmailMultiAlternatives, get_connection from django.template.loader import render_to_string @@ -14,9 +17,9 @@ from sentry_sdk import capture_exception from plane.license.models import InstanceConfiguration from plane.license.utils.instance_value import get_configuration_value + @shared_task def email_verification(first_name, email, token, current_site): - try: realtivelink = "/request-email-verification/" + "?token=" + str(token) abs_url = current_site + realtivelink @@ -33,17 +36,56 @@ def email_verification(first_name, email, token, current_site): text_content = strip_tags(html_content) # Configure email connection from the database - instance_configuration = InstanceConfiguration.objects.filter(key__startswith='EMAIL_').values("key", "value") + instance_configuration = InstanceConfiguration.objects.filter( + key__startswith="EMAIL_" + ).values("key", "value") connection = get_connection( - host=get_configuration_value(instance_configuration, "EMAIL_HOST"), - port=int(get_configuration_value(instance_configuration, "EMAIL_PORT", "587")), - username=get_configuration_value(instance_configuration, "EMAIL_HOST_USER"), - password=get_configuration_value(instance_configuration, "EMAIL_HOST_PASSWORD"), - use_tls=bool(get_configuration_value(instance_configuration, "EMAIL_USE_TLS", "1")), + host=get_configuration_value( + instance_configuration, "EMAIL_HOST", os.environ.get("EMAIL_HOST") + ), + port=int( + get_configuration_value( + instance_configuration, "EMAIL_PORT", os.environ.get("EMAIL_PORT") + ) + ), + username=get_configuration_value( + instance_configuration, + "EMAIL_HOST_USER", + os.environ.get("EMAIL_HOST_USER"), + ), + password=get_configuration_value( + instance_configuration, + "EMAIL_HOST_PASSWORD", + os.environ.get("EMAIL_HOST_PASSWORD"), + ), + use_tls=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_TLS", + os.environ.get("EMAIL_USE_TLS", "1"), + ) + ), + use_ssl=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_SSL", + os.environ.get("EMAIL_USE_SSL", "0"), + ) + ), ) # Initiate email alternatives - msg = EmailMultiAlternatives(subject=subject, body=text_content, from_email=get_configuration_value(instance_configuration, "EMAIL_FROM"), to=[email], connection=connection) + msg = EmailMultiAlternatives( + subject=subject, + body=text_content, + from_email=get_configuration_value( + instance_configuration, + "EMAIL_FROM", + os.environ.get("EMAIL_FROM", "Team Plane "), + ), + to=[email], + connection=connection, + ) msg.attach_alternative(html_content, "text/html") msg.send() return diff --git a/apiserver/plane/bgtasks/forgot_password_task.py b/apiserver/plane/bgtasks/forgot_password_task.py index 7eeec3dc4..a2b09cd8d 100644 --- a/apiserver/plane/bgtasks/forgot_password_task.py +++ b/apiserver/plane/bgtasks/forgot_password_task.py @@ -1,3 +1,6 @@ +# Python import +import os + # Django imports from django.core.mail import EmailMultiAlternatives, get_connection from django.template.loader import render_to_string @@ -32,14 +35,51 @@ def forgot_password(first_name, email, uidb64, token, current_site): instance_configuration = InstanceConfiguration.objects.filter(key__startswith='EMAIL_').values("key", "value") connection = get_connection( - host=get_configuration_value(instance_configuration, "EMAIL_HOST"), - port=int(get_configuration_value(instance_configuration, "EMAIL_PORT", "587")), - username=get_configuration_value(instance_configuration, "EMAIL_HOST_USER"), - password=get_configuration_value(instance_configuration, "EMAIL_HOST_PASSWORD"), - use_tls=bool(get_configuration_value(instance_configuration, "EMAIL_USE_TLS", "1")), + host=get_configuration_value( + instance_configuration, "EMAIL_HOST", os.environ.get("EMAIL_HOST") + ), + port=int( + get_configuration_value( + instance_configuration, "EMAIL_PORT", os.environ.get("EMAIL_PORT") + ) + ), + username=get_configuration_value( + instance_configuration, + "EMAIL_HOST_USER", + os.environ.get("EMAIL_HOST_USER"), + ), + password=get_configuration_value( + instance_configuration, + "EMAIL_HOST_PASSWORD", + os.environ.get("EMAIL_HOST_PASSWORD"), + ), + use_tls=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_TLS", + os.environ.get("EMAIL_USE_TLS", "1"), + ) + ), + use_ssl=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_SSL", + os.environ.get("EMAIL_USE_SSL", "0"), + ) + ), + ) + + msg = EmailMultiAlternatives( + subject=subject, + body=text_content, + from_email=get_configuration_value( + instance_configuration, + "EMAIL_FROM", + os.environ.get("EMAIL_FROM", "Team Plane "), + ), + to=[email], + connection=connection, ) - # Initiate email alternatives - msg = EmailMultiAlternatives(subject=subject, body=text_content, from_email=get_configuration_value(instance_configuration, "EMAIL_FROM"), to=[email], connection=connection) msg.attach_alternative(html_content, "text/html") msg.send() return diff --git a/apiserver/plane/bgtasks/magic_link_code_task.py b/apiserver/plane/bgtasks/magic_link_code_task.py index 372cafa6e..da84769f6 100644 --- a/apiserver/plane/bgtasks/magic_link_code_task.py +++ b/apiserver/plane/bgtasks/magic_link_code_task.py @@ -1,3 +1,6 @@ +# Python imports +import os + # Django imports from django.core.mail import EmailMultiAlternatives, get_connection from django.template.loader import render_to_string @@ -12,6 +15,7 @@ from sentry_sdk import capture_exception from plane.license.models import InstanceConfiguration from plane.license.utils.instance_value import get_configuration_value + @shared_task def magic_link(email, key, token, current_site): try: @@ -26,17 +30,55 @@ def magic_link(email, key, token, current_site): text_content = strip_tags(html_content) - instance_configuration = InstanceConfiguration.objects.filter(key__startswith='EMAIL_').values("key", "value") + instance_configuration = InstanceConfiguration.objects.filter( + key__startswith="EMAIL_" + ).values("key", "value") connection = get_connection( - host=get_configuration_value(instance_configuration, "EMAIL_HOST"), - port=int(get_configuration_value(instance_configuration, "EMAIL_PORT", "587")), - username=get_configuration_value(instance_configuration, "EMAIL_HOST_USER"), - password=get_configuration_value(instance_configuration, "EMAIL_HOST_PASSWORD"), - use_tls=bool(get_configuration_value(instance_configuration, "EMAIL_USE_TLS", "1")), + host=get_configuration_value( + instance_configuration, "EMAIL_HOST", os.environ.get("EMAIL_HOST") + ), + port=int( + get_configuration_value( + instance_configuration, "EMAIL_PORT", os.environ.get("EMAIL_PORT") + ) + ), + username=get_configuration_value( + instance_configuration, + "EMAIL_HOST_USER", + os.environ.get("EMAIL_HOST_USER"), + ), + password=get_configuration_value( + instance_configuration, + "EMAIL_HOST_PASSWORD", + os.environ.get("EMAIL_HOST_PASSWORD"), + ), + use_tls=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_TLS", + os.environ.get("EMAIL_USE_TLS", "1"), + ) + ), + use_ssl=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_SSL", + os.environ.get("EMAIL_USE_SSL", "0"), + ) + ), ) - # Initiate email alternatives - msg = EmailMultiAlternatives(subject=subject, body=text_content, from_email=get_configuration_value(instance_configuration, "EMAIL_FROM"), to=[email], connection=connection) + msg = EmailMultiAlternatives( + subject=subject, + body=text_content, + from_email=get_configuration_value( + instance_configuration, + "EMAIL_FROM", + os.environ.get("EMAIL_FROM", "Team Plane "), + ), + to=[email], + connection=connection, + ) msg.attach_alternative(html_content, "text/html") msg.send() return diff --git a/apiserver/plane/bgtasks/project_invitation_task.py b/apiserver/plane/bgtasks/project_invitation_task.py index 9fd3dd904..ca414d46b 100644 --- a/apiserver/plane/bgtasks/project_invitation_task.py +++ b/apiserver/plane/bgtasks/project_invitation_task.py @@ -1,3 +1,6 @@ +# Python import +import os + # Django imports from django.core.mail import EmailMultiAlternatives, get_connection from django.template.loader import render_to_string @@ -46,14 +49,52 @@ def project_invitation(email, project_id, token, current_site, invitor): # Configure email connection from the database instance_configuration = InstanceConfiguration.objects.filter(key__startswith='EMAIL_').values("key", "value") connection = get_connection( - host=get_configuration_value(instance_configuration, "EMAIL_HOST"), - port=int(get_configuration_value(instance_configuration, "EMAIL_PORT", "587")), - username=get_configuration_value(instance_configuration, "EMAIL_HOST_USER"), - password=get_configuration_value(instance_configuration, "EMAIL_HOST_PASSWORD"), - use_tls=bool(get_configuration_value(instance_configuration, "EMAIL_USE_TLS", "1")), + host=get_configuration_value( + instance_configuration, "EMAIL_HOST", os.environ.get("EMAIL_HOST") + ), + port=int( + get_configuration_value( + instance_configuration, "EMAIL_PORT", os.environ.get("EMAIL_PORT") + ) + ), + username=get_configuration_value( + instance_configuration, + "EMAIL_HOST_USER", + os.environ.get("EMAIL_HOST_USER"), + ), + password=get_configuration_value( + instance_configuration, + "EMAIL_HOST_PASSWORD", + os.environ.get("EMAIL_HOST_PASSWORD"), + ), + use_tls=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_TLS", + os.environ.get("EMAIL_USE_TLS", "1"), + ) + ), + use_ssl=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_SSL", + os.environ.get("EMAIL_USE_SSL", "0"), + ) + ), ) - # Initiate email alternatives - msg = EmailMultiAlternatives(subject=subject, body=text_content, from_email=get_configuration_value(instance_configuration, "EMAIL_FROM"), to=[email], connection=connection) + + msg = EmailMultiAlternatives( + subject=subject, + body=text_content, + from_email=get_configuration_value( + instance_configuration, + "EMAIL_FROM", + os.environ.get("EMAIL_FROM", "Team Plane "), + ), + to=[email], + connection=connection, + ) + msg.attach_alternative(html_content, "text/html") msg.send() return diff --git a/apiserver/plane/bgtasks/workspace_invitation_task.py b/apiserver/plane/bgtasks/workspace_invitation_task.py index 767ef07fd..aa527f241 100644 --- a/apiserver/plane/bgtasks/workspace_invitation_task.py +++ b/apiserver/plane/bgtasks/workspace_invitation_task.py @@ -1,3 +1,6 @@ +# Python imports +import os + # Django imports from django.core.mail import EmailMultiAlternatives, get_connection from django.template.loader import render_to_string @@ -55,23 +58,48 @@ def workspace_invitation(email, workspace_id, token, current_site, invitor): key__startswith="EMAIL_" ).values("key", "value") connection = get_connection( - host=get_configuration_value(instance_configuration, "EMAIL_HOST"), - port=int( - get_configuration_value(instance_configuration, "EMAIL_PORT", "587") + host=get_configuration_value( + instance_configuration, "EMAIL_HOST", os.environ.get("EMAIL_HOST") + ), + port=int( + get_configuration_value( + instance_configuration, "EMAIL_PORT", os.environ.get("EMAIL_PORT") + ) + ), + username=get_configuration_value( + instance_configuration, + "EMAIL_HOST_USER", + os.environ.get("EMAIL_HOST_USER"), ), - username=get_configuration_value(instance_configuration, "EMAIL_HOST_USER"), password=get_configuration_value( - instance_configuration, "EMAIL_HOST_PASSWORD" + instance_configuration, + "EMAIL_HOST_PASSWORD", + os.environ.get("EMAIL_HOST_PASSWORD"), ), use_tls=bool( - get_configuration_value(instance_configuration, "EMAIL_USE_TLS", "1") + get_configuration_value( + instance_configuration, + "EMAIL_USE_TLS", + os.environ.get("EMAIL_USE_TLS", "1"), + ) + ), + use_ssl=bool( + get_configuration_value( + instance_configuration, + "EMAIL_USE_SSL", + os.environ.get("EMAIL_USE_SSL", "0"), + ) ), ) - # Initiate email alternatives + msg = EmailMultiAlternatives( subject=subject, body=text_content, - from_email=get_configuration_value(instance_configuration, "EMAIL_FROM"), + from_email=get_configuration_value( + instance_configuration, + "EMAIL_FROM", + os.environ.get("EMAIL_FROM", "Team Plane "), + ), to=[email], connection=connection, ) From 53b1a0a5c66a18f36b2b9da319978e58acf9a545 Mon Sep 17 00:00:00 2001 From: pablohashescobar Date: Wed, 22 Nov 2023 16:22:30 +0530 Subject: [PATCH 2/2] dev: make the user active if he was already part of project member --- apiserver/plane/app/views/project.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apiserver/plane/app/views/project.py b/apiserver/plane/app/views/project.py index 2d616e5a6..f2f48e7c3 100644 --- a/apiserver/plane/app/views/project.py +++ b/apiserver/plane/app/views/project.py @@ -388,7 +388,7 @@ class ProjectInvitationsViewset(BaseViewSet): {"error": "You cannot invite a user with higher role"}, status=status.HTTP_400_BAD_REQUEST, ) - + workspace = Workspace.objects.get(slug=slug) project_invitations = [] @@ -424,7 +424,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 = request.META.get("HTTP_ORIGIN") # Send invitations for invitation in project_invitations: @@ -469,6 +469,13 @@ class UserProjectInvitationsViewset(BaseViewSet): workspace_role = workspace_member.role workspace = workspace_member.workspace + # If the user was already part of workspace + _ = ProjectMember.objects.filter( + workspace__slug=slug, + project_id__in=project_ids, + member=request.user, + ).update(is_active=True) + ProjectMember.objects.bulk_create( [ ProjectMember( @@ -1040,4 +1047,4 @@ class ProjectDeployBoardViewSet(BaseViewSet): project_deploy_board.save() serializer = ProjectDeployBoardSerializer(project_deploy_board) - return Response(serializer.data, status=status.HTTP_200_OK) \ No newline at end of file + return Response(serializer.data, status=status.HTTP_200_OK)