kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
269 wiersze
9.1 KiB
Python
269 wiersze
9.1 KiB
Python
import logging
|
|
from django.core import mail
|
|
from django.conf import settings
|
|
from django.db import transaction
|
|
from django.dispatch import receiver
|
|
|
|
from funkwhale_api.common import channels
|
|
from funkwhale_api.common import preferences
|
|
from funkwhale_api.common import utils
|
|
from funkwhale_api.taskapp import celery
|
|
from funkwhale_api.federation import utils as federation_utils
|
|
from funkwhale_api.users import models as users_models
|
|
|
|
from . import models
|
|
from . import signals
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@receiver(signals.report_created)
|
|
def broadcast_report_created(report, **kwargs):
|
|
from . import serializers
|
|
|
|
channels.group_send(
|
|
"admin.moderation",
|
|
{
|
|
"type": "event.send",
|
|
"text": "",
|
|
"data": {
|
|
"type": "report.created",
|
|
"report": serializers.ReportSerializer(report).data,
|
|
"unresolved_count": models.Report.objects.filter(
|
|
is_handled=False
|
|
).count(),
|
|
},
|
|
},
|
|
)
|
|
|
|
|
|
@receiver(signals.report_created)
|
|
def trigger_moderator_email(report, **kwargs):
|
|
if settings.MODERATION_EMAIL_NOTIFICATIONS_ENABLED:
|
|
utils.on_commit(send_new_report_email_to_moderators.delay, report_id=report.pk)
|
|
|
|
|
|
def get_moderators():
|
|
moderators = users_models.User.objects.filter(
|
|
is_active=True, permission_moderation=True
|
|
)
|
|
if not moderators:
|
|
# we fallback on superusers
|
|
moderators = users_models.User.objects.filter(is_superuser=True)
|
|
moderators = sorted(moderators, key=lambda m: m.pk)
|
|
return moderators
|
|
|
|
|
|
@celery.app.task(name="moderation.send_new_report_email_to_moderators")
|
|
@celery.require_instance(
|
|
models.Report.objects.select_related("submitter").filter(is_handled=False), "report"
|
|
)
|
|
def send_new_report_email_to_moderators(report):
|
|
moderators = get_moderators()
|
|
submitter_repr = (
|
|
report.submitter.full_username if report.submitter else report.submitter_email
|
|
)
|
|
subject = "[{} moderation - {}] New report from {}".format(
|
|
settings.FUNKWHALE_HOSTNAME, report.get_type_display(), submitter_repr
|
|
)
|
|
detail_url = federation_utils.full_url(
|
|
"/manage/moderation/reports/{}".format(report.uuid)
|
|
)
|
|
unresolved_reports_url = federation_utils.full_url(
|
|
"/manage/moderation/reports?q=resolved:no"
|
|
)
|
|
unresolved_reports = models.Report.objects.filter(is_handled=False).count()
|
|
body = [
|
|
'{} just submitted a report in the "{}" category.'.format(
|
|
submitter_repr, report.get_type_display()
|
|
),
|
|
"",
|
|
"Reported object: {} - {}".format(
|
|
report.target._meta.verbose_name.title(), str(report.target)
|
|
),
|
|
]
|
|
if hasattr(report.target, "get_absolute_url"):
|
|
body.append(
|
|
"Open public page: {}".format(
|
|
federation_utils.full_url(report.target.get_absolute_url())
|
|
)
|
|
)
|
|
if hasattr(report.target, "get_moderation_url"):
|
|
body.append(
|
|
"Open moderation page: {}".format(
|
|
federation_utils.full_url(report.target.get_moderation_url())
|
|
)
|
|
)
|
|
if report.summary:
|
|
body += ["", "Report content:", "", report.summary]
|
|
|
|
body += [
|
|
"",
|
|
"- To handle this report, please visit {}".format(detail_url),
|
|
"- To view all unresolved reports (currently {}), please visit {}".format(
|
|
unresolved_reports, unresolved_reports_url
|
|
),
|
|
"",
|
|
"—",
|
|
"",
|
|
"You are receiving this email because you are a moderator for {}.".format(
|
|
settings.FUNKWHALE_HOSTNAME
|
|
),
|
|
]
|
|
|
|
for moderator in moderators:
|
|
if not moderator.email:
|
|
logger.warning("Moderator %s has no email configured", moderator.username)
|
|
continue
|
|
mail.send_mail(
|
|
subject,
|
|
message="\n".join(body),
|
|
recipient_list=[moderator.email],
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
)
|
|
|
|
|
|
@celery.app.task(name="moderation.user_request_handle")
|
|
@celery.require_instance(
|
|
models.UserRequest.objects.select_related("submitter"), "user_request"
|
|
)
|
|
@transaction.atomic
|
|
def user_request_handle(user_request, new_status, old_status=None):
|
|
if user_request.status != new_status:
|
|
logger.warn(
|
|
"User request %s was handled before asynchronous tasks run", user_request.pk
|
|
)
|
|
return
|
|
|
|
if user_request.type == "signup" and new_status == "pending" and old_status is None:
|
|
notify_mods_signup_request_pending(user_request)
|
|
broadcast_user_request_created(user_request)
|
|
elif user_request.type == "signup" and new_status == "approved":
|
|
user_request.submitter.user.is_active = True
|
|
user_request.submitter.user.save(update_fields=["is_active"])
|
|
notify_submitter_signup_request_approved(user_request)
|
|
elif user_request.type == "signup" and new_status == "refused":
|
|
notify_submitter_signup_request_refused(user_request)
|
|
|
|
|
|
def broadcast_user_request_created(user_request):
|
|
from funkwhale_api.manage import serializers as manage_serializers
|
|
|
|
channels.group_send(
|
|
"admin.moderation",
|
|
{
|
|
"type": "event.send",
|
|
"text": "",
|
|
"data": {
|
|
"type": "user_request.created",
|
|
"user_request": manage_serializers.ManageUserRequestSerializer(
|
|
user_request
|
|
).data,
|
|
"pending_count": models.UserRequest.objects.filter(
|
|
status="pending"
|
|
).count(),
|
|
},
|
|
},
|
|
)
|
|
|
|
|
|
def notify_mods_signup_request_pending(obj):
|
|
moderators = get_moderators()
|
|
submitter_repr = obj.submitter.preferred_username
|
|
subject = "[{} moderation] New sign-up request from {}".format(
|
|
settings.FUNKWHALE_HOSTNAME, submitter_repr
|
|
)
|
|
detail_url = federation_utils.full_url(
|
|
"/manage/moderation/requests/{}".format(obj.uuid)
|
|
)
|
|
unresolved_requests_url = federation_utils.full_url(
|
|
"/manage/moderation/requests?q=status:pending"
|
|
)
|
|
unresolved_requests = models.UserRequest.objects.filter(status="pending").count()
|
|
body = [
|
|
"{} wants to register on your pod. You need to review their request before they can use the service.".format(
|
|
submitter_repr
|
|
),
|
|
"",
|
|
"- To handle this request, please visit {}".format(detail_url),
|
|
"- To view all unresolved requests (currently {}), please visit {}".format(
|
|
unresolved_requests, unresolved_requests_url
|
|
),
|
|
"",
|
|
"—",
|
|
"",
|
|
"You are receiving this email because you are a moderator for {}.".format(
|
|
settings.FUNKWHALE_HOSTNAME
|
|
),
|
|
]
|
|
|
|
for moderator in moderators:
|
|
if not moderator.email:
|
|
logger.warning("Moderator %s has no email configured", moderator.username)
|
|
continue
|
|
mail.send_mail(
|
|
subject,
|
|
message="\n".join(body),
|
|
recipient_list=[moderator.email],
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
)
|
|
|
|
|
|
def notify_submitter_signup_request_approved(user_request):
|
|
submitter_repr = user_request.submitter.preferred_username
|
|
submitter_email = user_request.submitter.user.email
|
|
if not submitter_email:
|
|
logger.warning("User %s has no email configured", submitter_repr)
|
|
return
|
|
subject = "Welcome to {}, {}!".format(settings.FUNKWHALE_HOSTNAME, submitter_repr)
|
|
login_url = federation_utils.full_url("/login")
|
|
body = [
|
|
"Hi {} and welcome,".format(submitter_repr),
|
|
"",
|
|
"Our moderation team has approved your account request and you can now start "
|
|
"using the service. Please visit {} to get started.".format(login_url),
|
|
"",
|
|
"Before your first login, you may need to verify your email address if you didn't already.",
|
|
]
|
|
|
|
mail.send_mail(
|
|
subject,
|
|
message="\n".join(body),
|
|
recipient_list=[submitter_email],
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
)
|
|
|
|
|
|
def notify_submitter_signup_request_refused(user_request):
|
|
submitter_repr = user_request.submitter.preferred_username
|
|
submitter_email = user_request.submitter.user.email
|
|
if not submitter_email:
|
|
logger.warning("User %s has no email configured", submitter_repr)
|
|
return
|
|
subject = "Your account request at {} was refused".format(
|
|
settings.FUNKWHALE_HOSTNAME
|
|
)
|
|
body = [
|
|
"Hi {},".format(submitter_repr),
|
|
"",
|
|
"You recently submitted an account request on our service. However, our "
|
|
"moderation team has refused it, and as a result, you won't be able to use "
|
|
"the service.",
|
|
]
|
|
|
|
instance_contact_email = preferences.get("instance__contact_email")
|
|
if instance_contact_email:
|
|
body += [
|
|
"",
|
|
"If you think this is a mistake, please contact our team at {}.".format(
|
|
instance_contact_email
|
|
),
|
|
]
|
|
|
|
mail.send_mail(
|
|
subject,
|
|
message="\n".join(body),
|
|
recipient_list=[submitter_email],
|
|
from_email=settings.DEFAULT_FROM_EMAIL,
|
|
)
|