def notify_member(self): """ Notify the request author about the decision that has been made. """ if self.is_granted is None: raise Exception( "The request must have been solved to use this method.") solved_by_bot = self.moderator == get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) message = render_to_string( "member/messages/hat_request_decision.md", { "is_granted": self.is_granted, "hat": self.hat, "comment": self.comment, "solved_by_bot": solved_by_bot, }, ) send_mp( self.moderator, [self.user], _("Casquette « {} »").format(self.hat), "", message, leave=solved_by_bot, hat=get_hat_from_settings("hats_management"), )
def activate_account(request): """Activate an account with a token.""" try: token = request.GET["token"] except KeyError: return redirect(reverse("homepage")) token = get_object_or_404(TokenRegister, token=token) usr = token.user # User can't confirm their request if their account is already active if usr.is_active: return render(request, "member/register/token_already_used.html") # User can't confirm their request if it is too late if datetime.now() > token.date_end: return render(request, "member/register/token_failed.html", {"token": token}) usr.is_active = True usr.save() # Send welcome message bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "member/messages/account_activated.md", { "username": usr.username, "site_name": settings.ZDS_APP["site"]["literal_name"], "library_url": settings.ZDS_APP["site"]["url"] + reverse("publication:list"), "opinions_url": settings.ZDS_APP["site"]["url"] + reverse("opinion:list"), "forums_url": settings.ZDS_APP["site"]["url"] + reverse("cats-forums-list"), }, ) send_mp( bot, [usr], _("Bienvenue sur {}").format(settings.ZDS_APP["site"]["literal_name"]), _("Le manuel du nouveau membre"), msg, send_by_mail=False, leave=True, direct=False, hat=get_hat_from_settings("moderation"), ) token.delete() # Create an alert for the staff if it's a new provider if usr.email: provider = usr.email.split("@")[-1].lower() if ( not NewEmailProvider.objects.filter(provider=provider).exists() and not User.objects.filter(email__iendswith=f"@{provider}").exclude(pk=usr.pk).exists() ): NewEmailProvider.objects.create(user=usr, provider=provider, use=NEW_ACCOUNT) form = LoginForm(initial={"username": usr.username}) return render(request, "member/register/token_success.html", {"usr": usr, "form": form})
def form_valid(self, form): _type = _("de l'article") if self.object.is_tutorial: _type = _("du tutoriel") elif self.object.is_opinion: _type = _("du billet") bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) all_authors_pk = [author.pk for author in self.object.authors.all()] for user in form.cleaned_data["users"]: if user.pk not in all_authors_pk: self.object.authors.add(user) if self.object.validation_private_message: self.object.validation_private_message.add_participant( user) all_authors_pk.append(user.pk) if user != self.request.user: url_index = reverse(self.object.type.lower() + ":find-" + self.object.type.lower(), args=[user.pk]) send_mp( bot, [user], format_lazy("{}{}", _("Ajout à la rédaction "), _type), self.versioned_object.title, render_to_string( "tutorialv2/messages/add_author_pm.md", { "content": self.object, "type": _type, "url": self.object.get_absolute_url(), "index": url_index, "user": user.username, }, ), hat=get_hat_from_settings("validation"), ) UserGallery(gallery=self.object.gallery, user=user, mode=GALLERY_WRITE).save() signals.authors_management.send(sender=self.__class__, content=self.object, performer=self.request.user, author=user, action="add") self.object.save() self.success_url = self.object.get_absolute_url() return super().form_valid(form)
def solve(self, moderator, resolve_reason="", msg_title="", msg_content=""): """Solve the alert and send a private message to the author if a reason is given :param resolve_reason: reason :type resolve_reason: str """ self.resolve_reason = resolve_reason or None if msg_title and msg_content: bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) privatetopic = send_mp( bot, [self.author], msg_title, "", msg_content, send_by_mail=True, hat=get_hat_from_settings("moderation"), ) self.privatetopic = privatetopic self.solved = True self.moderator = moderator self.solved_date = datetime.now() self.save()
def test_reuse_old_notification(self): """ When there already is a read notification for a given content, we reuse it. """ topic = send_mp(author=self.user1, users=[self.user2], title="Testing", subtitle="", text="", leave=False) send_message_mp(self.user2, topic, "", send_by_mail=True) notifications = Notification.objects.get_unread_notifications_of( self.user1) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.first()) self.assertEqual(topic.last_message, notifications.first().content_object) mark_read(topic, self.user1) send_message_mp(self.user2, topic, "", send_by_mail=True) notifications = Notification.objects.filter( subscription__user=self.user1) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.first())
def test_generate_a_notification_after_new_post(self): """ When a user posts on a private topic, we generate a notification for all participants. """ topic = send_mp(author=self.user1, users=[self.user2, self.user3], title="Testing", subtitle="", text="", leave=False) notifications = Notification.objects.get_unread_notifications_of( self.user2) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.first()) self.assertEqual(topic.last_message, notifications.first().content_object) mark_read(topic, self.user2) notifications = Notification.objects.get_unread_notifications_of( self.user2) self.assertEqual(0, len(notifications)) send_message_mp(self.user3, topic, "") notifications = Notification.objects.get_unread_notifications_of( self.user2) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.first()) self.assertEqual(topic.last_message, notifications.first().content_object)
def test_generate_a_notification_when_add_a_participant(self): """ When we add a user to a private topic, we generate a notification for this user at the last message. """ topic = send_mp(author=self.user1, users=[self.user2], title="Testing", subtitle="", text="", leave=False) subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user3) self.assertEqual(0, len(subscriptions)) topic.add_participant(self.user3) topic.save() subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user3) self.assertEqual(1, len(subscriptions)) notifications = Notification.objects.get_unread_notifications_of( self.user3) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.filter()) self.assertEqual(topic.last_message, notifications.first().content_object)
def create(self, validated_data): # This hack is necessary because `text` isn't a field of PrivateTopic. self.fields.pop("text") return send_mp( self.context.get("request").user, validated_data.get("participants"), validated_data.get("title"), validated_data.get("subtitle") or "", validated_data.get("text"), send_by_mail=True, leave=False, )
def notify_member(self, ban, msg): """ Notify the member sanctioned with a MP. :param ban: Sanction. :type ban: Ban object :param msg: message send at the user sanctioned. :type msg: string object :return: nothing :rtype: None """ bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"]) send_mp( bot, [ban.user], ban.type, "", msg, send_by_mail=True, direct=True, hat=get_hat_from_settings("moderation"), )
def test_creation_private_topic(self): """ When we create a topic, its author follows it. """ topic = send_mp(author=self.user1, users=[], title="Testing", subtitle="", text="", leave=False) subscriptions = PrivateTopicAnswerSubscription.objects.get_subscriptions( topic) self.assertEqual(1, len(subscriptions)) self.assertEqual(self.user1, subscriptions[0].user) self.assertTrue(subscriptions[0].by_email) self.assertIsNone(subscriptions[0].last_notification)
def test_remove_notifications_when_a_user_leave_private_topic(self): """ When a user leaves a private topic, we mark the current notification as read if it exists. """ topic = send_mp(author=self.user1, users=[self.user2], title="Testing", subtitle="", text="", leave=False) notifications = Notification.objects.get_unread_notifications_of( self.user2) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.first()) self.assertEqual(topic.last_message, notifications.first().content_object) self.assertIsNotNone( PrivateTopicAnswerSubscription.objects.get_existing( self.user2, topic, is_active=True)) send_message_mp(self.user2, topic, "Test") topic.remove_participant(self.user2) topic.save() self.assertEqual( 0, len(Notification.objects.get_unread_notifications_of(self.user2))) self.assertIsNotNone( PrivateTopicAnswerSubscription.objects.get_existing( self.user2, topic, is_active=False)) self.assertEqual( 1, len(Notification.objects.get_unread_notifications_of(self.user1))) response = self.client.post(reverse("mp-delete", args=[topic.pk, topic.slug]), follow=True) self.assertEqual(200, response.status_code) self.assertEqual( 0, len(Notification.objects.get_unread_notifications_of(self.user1)))
def form_valid(self, form): participants = [] for participant in form.data["participants"].split(","): current = participant.strip() if not current: continue participants.append(get_object_or_404(User, username=current)) p_topic = send_mp( self.request.user, participants, form.data["title"], form.data["subtitle"], form.data["text"], send_by_mail=True, leave=False, hat=get_hat_from_request(self.request), ) return redirect(p_topic.get_absolute_url())
def test_no_emails_for_those_who_have_other_things_in_that_place(self): """ Test that we do not try to send e-mails to those who have not registered a valid one. """ self.assertEqual(0, len(mail.outbox)) topic = send_mp( author=self.userStandard1, users=[self.userOAuth2], title="Testing", subtitle="", text="", send_by_mail=True, leave=False, ) self.assertEqual(0, len(mail.outbox)) send_message_mp(self.userOAuth2, topic, "", send_by_mail=True) self.assertEqual(1, len(mail.outbox))
def setUp(self): self.licence = LicenceFactory() self.subcategory = SubCategoryFactory() self.author = ProfileFactory() self.user = ProfileFactory() self.staff = StaffProfileFactory() self.tuto = PublishableContentFactory(type="TUTORIAL") self.tuto.authors.add(self.author.user) self.tuto.licence = self.licence self.tuto.subcategory.add(self.subcategory) self.tuto.save() self.validation = Validation( content=self.tuto, version=self.tuto.sha_draft, comment_authors="bla", date_proposition=datetime.now(), ) self.validation.save() self.topic = send_mp(author=self.author.user, users=[], title="Title", text="Testing", subtitle="", leave=False) self.topic.add_participant(self.user.user) send_message_mp(self.user.user, self.topic, "Testing") # humane_delta test periods = ((1, 0), (2, 1), (3, 7), (4, 30), (5, 360)) cont = dict() cont["date_today"] = periods[0][0] cont["date_yesterday"] = periods[1][0] cont["date_last_week"] = periods[2][0] cont["date_last_month"] = periods[3][0] cont["date_last_year"] = periods[4][0] self.context = Context(cont)
def test_send_an_email_when_we_specify_it(self): """ When the user asked to be notified via email, we actually send the email when a topic is created. """ settings.EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" self.assertEqual(0, len(mail.outbox)) topic = send_mp( author=self.user1, users=[self.user2, self.user3], title="Testing", subtitle="", text="", send_by_mail=True, leave=False, ) self.assertEqual(1, len(mail.outbox)) self.user1.profile.email_for_answer = True self.user1.profile.save() self.user2.profile.email_for_answer = True self.user2.profile.save() self.user3.profile.email_for_answer = False self.user3.profile.save() send_message_mp(self.user2, topic, "", send_by_mail=True) subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user2) self.assertTrue(subscriptions.last().by_email) self.assertEqual(2, len(mail.outbox)) self.user1.profile.email_for_answer = False self.user1.profile.save() send_message_mp(self.user2, topic, "", send_by_mail=True) self.assertEqual(2, len(mail.outbox))
def test_generate_a_notification_for_all_participants(self): """ When we create a topic, all participants have a notification for the last message. """ subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user2) self.assertEqual(0, len(subscriptions)) subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user3) self.assertEqual(0, len(subscriptions)) topic = send_mp(author=self.user1, users=[self.user2, self.user3], title="Testing", subtitle="", text="", leave=False) subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user2) self.assertEqual(1, len(subscriptions)) self.assertEqual(topic, subscriptions.first().content_object) subscriptions = PrivateTopicAnswerSubscription.objects.filter( user=self.user3) self.assertEqual(1, len(subscriptions)) self.assertEqual(topic, subscriptions.first().content_object) notification = Notification.objects.get_unread_notifications_of( self.user2).first() self.assertIsNotNone(notification) self.assertEqual(topic.last_message, notification.content_object) notification = Notification.objects.get_unread_notifications_of( self.user3).first() self.assertIsNotNone(notification) self.assertEqual(topic.last_message, notification.content_object)
def test_mark_read_a_notification(self): """ When we mark a private topic as read, we mark its notification as read. """ topic = send_mp(author=self.user1, users=[self.user2, self.user3], title="Testing", subtitle="", text="", leave=False) notifications = Notification.objects.get_unread_notifications_of( self.user2) self.assertEqual(1, len(notifications)) self.assertIsNotNone(notifications.first()) self.assertEqual(topic.last_message, notifications.first().content_object) mark_read(topic, self.user2) notifications = Notification.objects.get_unread_notifications_of( self.user2) self.assertEqual(0, len(notifications))
def delete(self, request, *args, **kwargs): """rewrite delete() function to ensure repository deletion""" self.object = self.get_object() object_type = self.object.type.lower() _type = _("ce tutoriel") if self.object.is_article: _type = _("cet article") elif self.object.is_opinion: _type = _("ce billet") if self.object.authors.count() > 1: # if more than one author, just remove author from list RemoveAuthorFromContent.remove_author(self.object, self.request.user) messages.success(self.request, _("Vous avez quitté la rédaction de {}.").format(_type)) else: validation = Validation.objects.filter(content=self.object).order_by("-date_proposition").first() if validation and validation.status == "PENDING_V": # if the validation have a validator, warn him by PM if "text" not in self.request.POST or len(self.request.POST["text"].strip()) < 3: messages.error(self.request, _("Merci de fournir une raison à la suppression.")) return redirect(self.object.get_absolute_url()) else: bot = get_object_or_404(User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "tutorialv2/messages/validation_cancel_on_delete.md", { "content": self.object, "validator": validation.validator.username, "user": self.request.user, "message": "\n".join(["> " + line for line in self.request.POST["text"].split("\n")]), }, ) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, [validation.validator], _("Demande de validation annulée").format(), self.object.title, msg, send_by_mail=False, leave=True, hat=get_hat_from_settings("validation"), automatically_read=validation.validator, ) validation.content.save() else: send_message_mp( bot, validation.content.validation_private_message, msg, hat=get_hat_from_settings("validation"), no_notification_for=[self.request.user], ) if self.object.beta_topic is not None: beta_topic = self.object.beta_topic beta_topic.is_locked = True beta_topic.add_tags(["Supprimé"]) beta_topic.save() post = beta_topic.first_post() post.update_content( _("[[a]]\n" "| Malheureusement, {} qui était en bêta a été supprimé par son auteur.\n\n").format( _type ) + post.text ) post.save() self.object.delete() messages.success(self.request, _("Vous avez bien supprimé {}.").format(_type)) return redirect(reverse(object_type + ":find-" + object_type, args=[request.user.username]))
def form_valid(self, form): current_user = False users = form.cleaned_data["users"] _type = (_("cet article"), _("de l'article")) if self.object.is_tutorial: _type = (_("ce tutoriel"), _("du tutoriel")) elif self.object.is_opinion: _type = (_("ce billet"), _("du billet")) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) for user in users: if RemoveAuthorFromContent.remove_author(self.object, user): if user.pk == self.request.user.pk: current_user = True else: send_mp( bot, [user], format_lazy("{}{}", _("Retrait de la rédaction "), _type[1]), self.versioned_object.title, render_to_string( "tutorialv2/messages/remove_author_pm.md", { "content": self.object, "user": user.username, }, ), hat=get_hat_from_settings("validation"), ) signals.authors_management.send( sender=self.__class__, content=self.object, performer=self.request.user, author=user, action="remove", ) else: # if user is incorrect or alone messages.error( self.request, _("Vous êtes le seul auteur de {} ou le membre sélectionné " "en a déjà quitté la rédaction.").format(_type[0]), ) return redirect(self.object.get_absolute_url()) self.object.save() authors_list = "" for index, user in enumerate(form.cleaned_data["users"]): if index > 0: if index == len(users) - 1: authors_list += _(" et ") else: authors_list += _(", ") authors_list += user.username if not current_user: # if the removed author is not current user messages.success( self.request, _("Vous avez enlevé {} de la liste des auteurs de {}.").format( authors_list, _type[0])) self.success_url = self.object.get_absolute_url() else: # if current user is leaving the content's redaction, redirect him to a more suitable page messages.success( self.request, _("Vous avez bien quitté la rédaction de {}.").format( _type[0])) self.success_url = reverse(self.object.type.lower() + ":find-" + self.object.type.lower(), args=[self.request.user.username]) return super().form_valid(form)
def form_valid(self, form): beta_version = self.versioned_object sha_beta = beta_version.current_version # topic of the beta version: topic = self.object.beta_topic if topic: if topic.forum_id != settings.ZDS_APP["forum"]["beta_forum_id"]: # if the topic is moved from the beta forum, then a new one is created instead topic = None _type = self.object.type.lower() if _type == "tutorial": _type = _("tutoriel") elif _type == "opinion": raise PermissionDenied # perform actions: if self.action == "inactive": self.object.sha_beta = None msg_post = render_to_string( "tutorialv2/messages/beta_desactivate.md", { "content": beta_version, "type": _type }) send_post(self.request, topic, self.request.user, msg_post) lock_topic(topic) signals.beta_management.send( sender=self.__class__, content=self.object, performer=self.request.user, version=sha_beta, action="deactivate", ) elif self.action == "set": already_in_beta = self.object.in_beta() all_tags = [] if not already_in_beta or self.object.sha_beta != sha_beta: self.object.sha_beta = sha_beta self.versioned_object.in_beta = True self.versioned_object.sha_beta = sha_beta msg = render_to_string( "tutorialv2/messages/beta_activate_topic.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + self.versioned_object.get_absolute_url_beta(), }, ) if not topic: # if first time putting the content in beta, send a message on the forum and a PM # find tags all_tags = self._get_all_tags() topic = self._create_beta_topic(msg, beta_version, _type, all_tags) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg_pm = render_to_string( "tutorialv2/messages/beta_activate_pm.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + topic.get_absolute_url(), "user": self.request.user, }, ) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, self.object.authors.all(), self.object.validation_message_title, beta_version.title, msg_pm, send_by_mail=False, leave=True, hat=get_hat_from_settings("validation"), ) self.object.save() else: send_message_mp( bot, self.object.validation_private_message, msg, hat=get_hat_from_settings("validation")) # When the anti-spam triggers (because the author of the # message posted themselves within the last 15 minutes), # it is likely that we want to avoid to generate a duplicated # post that couldn't be deleted. We hence avoid to add another # message to the topic. else: all_tags = self._get_all_tags() if not already_in_beta: unlock_topic(topic) msg_post = render_to_string( "tutorialv2/messages/beta_reactivate.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + self.versioned_object.get_absolute_url_beta(), }, ) topic = send_post(self.request, topic, self.request.user, msg_post) elif not topic.antispam(): msg_post = render_to_string( "tutorialv2/messages/beta_update.md", { "content": beta_version, "type": _type, "url": settings.ZDS_APP["site"]["url"] + self.versioned_object.get_absolute_url_beta(), }, ) topic = send_post(self.request, topic, self.request.user, msg_post) # make sure that all authors follow the topic: for author in self.object.authors.all(): TopicAnswerSubscription.objects.get_or_create_active( author, topic) mark_read(topic, author) # finally set the tags on the topic if topic: topic.tags.clear() for tag in all_tags: topic.tags.add(tag) topic.save() signals.beta_management.send( sender=self.__class__, content=self.object, performer=self.request.user, version=sha_beta, action="activate", ) self.object.save( ) # we should prefer .update but it needs a huge refactoring self.success_url = self.versioned_object.get_absolute_url( version=sha_beta) if self.object.is_beta(sha_beta): self.success_url = self.versioned_object.get_absolute_url_beta() return super().form_valid(form)
def form_valid(self, form): user = self.request.user authors = list(Profile.objects.contactable_members().filter( user__in=self.object.authors.all())) authors = list(author.user for author in authors) # check if the warn is done on a public or beta version : is_public = False if form.content.is_public: is_public = True elif not form.content.is_beta: raise Http404("Le contenu n'est ni public, ni en bêta.") if not authors: if self.object.authors.count() > 1: messages.error( self.request, _("Les auteurs sont malheureusement injoignables.")) else: messages.error(self.request, _("L'auteur est malheureusement injoignable.")) elif user in authors: # author try to PM himself messages.error( self.request, _("Impossible d'envoyer la proposition de correction : vous êtes auteur." )) else: # send correction text = "\n".join([ "> " + line for line in form.cleaned_data["text"].split("\n") ]) _type = _("l'article") if form.content.is_tutorial: _type = _("le tutoriel") if form.content.is_opinion: _type = _("le billet") pm_title = _("J'ai trouvé une faute dans {} « {} ».").format( _type, form.content.title) msg = render_to_string( "tutorialv2/messages/warn_typo.md", { "user": user, "content": form.content, "target": form.targeted, "type": _type, "public": is_public, "text": text, }, ) # send it : send_mp(user, authors, pm_title, "", msg, leave=False) messages.success(self.request, _("Merci pour votre proposition de correction.")) return redirect(form.previous_page_url)
def form_valid(self, form): old_validation = Validation.objects.filter( content__pk=self.object.pk, status__in=["PENDING", "PENDING_V"]).first() if old_validation: # if an old validation exists, cancel it! old_validator = old_validation.validator old_validation.status = "CANCEL" old_validation.date_validation = datetime.now() old_validation.save() else: old_validator = None # create a 'validation' object validation = Validation() validation.content = self.object validation.date_proposition = datetime.now() validation.comment_authors = form.cleaned_data["text"] validation.version = form.cleaned_data["version"] if old_validator: validation.validator = old_validator validation.date_reserve = old_validation.date_reserve validation.status = "PENDING_V" validation.save() # warn the former validator that an update has been made, if any if old_validator: bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "tutorialv2/messages/validation_change.md", { "content": self.versioned_object, "validator": validation.validator.username, "url": self.versioned_object.get_absolute_url() + "?version=" + form.cleaned_data["version"], "url_history": reverse("content:history", args=[self.object.pk, self.object.slug]), }, ) if not self.object.validation_private_message: self.object.validation_private_message = send_mp( bot, [old_validator], self.object.validation_message_title, self.versioned_object.title, msg, send_by_mail=False, hat=get_hat_from_settings("validation"), ) else: send_message_mp(bot, self.object.validation_private_message, msg) # update the content with the source and the version of the validation self.object.source = self.versioned_object.source self.object.sha_validation = validation.version self.object.save() messages.success( self.request, _("Votre demande de validation a été transmise à l'équipe.")) signals.validation_management.send( sender=self.__class__, content=validation.content, performer=self.request.user, version=validation.version, action="request", ) self.success_url = self.versioned_object.get_absolute_url( version=self.sha) return super().form_valid(form)
def form_valid(self, form): user = self.request.user validation = (Validation.objects.filter( pk=self.kwargs["pk"]).prefetch_related("content").prefetch_related( "content__authors").last()) if not validation: raise PermissionDenied if validation.status not in ["PENDING", "PENDING_V"]: raise PermissionDenied # cannot cancel a validation that is already accepted or rejected if user not in validation.content.authors.all( ) and not user.has_perm("tutorialv2.change_validation"): raise PermissionDenied versioned = validation.content.load_version(sha=validation.version) # reject validation: quote = "\n".join( ["> " + line for line in form.cleaned_data["text"].split("\n")]) validation.status = "CANCEL" validation.comment_authors = _( "\n\nLa validation a été **annulée** pour la raison suivante :\n\n{}" ).format(quote) validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # warn the former validator that the whole thing has been cancelled if validation.validator: bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = render_to_string( "tutorialv2/messages/validation_cancel.md", { "content": versioned, "validator": validation.validator.username, "url": versioned.get_absolute_url() + "?version=" + validation.version, "user": self.request.user, "message": quote, }, ) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, [validation.validator], _("Demande de validation annulée").format(), versioned.title, msg, send_by_mail=False, hat=get_hat_from_settings("validation"), ) validation.content.save() else: send_message_mp(bot, validation.content.validation_private_message, msg) messages.info(self.request, _("La validation de ce contenu a bien été annulée.")) signals.validation_management.send( sender=self.__class__, content=validation.content, performer=self.request.user, version=validation.version, action="cancel", ) self.success_url = ( reverse("content:view", args=[validation.content.pk, validation.content.slug]) + "?version=" + validation.version) return super().form_valid(form)
def post(self, request, *args, **kwargs): validation = get_object_or_404(Validation, pk=kwargs["pk"]) if validation.validator: validation.validator = None validation.date_reserve = None validation.status = "PENDING" validation.save() messages.info(request, _("Ce contenu n'est plus réservé.")) signals.validation_management.send( sender=self.__class__, content=validation.content, performer=request.user, version=validation.version, action="unreserve", ) return redirect(reverse("validation:list")) else: validation.validator = request.user validation.date_reserve = datetime.now() validation.status = "PENDING_V" validation.save() versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( "tutorialv2/messages/validation_reserve.md", { "content": versioned, "url": versioned.get_absolute_url() + "?version=" + validation.version, }, ) authors = list(validation.content.authors.all()) if validation.validator in authors: authors.remove(validation.validator) if len(authors) > 0: if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( validation.validator, authors, _("Contenu réservé - {0}").format( validation.content.title), validation.content.title, msg, send_by_mail=True, leave=False, direct=False, hat=get_hat_from_settings("validation"), ) validation.content.save() else: send_message_mp( validation.validator, validation.content.validation_private_message, msg) mark_read(validation.content.validation_private_message, validation.validator) messages.info( request, _("Ce contenu a bien été réservé par {0}.").format( request.user.username)) signals.validation_management.send( sender=self.__class__, content=validation.content, performer=request.user, version=validation.version, action="reserve", ) return redirect( reverse("content:view", args=[validation.content.pk, validation.content.slug]) + "?version=" + validation.version)
def form_valid(self, form): user = self.request.user validation = Validation.objects.filter(pk=self.kwargs["pk"]).last() if not validation: raise PermissionDenied if validation.validator != user: raise PermissionDenied if validation.status != "PENDING_V": raise PermissionDenied # reject validation: validation.comment_validator = form.cleaned_data["text"] validation.status = "REJECT" validation.date_validation = datetime.now() validation.save() validation.content.sha_validation = None validation.content.save() # send PM versioned = validation.content.load_version(sha=validation.version) msg = render_to_string( "tutorialv2/messages/validation_reject.md", { "content": versioned, "url": versioned.get_absolute_url() + "?version=" + validation.version, "validator": validation.validator, "message_reject": "\n".join( ["> " + a for a in form.cleaned_data["text"].split("\n")]), }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, validation.content.authors.all(), _("Rejet de la demande de publication").format(), validation.content.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("validation"), ) validation.content.save() else: send_message_mp(bot, validation.content.validation_private_message, msg, no_notification_for=[self.request.user]) messages.info(self.request, _("Le contenu a bien été refusé.")) self.success_url = reverse("validation:list") signals.validation_management.send( sender=self.__class__, content=validation.content, performer=self.request.user, version=validation.version, action="reject", ) return super().form_valid(form)
def form_valid(self, form): versioned = self.versioned_object if form.cleaned_data["version"] != self.object.sha_public: raise PermissionDenied validation = (Validation.objects.filter( content=self.object, version=self.object.sha_public, status="ACCEPT").prefetch_related("content__authors").last()) if not validation: raise PermissionDenied unpublish_content(self.object) validation.status = "PENDING" validation.validator = None # remove previous validator validation.date_validation = None validation.save() self.object.sha_public = None self.object.sha_validation = validation.version self.object.pubdate = None self.object.save() # send PM msg = render_to_string( "tutorialv2/messages/validation_revoke.md", { "content": versioned, "url": versioned.get_absolute_url() + "?version=" + validation.version, "admin": self.request.user, "message_reject": "\n".join( ["> " + a for a in form.cleaned_data["text"].split("\n")]), }, ) bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) if not validation.content.validation_private_message: validation.content.validation_private_message = send_mp( bot, validation.content.authors.all(), self.object.validation_message_title, validation.content.title, msg, send_by_mail=True, direct=False, hat=get_hat_from_settings("validation"), ) self.object.save() else: send_message_mp(bot, validation.content.validation_private_message, msg, no_notification_for=[self.request.user]) messages.success(self.request, _("Le contenu a bien été dépublié.")) self.success_url = self.versioned_object.get_absolute_url( ) + "?version=" + validation.version signals.validation_management.send( sender=self.__class__, content=validation.content, performer=self.request.user, version=validation.version, action="revoke", ) return super().form_valid(form)
def settings_promote(request, user_pk): """ Manage groups and activation status of a user. Only superusers are allowed to use this. """ if not request.user.is_superuser: raise PermissionDenied profile = get_object_or_404(Profile, user__pk=user_pk) user = profile.user if request.method == "POST": form = PromoteMemberForm(request.POST) data = dict(form.data) groups = Group.objects.all() usergroups = user.groups.all() if "groups" in data: for group in groups: if str(group.id) in data["groups"]: if group not in usergroups: user.groups.add(group) messages.success( request, _("{0} appartient maintenant au groupe {1}."). format(user.username, group.name)) else: if group in usergroups: user.groups.remove(group) messages.warning( request, _("{0} n'appartient maintenant plus au groupe {1}." ).format(user.username, group.name), ) else: user.groups.clear() messages.warning( request, _("{0} n'appartient (plus ?) à aucun groupe.").format( user.username)) if "activation" in data and "on" in data["activation"]: user.is_active = True messages.success( request, _("{0} est maintenant activé.").format(user.username)) else: user.is_active = False messages.warning(request, _("{0} est désactivé.").format(user.username)) user.save() usergroups = user.groups.all() bot = get_object_or_404( User, username=settings.ZDS_APP["member"]["bot_account"]) msg = _("Bonjour {0},\n\n" "Un administrateur vient de modifier les groupes " "auxquels vous appartenez. \n").format(user.username) if len(usergroups) > 0: msg = format_lazy( "{}{}", msg, _("Voici la liste des groupes dont vous faites dorénavant partie :\n\n" )) for group in usergroups: msg += f"* {group.name}\n" else: msg = format_lazy("{}{}", msg, _("* Vous ne faites partie d'aucun groupe")) send_mp( bot, [user], _("Modification des groupes"), "", msg, send_by_mail=True, leave=True, hat=get_hat_from_settings("moderation"), ) return redirect(profile.get_absolute_url()) form = PromoteMemberForm(initial={ "groups": user.groups.all(), "activation": user.is_active }) return render(request, "member/admin/promote.html", { "usr": user, "profile": profile, "form": form })