def contact_us_emails(sender, **kwargs): """ Whenever a user submits a message using the contact us form this forwards the message to [email protected] with some additional data. """ reply_to = [] cc = [] user_email = kwargs['user_email'] editor_wp_username = kwargs['editor_wp_username'] body = kwargs['body'] reply_to.append(user_email) logger.info( u'Received contact us form submit signal for {editor_wp_username}; ' 'preparing to send email to [email protected].'.format( editor_wp_username=editor_wp_username)) mail_instance = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mail_instance.contact_us_email('*****@*****.**', { 'editor_wp_username': editor_wp_username, 'body': body }) email.extra_headers["Reply-To"] = ", ".join(reply_to) if kwargs['cc']: cc.append(user_email) email.extra_headers["Cc"] = ", ".join(cc) logger.info('Email constructed.') email.send() logger.info(u'Email queued.')
def dump_project(self, user, project): mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) path = "exports/{}/{}-{}.json".format(project.pk, project.slug, self.request.id) storage_path = default_storage.path(path) try: url = default_storage.url(path) with default_storage.open(storage_path, mode="w") as outfile: render_project(project, outfile) except Exception: ctx = { "user": user, "error_subject": _("Error generating project dump"), "error_message": _("Error generating project dump"), "project": project } email = mbuilder.export_error(user, ctx) email.send() logger.error('Error generating dump %s (by %s)', project.slug, user, exc_info=sys.exc_info()) return deletion_date = timezone.now() + datetime.timedelta(seconds=settings.EXPORTS_TTL) ctx = { "url": url, "project": project, "user": user, "deletion_date": deletion_date } email = mbuilder.dump_project(user, ctx) email.send()
def contact_us_emails(sender, **kwargs): """ Whenever a user submits a message using the contact us form this forwards the message to [email protected] with some additional data. """ reply_to = [] cc = [] user_email = kwargs["user_email"] editor_wp_username = kwargs["editor_wp_username"] body = kwargs["body"] reply_to.append(user_email) logger.info( "Received contact us form submit signal for {editor_wp_username}; " "preparing to send email to [email protected].".format( editor_wp_username=editor_wp_username ) ) mail_instance = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mail_instance.contact_us_email( "*****@*****.**", {"editor_wp_username": editor_wp_username, "body": body}, ) email.extra_headers["Reply-To"] = ", ".join(reply_to) if kwargs["cc"]: cc.append(user_email) email.extra_headers["Cc"] = ", ".join(cc) logger.info("Email constructed.") email.send() logger.info("Email queued.")
def password_recovery(self, request): """ Get a token to email for change password via token. --- serializer: AccountRecoverySerializer """ username_or_email = request.data.get('username', None) if not username_or_email: raise WrongArguments(_("Invalid username or email")) try: queryset = User.objects.all() user = queryset.get( Q(username=username_or_email) | Q(email=username_or_email)) except User.DoesNotExist: raise WrongArguments(_("Invalid username or email")) user.token = str(uuid.uuid1()) user.save(update_fields=["token"]) mbuilder = MagicMailBuilder() email = mbuilder.password_recovery( user.email, { "user": user, "base_url": settings.WEBSITE_BASE_URL, }) email.send() return Response( { "success": _("Mail sended successful!"), "email": user.email, }, status=status.HTTP_200_OK)
def send_authorization_emails(sender, instance, **kwargs): """ When access code objects are updated, check if they should trigger an email to a user. """ # The AccessCode should already exist, don't trigger on code creation. if instance.id: orig_code = AccessCode.objects.get(pk=instance.id) # If this code is having an authorization added where it didn't # have one before, we've probably just finalised an application # and therefore want to send an email. if not orig_code.authorization and instance.authorization: base_url = get_current_site(None).domain user_instructions = instance.partner.user_instructions mail_instance = MagicMailBuilder() email = mail_instance.access_code_email( instance.authorization.authorized_user.email, { 'editor_wp_username': instance.authorization.authorized_user.editor.wp_username, 'partner': instance.partner, 'access_code': instance.code, 'user_instructions': user_instructions }) email.send()
def dump_project(self, user, project): mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) path = "exports/{}/{}-{}.json".format(project.pk, project.slug, self.request.id) try: content = ExportRenderer().render(project_to_dict(project), renderer_context={"indent": 4}) content = content.decode('utf-8') content = ContentFile(content) default_storage.save(path, content) url = default_storage.url(path) except Exception: ctx = { "user": user, "error_subject": _("Error generating project dump"), "error_message": _("Error generating project dump"), "project": project } email = mbuilder.export_error(user, ctx) email.send() logger.error('Error generating dump %s (by %s)', project.slug, user, exc_info=sys.exc_info()) return deletion_date = timezone.now() + datetime.timedelta(seconds=settings.EXPORTS_TTL) ctx = { "url": url, "project": project, "user": user, "deletion_date": deletion_date } email = mbuilder.dump_project(user, ctx) email.send()
def dump_project(self, user, project): mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) path = "exports/{}/{}-{}.json".format(project.pk, project.slug, self.request.id) try: content = ExportRenderer().render(project_to_dict(project), renderer_context={"indent": 4}) content = content.decode('utf-8') content = ContentFile(content) default_storage.save(path, content) url = default_storage.url(path) except Exception: ctx = { "user": user, "error_subject": _("Error generating project dump"), "error_message": _("Error generating project dump"), "project": project } email = mbuilder.export_error(user, ctx) email.send() return deletion_date = timezone.now() + datetime.timedelta( seconds=settings.EXPORTS_TTL) ctx = { "url": url, "project": project, "user": user, "deletion_date": deletion_date } email = mbuilder.dump_project(user, ctx) email.send()
def password_recovery(self, request, pk=None): username_or_email = request.DATA.get('username', None) self.check_permissions(request, "password_recovery", None) if not username_or_email: raise exc.WrongArguments(_("Invalid username or email")) try: queryset = models.User.objects.all() user = queryset.get( Q(username=username_or_email) | Q(email=username_or_email)) except models.User.DoesNotExist: raise exc.WrongArguments(_("Invalid username or email")) user.token = str(uuid.uuid1()) user.save(update_fields=["token"]) mbuilder = MagicMailBuilder() email = mbuilder.password_recovery(user.email, {"user": user}) email.send() return Response({ "detail": _("Mail sended successful!"), "email": user.email })
def send_authorization_emails(sender, instance, **kwargs): """ When access code objects are updated, check if they should trigger an email to a user. """ # The AccessCode should already exist, don't trigger on code creation. if instance.id: orig_code = AccessCode.objects.get(pk=instance.id) # If this code is having an authorization added where it didn't # have one before, we've probably just finalised an application # and therefore want to send an email. if not orig_code.authorization and instance.authorization: mail_instance = MagicMailBuilder() email = mail_instance.access_code_email( instance.authorization.user.email, { "editor_wp_username": instance.authorization.user.editor.wp_username, "lang": instance.authorization.user.userprofile.lang, "partner": instance.partner, "access_code": instance.code, "user_instructions": instance.partner.user_instructions, }, ) email.send()
def send_feedback(feedback_entry, extra): support_email = settings.FEEDBACK_EMAIL if support_email: mbuilder = MagicMailBuilder() email = mbuilder.feedback_notification(support_email, {"feedback_entry": feedback_entry, "extra": extra}) email.send()
def send_feedback(feedback_entry, extra): support_email = settings.FEEDBACK_EMAIL if support_email: mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mbuilder.feedback_notification(support_email, {"feedback_entry": feedback_entry, "extra": extra}) email.send()
def post_save(self, object, created=False): super().post_save(object, created=created) if not created: return # Send email only if a new membership is created mbuilder = MagicMailBuilder() email = mbuilder.membership_invitation(object.email, {"membership": object}) email.send()
def _send_notification(self): if self.object: with open(os.path.join(settings.STATIC_ROOT, 'css', 'style.css'), 'r') as css_file: css = css_file.read() context = {'css': css, 'instance': self.object} email = MagicMailBuilder() notification = email.submission_notification( self.object.email, context) notification.send()
def send_public_register_email(user) -> bool: """ Given a user, send public register welcome email message to specified user. """ context = {"user": user} mbuilder = MagicMailBuilder() email = mbuilder.public_register_user(user.email, context) return bool(email.send())
def send_register_email(user) -> bool: """ Given a user, send register welcome email message to specified user. """ cancel_token = get_token_for_user(user, "cancel_account") context = {"user": user, "cancel_token": cancel_token} mbuilder = MagicMailBuilder() email = mbuilder.registered_user(user.email, context) return bool(email.send())
def send_register_email(user) -> bool: """ Given a user, send register welcome email message to specified user. """ cancel_token = get_token_for_user(user, "cancel_account") context = {"user": user, "cancel_token": cancel_token} mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mbuilder.registered_user(user.email, context) return bool(email.send())
def send_private_register_email(user, **kwargs) -> bool: """ Given a user, send private register welcome email message to specified user. """ context = {"user": user} context.update(kwargs) mbuilder = MagicMailBuilder() email = mbuilder.private_register_user(user.email, context) return bool(email.send())
def test_simple_send_email_with_magic_builder_1(self): mails = MagicMailBuilder() email = mails.test_email2('*****@*****.**', {'name': 'foo'}) email.send() model = Message.objects.get() self.assertEqual(email.from_email, model.from_email) self.assertEqual(email.to, model.to_email.split(',')) self.assertEqual(email.subject, model.subject) self.assertEqual(email.body, model.body_text)
def test_simple_send_email_with_magic_builder_1(self): mails = MagicMailBuilder() email = mails.test_email2('*****@*****.**', {'name': 'foo'}) email.send() self.assertEqual(len(mail.outbox), 1) self.assertEqual(Message.objects.count(), 1) self.assertEqual(email.subject, u'Subject2: foo') self.assertEqual(email.body, u"body\n") self.assertEqual(email.alternatives, [(u'<b>Body</b>\n', 'text/html')])
def test_simple_send_email_with_magic_builder_1_with_extra_kwargs(self): mails = MagicMailBuilder() email = mails.test_email2( "*****@*****.**", {"name": "foo"}, from_email="*****@*****.**") email.send() self.assertEqual(len(mail.outbox), 1) self.assertEqual(Message.objects.count(), 1) self.assertEqual(email.subject, 'Subject2: foo') self.assertEqual(email.body, 'body\n') self.assertEqual(email.alternatives, [(u'<b>Body</b>\n', 'text/html')])
def send_register_email(user): """ Given a user, send register welcome email message to specified user. """ context = { "user": user, "base_url": settings.WEBSITE_BASE_URL, } mbuilder = MagicMailBuilder() email = mbuilder.registered_user(user.email, context) return bool(email.send())
def send_feedback(feedback_entry, extra, reply_to=[]): support_email = settings.FEEDBACK_EMAIL if support_email: reply_to.append(support_email) ctx = { "feedback_entry": feedback_entry, "extra": extra } mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mbuilder.feedback_notification(support_email, ctx) email.extra_headers["Reply-To"] = ", ".join(reply_to) email.send()
def load_project_dump(user, dump): mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) try: project = dict_to_project(dump, user.email) except Exception: ctx = { "user": user, "error_subject": "Error loading project dump", "error_message": "Error loading project dump", } email = mbuilder.import_error(user.email, ctx) email.send() return ctx = {"user": user, "project": project} email = mbuilder.load_dump(user.email, ctx) email.send()
def load_project_dump(user, dump): mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) try: project = dict_to_project(dump, user.email) except Exception: ctx = { "user": user, "error_subject": _("Error loading project dump"), "error_message": _("Error loading project dump"), } email = mbuilder.import_error(user, ctx) email.send() return ctx = {"user": user, "project": project} email = mbuilder.load_dump(user, ctx) email.send()
def send_invitation(invitation): """Send an invitation email""" mbuilder = MagicMailBuilder() if invitation.user: template = mbuilder.membership_notification else: template = mbuilder.membership_invitation email = template(invitation.email, {"membership": invitation}) email.send()
def test_contact_us_emails(self, mock_email): factory = RequestFactory() request = factory.post(get_form_target()) request.user = UserFactory() editor = EditorFactory() reply_to = ['*****@*****.**'] cc = ['*****@*****.**'] self.assertEqual(len(mail.outbox), 0) mail_instance = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mail_instance.contact_us_email('*****@*****.**', {'editor_wp_username': editor.wp_username, 'body': 'This is a test email'}) email.extra_headers["Reply-To"] = ", ".join(reply_to) email.extra_headers["Cc"] = ", ".join(cc) email.send() self.assertEqual(len(mail.outbox), 1)
def load_project_dump(user, dump): mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) try: project = dict_to_project(dump, user.email) except Exception: ctx = { "user": user, "error_subject": _("Error loading project dump"), "error_message": _("Error loading project dump"), } email = mbuilder.import_error(user, ctx) email.send() logger.error('Error loading dump %s (by %s)', project.slug, user, exc_info=sys.exc_info()) return ctx = {"user": user, "project": project} email = mbuilder.load_dump(user, ctx) email.send()
def partial_update(self, request, *args, **kwargs): """ We must detect if the user is trying to change his email so we can save that value and generate a token that allows him to validate it in the new email account """ user = self.get_object() self.check_permissions(request, "update", user) ret = super(UsersViewSet, self).partial_update(request, *args, **kwargs) new_email = request.DATA.get('email', None) if new_email is not None: valid_new_email = True duplicated_email = models.User.objects.filter( email=new_email).exists() try: validate_email(new_email) except ValidationError: valid_new_email = False valid_new_email = valid_new_email and new_email != request.user.email if duplicated_email: raise exc.WrongArguments(_("Duplicated email")) elif not valid_new_email: raise exc.WrongArguments(_("Not valid email")) #We need to generate a token for the email request.user.email_token = str(uuid.uuid1()) request.user.new_email = new_email request.user.save(update_fields=["email_token", "new_email"]) mbuilder = MagicMailBuilder( template_mail_cls=InlineCSSTemplateMail) email = mbuilder.change_email(request.user.new_email, { "user": request.user, "lang": request.user.lang }) email.send() return ret
def password_recovery(self, request, pk=None): username_or_email = request.DATA.get('username', None) if not username_or_email: raise exc.WrongArguments(_("Invalid username or email")) try: queryset = User.objects.all() user = queryset.get(Q(username=username_or_email) | Q(email=username_or_email)) except User.DoesNotExist: raise exc.WrongArguments(_("Invalid username or email")) user.token = str(uuid.uuid1()) user.save(update_fields=["token"]) mbuilder = MagicMailBuilder() email = mbuilder.password_recovery(user.email, {"user": user}) email.send() return Response({"detail": _("Mail sended successful!")})
def test_simple_send_email_with_magic_builder_1_with_low_priority(self): mails = MagicMailBuilder() email = mails.test_email2( '*****@*****.**', {'name': 'foo'}, priority=10) email.send() self.assertEqual(len(mail.outbox), 0) self.assertEqual(Message.objects.count(), 1) m1 = Message.objects.get() self.assertEqual(m1.status, Message.STATUS_PENDING) self.assertEqual(m1.priority, 10) core._send_pending_messages() self.assertEqual(len(mail.outbox), 1) self.assertEqual(Message.objects.count(), 1) m2 = Message.objects.get() self.assertEqual(m2.status, Message.STATUS_SENT) self.assertEqual(m2.priority, 10)
def partial_update(self, request, *args, **kwargs): """ We must detect if the user is trying to change his email so we can save that value and generate a token that allows him to validate it in the new email account """ user = self.get_object() self.check_permissions(request, "update", user) ret = super(UsersViewSet, self).partial_update(request, *args, **kwargs) new_email = request.DATA.get('email', None) if new_email is not None: valid_new_email = True duplicated_email = models.User.objects.filter(email = new_email).exists() try: validate_email(new_email) except ValidationError: valid_new_email = False valid_new_email = valid_new_email and new_email != request.user.email if duplicated_email: raise exc.WrongArguments(_("Duplicated email")) elif not valid_new_email: raise exc.WrongArguments(_("Not valid email")) #We need to generate a token for the email request.user.email_token = str(uuid.uuid1()) request.user.new_email = new_email request.user.save(update_fields=["email_token", "new_email"]) mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mbuilder.change_email(request.user.new_email, {"user": request.user, "lang": request.user.lang}) email.send() return ret
def confirm_register(self, request): """ Comfirmation account register. >>> register step required <<< --- parameters: - name: token description: this token is sended to user email, after user registration. required: true type: string paramType: form """ serializer = ConfirmRegisterSerializer(data=request.data) if not serializer.is_valid(): raise WrongArguments(_("Missing arguments")) try: user = User.objects.get(token=serializer.data["token"]) except User.DoesNotExist: raise WrongArguments(_("Token is invalid")) user.is_active = True mbuilder = MagicMailBuilder() cancel_token = get_token_for_user(user, "cancel_account") email = mbuilder.registered_user_confirmation( user.email, { "user": user, "cancel_token": cancel_token, "base_url": settings.WEBSITE_BASE_URL, }) email.send() user.token = None user.save(update_fields=["is_active", "token"]) return Response({ "success": _("Welcome your account has been activated!"), }, status=status.HTTP_200_OK)
def password_recovery(self, request, pk=None): username_or_email = request.DATA.get('username', None) self.check_permissions(request, "password_recovery", None) if not username_or_email: raise exc.WrongArguments(_("Invalid username or email")) try: queryset = models.User.objects.all() user = queryset.get(Q(username=username_or_email) | Q(email=username_or_email)) except models.User.DoesNotExist: raise exc.WrongArguments(_("Invalid username or email")) user.token = str(uuid.uuid1()) user.save(update_fields=["token"]) mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) email = mbuilder.password_recovery(user, {"user": user}) email.send() return response.Ok({"detail": _("Mail sended successful!")})
def handle(self, *args, **options): if len(args) != 1: print("Usage: ./manage.py test_emails <email-address>") return test_email = args[0] mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) # Register email context = {"user": User.objects.all().order_by("?").first(), "cancel_token": "cancel-token"} email = mbuilder.registered_user(test_email, context) email.send() # Membership invitation membership = Membership.objects.order_by("?").filter(user__isnull=True).first() membership.invited_by = User.objects.all().order_by("?").first() membership.invitation_extra_text = "Text example, Text example,\nText example,\n\nText example" context = {"membership": membership} email = mbuilder.membership_invitation(test_email, context) email.send() # Membership notification context = {"membership": Membership.objects.order_by("?").filter(user__isnull=False).first()} email = mbuilder.membership_notification(test_email, context) email.send() # Feedback context = { "feedback_entry": { "full_name": "Test full name", "email": "*****@*****.**", "comment": "Test comment", }, "extra": { "key1": "value1", "key2": "value2", }, } email = mbuilder.feedback_notification(test_email, context) email.send() # Password recovery context = {"user": User.objects.all().order_by("?").first()} email = mbuilder.password_recovery(test_email, context) email.send() # Change email context = {"user": User.objects.all().order_by("?").first()} email = mbuilder.change_email(test_email, context) email.send() # Export/Import emails context = { "user": User.objects.all().order_by("?").first(), "project": Project.objects.all().order_by("?").first(), "error_subject": "Error generating project dump", "error_message": "Error generating project dump", } email = mbuilder.export_error(test_email, context) email.send() context = { "user": User.objects.all().order_by("?").first(), "error_subject": "Error importing project dump", "error_message": "Error importing project dump", } email = mbuilder.import_error(test_email, context) email.send() deletion_date = timezone.now() + datetime.timedelta(seconds=60*60*24) context = { "url": "http://dummyurl.com", "user": User.objects.all().order_by("?").first(), "project": Project.objects.all().order_by("?").first(), "deletion_date": deletion_date, } email = mbuilder.dump_project(test_email, context) email.send() context = { "user": User.objects.all().order_by("?").first(), "project": Project.objects.all().order_by("?").first(), } email = mbuilder.load_dump(test_email, context) email.send() # Notification emails notification_emails = [ ("issues.Issue", "issues/issue-change"), ("issues.Issue", "issues/issue-create"), ("issues.Issue", "issues/issue-delete"), ("tasks.Task", "tasks/task-change"), ("tasks.Task", "tasks/task-create"), ("tasks.Task", "tasks/task-delete"), ("userstories.UserStory", "userstories/userstory-change"), ("userstories.UserStory", "userstories/userstory-create"), ("userstories.UserStory", "userstories/userstory-delete"), ("milestones.Milestone", "milestones/milestone-change"), ("milestones.Milestone", "milestones/milestone-create"), ("milestones.Milestone", "milestones/milestone-delete"), ("wiki.WikiPage", "wiki/wikipage-change"), ("wiki.WikiPage", "wiki/wikipage-create"), ("wiki.WikiPage", "wiki/wikipage-delete"), ] context = { "project": Project.objects.all().order_by("?").first(), "changer": User.objects.all().order_by("?").first(), "history_entries": HistoryEntry.objects.all().order_by("?")[0:5], "user": User.objects.all().order_by("?").first(), } for notification_email in notification_emails: model = get_model(*notification_email[0].split(".")) snapshot = { "subject": "Tests subject", "ref": 123123, "name": "Tests name", "slug": "test-slug" } queryset = model.objects.all().order_by("?") for obj in queryset: end = False entries = get_history_queryset_by_model_instance(obj).filter(is_snapshot=True).order_by("?") for entry in entries: if entry.snapshot: snapshot = entry.snapshot end = True break if end: break context["snapshot"] = snapshot cls = type("InlineCSSTemplateMail", (InlineCSSTemplateMail,), {"name": notification_email[1]}) email = cls() email.send(test_email, context)
def handle(self, *args, **options): if len(args) != 1: print("Usage: ./manage.py test_emails <email-address>") return test_email = args[0] mbuilder = MagicMailBuilder(template_mail_cls=InlineCSSTemplateMail) # Register email context = {"user": User.objects.all().order_by("?").first(), "cancel_token": "cancel-token"} email = mbuilder.registered_user(test_email, context) email.send() # Membership invitation context = {"membership": Membership.objects.order_by("?").filter(user__isnull=True).first()} email = mbuilder.membership_invitation(test_email, context) email.send() # Membership notification context = {"membership": Membership.objects.order_by("?").filter(user__isnull=False).first()} email = mbuilder.membership_notification(test_email, context) email.send() # Feedback context = { "feedback_entry": { "full_name": "Test full name", "email": "*****@*****.**", "comment": "Test comment", }, "extra": { "key1": "value1", "key2": "value2", }, } email = mbuilder.feedback_notification(test_email, context) email.send() # Password recovery context = {"user": User.objects.all().order_by("?").first()} email = mbuilder.password_recovery(test_email, context) email.send() # Change email context = {"user": User.objects.all().order_by("?").first()} email = mbuilder.change_email(test_email, context) email.send() # Notification emails notification_emails = [ "issues/issue-change", "issues/issue-create", "issues/issue-delete", "milestones/milestone-change", "milestones/milestone-create", "milestones/milestone-delete", "projects/project-change", "projects/project-create", "projects/project-delete", "tasks/task-change", "tasks/task-create", "tasks/task-delete", "userstories/userstory-change", "userstories/userstory-create", "userstories/userstory-delete", "wiki/wikipage-change", "wiki/wikipage-create", "wiki/wikipage-delete", ] context = { "snapshot": HistoryEntry.objects.filter(is_snapshot=True).order_by("?")[0].snapshot, "project": Project.objects.all().order_by("?").first(), "changer": User.objects.all().order_by("?").first(), "history_entries": HistoryEntry.objects.all().order_by("?")[0:5], "user": User.objects.all().order_by("?").first(), } for notification_email in notification_emails: cls = type("InlineCSSTemplateMail", (InlineCSSTemplateMail,), {"name": notification_email}) email = cls() email.send(test_email, context)
class UsersViewSet(ModelCrudViewSet): permission_classes = [ UserPermissionSet, ] serializer_class = UserSerializer queryset = User.objects.all() paginate_by = 25 page_size = 25 def list(self, request, *args, **kwargs): """ List of all users """ page = self.paginate_queryset(self.queryset) if page is not None: serializer = self.get_pagination_serializer(page) else: serializer = self.get_serializer(self.queryset, many=True) return Response(serializer.data) def partial_update(self, request, *args, **kwargs): """ Save the user partial updates. We must detect if the user is trying to change his email so we can save that value and generate a token that allows him to validate it in the new email account """ try: current_user = User.objects.get(id=kwargs["pk"]) except Exception, e: raise RequestValidationError(_("User not found")) if current_user != request.user: raise RequestValidationError( _("You cann't change of other users information")) old_email = request.user.email new_email = request.data.get('email', None) if new_email is not None and new_email != old_email: valid_new_email = True duplicated_email = User.objects.filter(email=new_email).exists() try: validate_email(new_email) except ValidationError: valid_new_email = False if duplicated_email: raise WrongArguments( _("This mail is being used by another user")) elif not valid_new_email: raise WrongArguments(_("Not valid email")) # We need to generate a token for the email request.user.email_token = str(uuid.uuid1()) request.user.new_email = new_email request.user.email = old_email request.data["email"] = old_email request.user.save( update_fields=["email_token", "new_email", "email"]) mbuilder = MagicMailBuilder() email = mbuilder.change_email( request.user.email, { "user": request.user, "base_url": settings.WEBSITE_BASE_URL, }) email.send() return super(UsersViewSet, self).partial_update(request, *args, **kwargs)