Skip to content

Commit

Permalink
added management commands for list setting and confirm settings
Browse files Browse the repository at this point in the history
  • Loading branch information
KlemenSpruk committed Oct 12, 2023
1 parent 375e399 commit bac843a
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 48 deletions.
40 changes: 31 additions & 9 deletions django_project_base/base/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,36 @@ def trigger(self, payload=None, **kwargs):
return
from django_project_base.aws.ses import AwsSes

if (
payload.name == EMAIL_SENDER_ID_SETTING_NAME
and payload.python_pending_value in AwsSes.list_verified_sender_emails()
def confirm(item):
item.value = copy.copy(item.python_pending_value)
item.pending_value = None
item.save(update_fields=["value", "pending_value"])

# not self.user Event is trigerred from management command
if payload.name == EMAIL_SENDER_ID_SETTING_NAME and (
payload.python_pending_value in AwsSes.list_verified_sender_emails() or not self.user
):
payload.value = copy.copy(payload.python_pending_value)
payload.pending_value = None
payload.save(update_fields=["value", "pending_value"])
confirm(payload)
if payload.name == SMS_SENDER_ID_SETTING_NAME:
a = 9
a = 9
print(a)
if not self.user:
confirm(payload)


class ProjectSettingPendingResetEvent(BaseEvent):
def trigger_changed(self, old_state=None, new_state=None, payload=None, **kwargs):
super().trigger_changed(old_state=old_state, new_state=new_state, payload=payload, **kwargs)

def trigger(self, payload=None, **kwargs):
super().trigger(payload, **kwargs)
if not payload:
return
from django_project_base.aws.ses import AwsSes

payload.pending_value = None
payload.save(update_fields=["value", "pending_value"])

if payload.name == EMAIL_SENDER_ID_SETTING_NAME:
if payload.python_pending_value in AwsSes.list_sender_emails():
AwsSes.remove_sender_email(payload.python_pending_value)
if payload.name == SMS_SENDER_ID_SETTING_NAME:
pass
Empty file.
Empty file.
35 changes: 35 additions & 0 deletions django_project_base/management/commands/confirm_setting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import swapper
from django.core.management.base import BaseCommand
from django.shortcuts import get_object_or_404

from django_project_base.base.event import ProjectSettingConfirmedEvent


class Command(BaseCommand):
help = "Confirms project setting. Example: python manage.py confirm_setting 2 email-sender-id"

def add_arguments(self, parser) -> None:
parser.add_argument("project-id", type=str, help="Project identifier")
parser.add_argument("setting-name", type=str, help="Setting name")

def handle(self, *args, **options):
project = get_object_or_404(swapper.load_model("django_project_base", "Project"), pk=str(options["project-id"]))
setting = get_object_or_404(
swapper.load_model("django_project_base", "ProjectSettings"),
project=project,
name=str(options["setting-name"]),
)
ProjectSettingConfirmedEvent(user=None).trigger(payload=setting)
# TODO: send email when owner is known
# SystemEMailNotification(
# message=DjangoProjectBaseMessage(
# subject=f"{__('Project setting confirmed')}",
# body=f"{__('Setting')} {setting.name} {__('in project')} "
# f"{project.name} {__('has been confirmed and is now active.')}",
# footer="",
# content_type=DjangoProjectBaseMessage.PLAIN_TEXT,
# ),
# recipients=[], # TODO: find project owner
# user=None, # TODO: find project owner
# ).send()
return "ok"
34 changes: 34 additions & 0 deletions django_project_base/management/commands/list_pending_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import swapper
from django.core.management.base import BaseCommand
from django.shortcuts import get_object_or_404

from django_project_base.base.event import ProjectSettingConfirmedEvent


class Command(BaseCommand):
help = "Lists pending project settings. Example: python manage.py list_pending_settings 2"

def add_arguments(self, parser) -> None:
parser.add_argument("project-id", type=str, help="Project identifier")

def handle(self, *args, **options):
project = get_object_or_404(swapper.load_model("django_project_base", "Project"), pk=str(options["project-id"]))
setting = get_object_or_404(
swapper.load_model("django_project_base", "ProjectSettings"),
project=project,
name=str(options["setting-name"]),
)
ProjectSettingConfirmedEvent(user=None).trigger(payload=setting)
# TODO: send email when owner is known
# SystemEMailNotification(
# message=DjangoProjectBaseMessage(
# subject=f"{__('Project setting confirmed')}",
# body=f"{__('Setting')} {setting.name} {__('in project')} "
# f"{project.name} {__('has been confirmed and is now active.')}",
# footer="",
# content_type=DjangoProjectBaseMessage.PLAIN_TEXT,
# ),
# recipients=[], # TODO: find project owner
# user=None, # TODO: find project owner
# ).send()
return "ok"
67 changes: 58 additions & 9 deletions django_project_base/rest/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.shortcuts import get_object_or_404
from drf_spectacular.utils import extend_schema, OpenApiResponse
from dynamicforms import fields
from dynamicforms.action import TableAction, TablePosition
from dynamicforms.mixins import DisplayMode
from dynamicforms.serializers import ModelSerializer
from dynamicforms.template_render.layout import Column, Layout, Row
Expand All @@ -21,7 +22,11 @@
from rest_framework.response import Response

from django_project_base.account.middleware import ProjectNotSelectedError
from django_project_base.base.event import ProjectSettingConfirmedEvent, SmsSenderChangedEvent
from django_project_base.base.event import (
ProjectSettingConfirmedEvent,
ProjectSettingPendingResetEvent,
SmsSenderChangedEvent,
)
from django_project_base.base.models import BaseProjectSettings
from django_project_base.constants import EMAIL_SENDER_ID_SETTING_NAME, SMS_SENDER_ID_SETTING_NAME
from django_project_base.utils import get_pk_name
Expand Down Expand Up @@ -176,11 +181,26 @@ class ProjectSettingsSerializer(ModelSerializer):
def __init__(self, *args, is_filter: bool = False, **kwds):
super().__init__(*args, is_filter=is_filter, **kwds)
self.actions.actions = [a for a in self.actions.actions if a.name != "delete"]
self.actions.actions.append(
TableAction(
position=TablePosition.FIELD_END,
label="Reset pending",
name="reset-pending",
field_name="table_value",
icon="refresh-outline",
display_style=dict(
asButton=False,
showIcon=True,
showLabel=False,
),
),
)

id = fields.AutoGeneratedField(display=DisplayMode.HIDDEN)
project = fields.PrimaryKeyRelatedField(
display=DisplayMode.SUPPRESS, queryset=swapper.load_model("django_project_base", "Project").objects.all()
)
pending_value = fields.CharField(display=DisplayMode.SUPPRESS, required=False)

table_value = fields.CharField(
source="value",
Expand Down Expand Up @@ -225,7 +245,17 @@ def to_representation(self, instance, row_data=None):

class Meta:
model = swapper.load_model("django_project_base", "ProjectSettings")
fields = get_pk_name(model), "name", "table_value", "description", "value_type", "reserved", "value", "project"
fields = (
get_pk_name(model),
"name",
"table_value",
"description",
"value_type",
"reserved",
"value",
"project",
"pending_value",
)
layout = Layout(
Row(Column("name")),
Row(Column("value")),
Expand Down Expand Up @@ -317,14 +347,22 @@ def list(self, request, *args, **kwargs):
pk_name = get_pk_name(self.get_serializer_class().Meta.model)
list_response.set_cookie(
"setting-verification",
f"{','.join(list(map(str, pending_settings.values_list(pk_name, flat=True))))}",
f"{'*'.join(list(map(str, pending_settings.values_list(pk_name, flat=True))))}",
expires=24 * 60 * 60,
samesite="Lax",
)
return list_response
list_response.delete_cookie("setting-verification")
return list_response

def _get_pk_from_request(self, request: Request) -> int:
model = self.get_serializer_class().Meta.model
pk_name = get_pk_name(model)
pk = request.data.get(pk_name)
if not pk:
raise ValidationError({pk_name: [gettext("required")]})
return pk

@extend_schema(exclude=True)
@transaction.atomic()
@action(
Expand All @@ -334,10 +372,21 @@ def list(self, request, *args, **kwargs):
url_path="confirm-setting",
)
def confirm_pending_setting(self, request) -> Response:
model = self.get_serializer_class().Meta.model
pk_name = get_pk_name(model)
pk = request.data.get(pk_name)
if not pk:
raise ValidationError({pk_name: [gettext("required")]})
ProjectSettingConfirmedEvent(user=request.user).trigger(payload=get_object_or_404(model, pk=pk))
ProjectSettingConfirmedEvent(user=request.user).trigger(
payload=get_object_or_404(self.get_serializer_class().Meta.model, pk=self._get_pk_from_request(request))
)
return Response()

@extend_schema(exclude=True)
@transaction.atomic()
@action(
detail=False,
methods=["POST"],
url_name="reset-pending",
url_path="reset-pending",
)
def reset_pending_setting(self, request) -> Response:
setting = get_object_or_404(self.get_serializer_class().Meta.model, pk=self._get_pk_from_request(request))
if setting.pending_value:
ProjectSettingPendingResetEvent(user=request.user).trigger(payload=setting)
return Response()
Loading

0 comments on commit bac843a

Please sign in to comment.