diff --git a/BackEnd/administration/serializers.py b/BackEnd/administration/serializers.py index f306660ff..baf85ea34 100644 --- a/BackEnd/administration/serializers.py +++ b/BackEnd/administration/serializers.py @@ -1,13 +1,18 @@ +from django.contrib.auth import get_user_model from rest_framework import serializers from authentication.models import CustomUser from profiles.models import ( Profile, Region, ) +from utils.administration.create_password import generate_password +from utils.administration.send_email import send_email_about_admin_registration from .models import AutoModeration, ModerationEmail +User = get_user_model() -class AdminRegionSerialaizer(serializers.ModelSerializer): + +class AdminRegionSerializer(serializers.ModelSerializer): class Meta: model = Region fields = ( @@ -16,6 +21,35 @@ class Meta: ) +class AdminRegistrationSerializer(serializers.Serializer): + email = serializers.EmailField( + write_only=True, + ) + + def validate(self, value): + email = value.get("email").lower() + + if User.objects.filter(email=email).exists(): + raise serializers.ValidationError( + {"email": "Email is already registered"} + ) + + return value + + def create(self, validated_data): + email = validated_data.get("email") + password = generate_password() + admin = User.objects.create( + email=email, + is_staff=True, + is_active=True, + ) + admin.set_password(password) + admin.save() + send_email_about_admin_registration(email, password) + return admin + + class AdminUserListSerializer(serializers.ModelSerializer): class Meta: model = CustomUser @@ -48,7 +82,7 @@ def get_company_name(self, obj) -> bool: class AdminCompanyListSerializer(serializers.ModelSerializer): person = AdminUserDetailSerializer(read_only=True) - regions = AdminRegionSerialaizer(many=True, read_only=True) + regions = AdminRegionSerializer(many=True, read_only=True) class Meta: model = Profile @@ -76,7 +110,7 @@ class AdminCompanyDetailSerializer(serializers.ModelSerializer): activities = serializers.SlugRelatedField( many=True, slug_field="name", read_only=True ) - regions = AdminRegionSerialaizer(many=True, read_only=True) + regions = AdminRegionSerializer(many=True, read_only=True) banner_image = serializers.ImageField( source="banner.image_path", required=False ) diff --git a/BackEnd/administration/templates/administration/email_template.html b/BackEnd/administration/templates/administration/email_template.html new file mode 100644 index 000000000..c69639127 --- /dev/null +++ b/BackEnd/administration/templates/administration/email_template.html @@ -0,0 +1,25 @@ + + + + + + +
+ CRAFTMERGE +

Доброго дня,

+

Ваш пароль для входу на платформу: {{ password }}

+

Посилання для входу: {{ domain }}/login

+ +

З повагою,

+

Команда CraftMerge

+
+ + \ No newline at end of file diff --git a/BackEnd/administration/urls.py b/BackEnd/administration/urls.py index 8935d1414..7a699a1f9 100644 --- a/BackEnd/administration/urls.py +++ b/BackEnd/administration/urls.py @@ -8,6 +8,7 @@ UserDetailView, AutoModerationHoursView, ModerationEmailView, + CreateAdminUserView, ) app_name = "administration" @@ -24,4 +25,5 @@ ), path("email/", ModerationEmailView.as_view(), name="moderation-email"), path("contacts/", ContactsView.as_view(), name="contacts"), + path("admin_create/", CreateAdminUserView.as_view(), name="admin-create"), ] diff --git a/BackEnd/administration/views.py b/BackEnd/administration/views.py index 8399daee3..e2bf80daa 100644 --- a/BackEnd/administration/views.py +++ b/BackEnd/administration/views.py @@ -6,16 +6,14 @@ OpenApiResponse, ) -from rest_framework.permissions import ( - BasePermission, -) from rest_framework.generics import ( ListAPIView, - ListCreateAPIView, RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView, + CreateAPIView, ) +from administration.serializers import AdminRegistrationSerializer from forum.settings import CONTACTS_INFO from administration.serializers import ( AdminCompanyListSerializer, @@ -148,3 +146,14 @@ class ContactsView(View): def get(self, request): return JsonResponse(CONTACTS_INFO) + + +class CreateAdminUserView(CreateAPIView): + """ + View for creating an admin user. + """ + + permission_classes = [ + IsSuperUser, + ] + serializer_class = AdminRegistrationSerializer diff --git a/BackEnd/authentication/serializers.py b/BackEnd/authentication/serializers.py index 121bdb0cb..fd709c477 100644 --- a/BackEnd/authentication/serializers.py +++ b/BackEnd/authentication/serializers.py @@ -13,7 +13,6 @@ from ratelimit.decorators import RateLimitDecorator from ratelimit.exception import RateLimitException - from profiles.models import Profile from validation.validate_password import ( validate_password_long, diff --git a/BackEnd/requirements.txt b/BackEnd/requirements.txt index c59c62de0..d63296259 100644 --- a/BackEnd/requirements.txt +++ b/BackEnd/requirements.txt @@ -20,5 +20,6 @@ drf-spectacular==0.26.5 ratelimit==2.2.1 django-debug-toolbar==4.3.0 celery==5.4.0 +passlib==1.7.4 diff --git a/BackEnd/utils/administration/create_password.py b/BackEnd/utils/administration/create_password.py new file mode 100644 index 000000000..9e22cdf85 --- /dev/null +++ b/BackEnd/utils/administration/create_password.py @@ -0,0 +1,5 @@ +from passlib import pwd + + +def generate_password(): + return pwd.genword() diff --git a/BackEnd/utils/administration/send_email.py b/BackEnd/utils/administration/send_email.py new file mode 100644 index 000000000..a5e7557c4 --- /dev/null +++ b/BackEnd/utils/administration/send_email.py @@ -0,0 +1,33 @@ +from decouple import config +from django.conf import settings +from django.core.mail import EmailMultiAlternatives +from django.template.loader import render_to_string + + +EMAIL_CONTENT_SUBTYPE = "html" +PROTOCOL = "http" +DOMAIN = config("ALLOWED_ENV_HOST") + + +def send_email_about_admin_registration(email, password): + context = { + "protocol": PROTOCOL, + "password": password, + "domain": DOMAIN, + } + + recipient = email + email_body = render_to_string( + "administration/email_template.html", context + ) + email = EmailMultiAlternatives( + subject="Generated password for administrator", + body=email_body, + from_email=settings.EMAIL_HOST_USER, + to=[ + recipient, + ], + ) + + email.content_subtype = EMAIL_CONTENT_SUBTYPE + email.send(fail_silently=False)