✨(backend) send email to admins when user ask for access
When a user requests access to a document, an email is sent to the admins and owners of the document.
This commit is contained in:
committed by
Manuel Raynaud
parent
878de08b1e
commit
394f91387d
@@ -36,6 +36,7 @@ from rest_framework.throttling import UserRateThrottle
|
||||
from core import authentication, enums, models
|
||||
from core.services.ai_services import AIService
|
||||
from core.services.collaboration_services import CollaborationService
|
||||
from core.tasks.mail import send_ask_for_access_mail
|
||||
from core.utils import extract_attachments, filter_descendants
|
||||
|
||||
from . import permissions, serializers, utils
|
||||
@@ -1829,12 +1830,14 @@ class DocumentAskForAccessViewSet(
|
||||
status=drf.status.HTTP_400_BAD_REQUEST,
|
||||
)
|
||||
|
||||
models.DocumentAskForAccess.objects.create(
|
||||
ask_for_access = models.DocumentAskForAccess.objects.create(
|
||||
document=document,
|
||||
user=request.user,
|
||||
role=serializer.validated_data["role"],
|
||||
)
|
||||
|
||||
send_ask_for_access_mail.delay(ask_for_access.id)
|
||||
|
||||
return drf.response.Response(status=drf.status.HTTP_201_CREATED)
|
||||
|
||||
@drf.decorators.action(detail=True, methods=["post"])
|
||||
|
||||
@@ -876,8 +876,8 @@ class Document(MP_Node, BaseModel):
|
||||
)
|
||||
|
||||
with override(language):
|
||||
msg_html = render_to_string("mail/html/invitation.html", context)
|
||||
msg_plain = render_to_string("mail/text/invitation.txt", context)
|
||||
msg_html = render_to_string("mail/html/template.html", context)
|
||||
msg_plain = render_to_string("mail/text/template.txt", context)
|
||||
subject = str(subject) # Force translation
|
||||
|
||||
try:
|
||||
@@ -1221,6 +1221,39 @@ class DocumentAskForAccess(BaseModel):
|
||||
)
|
||||
self.delete()
|
||||
|
||||
def send_ask_for_access_email(self, email, language=None):
|
||||
"""
|
||||
Method allowing a user to send an email notification when asking for access to a document.
|
||||
"""
|
||||
|
||||
language = language or get_language()
|
||||
sender = self.user
|
||||
sender_name = sender.full_name or sender.email
|
||||
sender_name_email = (
|
||||
f"{sender.full_name:s} ({sender.email})"
|
||||
if sender.full_name
|
||||
else sender.email
|
||||
)
|
||||
|
||||
with override(language):
|
||||
context = {
|
||||
"title": _("{name} would like access to a document!").format(
|
||||
name=sender_name
|
||||
),
|
||||
"message": _(
|
||||
"{name} would like access to the following document:"
|
||||
).format(name=sender_name_email),
|
||||
}
|
||||
subject = (
|
||||
context["title"]
|
||||
if not self.document.title
|
||||
else _("{name} is asking for access to the document: {title}").format(
|
||||
name=sender_name, title=self.document.title
|
||||
)
|
||||
)
|
||||
|
||||
self.document.send_email(subject, [email], context, language)
|
||||
|
||||
|
||||
class Template(BaseModel):
|
||||
"""HTML and CSS code used for formatting the print around the MarkDown body."""
|
||||
|
||||
0
src/backend/core/tasks/__init__.py
Normal file
0
src/backend/core/tasks/__init__.py
Normal file
24
src/backend/core/tasks/mail.py
Normal file
24
src/backend/core/tasks/mail.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""Send mail using celery task."""
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from core import models
|
||||
|
||||
from impress.celery_app import app
|
||||
|
||||
|
||||
@app.task
|
||||
def send_ask_for_access_mail(ask_for_access_id):
|
||||
"""Send mail using celery task."""
|
||||
# Send email to document owners/admins
|
||||
ask_for_access = models.DocumentAskForAccess.objects.get(id=ask_for_access_id)
|
||||
owner_admin_accesses = models.DocumentAccess.objects.filter(
|
||||
document=ask_for_access.document, role__in=models.PRIVILEGED_ROLES
|
||||
).select_related("user")
|
||||
|
||||
for access in owner_admin_accesses:
|
||||
if access.user and access.user.email:
|
||||
ask_for_access.send_ask_for_access_email(
|
||||
access.user.email,
|
||||
access.user.language or settings.LANGUAGE_CODE,
|
||||
)
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
import uuid
|
||||
|
||||
from django.core import mail
|
||||
|
||||
import pytest
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
@@ -41,13 +43,26 @@ def test_api_documents_ask_for_access_create_invalid_document_id():
|
||||
|
||||
|
||||
def test_api_documents_ask_for_access_create_authenticated():
|
||||
"""Authenticated users should be able to create a document ask for access."""
|
||||
document = DocumentFactory()
|
||||
"""
|
||||
Authenticated users should be able to create a document ask for access.
|
||||
An email should be sent to document owners and admins to notify them.
|
||||
"""
|
||||
owner_user = UserFactory(language="en-us")
|
||||
admin_user = UserFactory(language="fr-fr")
|
||||
document = DocumentFactory(
|
||||
users=[
|
||||
(owner_user, RoleChoices.OWNER),
|
||||
(admin_user, RoleChoices.ADMIN),
|
||||
]
|
||||
)
|
||||
|
||||
user = UserFactory()
|
||||
|
||||
client = APIClient()
|
||||
client.force_login(user)
|
||||
|
||||
assert len(mail.outbox) == 0
|
||||
|
||||
response = client.post(f"/api/v1.0/documents/{document.id}/ask-for-access/")
|
||||
assert response.status_code == 201
|
||||
|
||||
@@ -57,6 +72,30 @@ def test_api_documents_ask_for_access_create_authenticated():
|
||||
role=RoleChoices.READER,
|
||||
).exists()
|
||||
|
||||
# Verify emails were sent to both owner and admin
|
||||
assert len(mail.outbox) == 2
|
||||
|
||||
# Check that emails were sent to the right recipients
|
||||
email_recipients = [email.to[0] for email in mail.outbox]
|
||||
assert owner_user.email in email_recipients
|
||||
assert admin_user.email in email_recipients
|
||||
|
||||
# Check email content for both users
|
||||
for email in mail.outbox:
|
||||
email_content = " ".join(email.body.split())
|
||||
email_subject = " ".join(email.subject.split())
|
||||
|
||||
# Check that the requesting user's name is in the email
|
||||
user_name = user.full_name or user.email
|
||||
assert user_name.lower() in email_content.lower()
|
||||
|
||||
# Check that the subject mentions access request
|
||||
assert "access" in email_subject.lower()
|
||||
|
||||
# Check that the document title is mentioned if it exists
|
||||
if document.title:
|
||||
assert document.title.lower() in email_subject.lower()
|
||||
|
||||
|
||||
def test_api_documents_ask_for_access_create_authenticated_specific_role():
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user