Example #1
0
def test_update_editor_follows_signal(client, factory, reverse):
    m1, m2 = factory.create_batch(2)
    u1, u2, u3, u4 = UserFactory.create_batch(4)

    if not reverse:
        for user in [u1, u2, u3, u4]:
            user.groups.add(m1.editors_group, m2.editors_group)
        for user in [u3, u4]:
            user.groups.remove(m1.editors_group)
        for user in [u1, u2, u3, u4]:
            user.groups.remove(m2.editors_group)

    else:
        g = Group.objects.filter(name=m1.editors_group).get()
        g.user_set.add(u1, u2, u3, u4)
        g.user_set.remove(u3, u4)

    assert is_following(u1, m1)
    assert is_following(u2, m1)
    assert not is_following(u3, m1)
    assert not is_following(u4, m1)
    assert not is_following(u1, m2)
    assert not is_following(u2, m2)
    assert not is_following(u3, m2)
    assert not is_following(u4, m2)

    # Test clearing
    if reverse:
        u1.groups.clear()
    else:
        g = Group.objects.filter(name=m1.editors_group).get()
        g.user_set.clear()

    assert not is_following(u1, m1)
Example #2
0
def test_permission_request_notifications_flow_for_accept_verified_users(
        client, factory, namespace, request_model, request_attr):
    base_object = factory(access_request_handling=AccessRequestHandlingOptions.
                          ACCEPT_VERIFIED_USERS)
    if namespace == "participants":
        permission_create_url = reverse(
            f"{namespace}:registration-create",
            kwargs={"challenge_short_name": base_object.short_name},
        )
        assert base_object.admins_group.user_set.count() == 1
        editor = base_object.admins_group.user_set.get()
        # challenge creation results in a notification, delete this notification
        Notification.objects.all().delete()
    else:
        editor = UserFactory()
        base_object.add_editor(editor)
        permission_create_url = reverse(
            f"{namespace}:permission-request-create",
            kwargs={"slug": base_object.slug},
        )
        assert base_object.editors_group.user_set.count() == 1

    not_verified_user = UserFactory()
    verified_user = UserFactory()
    Verification.objects.create(user=verified_user, is_verified=True)

    # the verified users gets accepted automatically, no follows and no notifcations
    _ = get_view_for_user(
        client=client,
        user=verified_user,
        url=permission_create_url,
        method=client.post,
    )
    pr = request_model.objects.get()
    assert pr.status == request_model.ACCEPTED
    assert pr.user == verified_user
    assert not is_following(user=verified_user, obj=pr)
    assert Notification.objects.count() == 0
    pr.delete()

    # for the not verified user, a follow is created, the request is pending and
    # the admin gets a notification
    _ = get_view_for_user(
        client=client,
        user=not_verified_user,
        url=permission_create_url,
        method=client.post,
    )
    pr = request_model.objects.get()
    assert pr.status == request_model.PENDING
    assert pr.user == not_verified_user
    assert is_following(user=not_verified_user, obj=pr)
    assert Notification.objects.count() == 1
    assert Notification.objects.get().user == editor
def test_participants_follow_forum(group):
    u = UserFactory()
    c = ChallengeFactory()

    add_method = getattr(c, f"add_{group}")
    remove_method = getattr(c, f"remove_{group}")

    add_method(user=u)
    assert is_following(user=u, obj=c.forum)

    remove_method(user=u)
    assert is_following(user=u, obj=c.forum) is False

    # No actions should be created
    assert Action.objects.exists() is False
Example #4
0
    def test_follow(self):
        """Test bulk following"""
        public_foia = FOIARequestFactory()
        private_foia = FOIARequestFactory(embargo=True)
        user = UserFactory()

        RequestList()._follow(
            FOIARequest.objects.filter(
                pk__in=[public_foia.pk, private_foia.pk]),
            user,
            {},
        )

        ok_(is_following(user, public_foia))
        assert_false(is_following(user, private_foia))
Example #5
0
def star_project(request, username, project):
    project = Project.retrieve(username, project, request.user)
    if is_following(request.user, project):
        unfollow(request.user, project)
    else:
        follow(request.user, project, actor_only=False)
    return HttpResponseRedirect(project.link())
Example #6
0
    def save(self, *args, **kwargs):
        adding = self._state.adding

        super().save(*args, **kwargs)

        if adding:
            self.set_default_interfaces()
            self.assign_permissions()
            for admin in self.challenge.get_admins():
                if not is_following(admin, self):
                    follow(
                        user=admin,
                        obj=self,
                        actor_only=False,
                        send_action=False,
                    )

        if self.public != self._orig_public:
            on_commit(
                assign_evaluation_permissions.signature(
                    kwargs={"phase_pks": [self.pk]}
                ).apply_async
            )
            on_commit(
                assign_submission_permissions.signature(
                    kwargs={"phase_pk": self.pk}
                ).apply_async
            )

        on_commit(
            lambda: calculate_ranks.apply_async(kwargs={"phase_pk": self.pk})
        )
Example #7
0
def follow_user(request, username):
    user = get_object_or_404(User, username=username)
    if user != request.user:
        if is_following(request.user, user):
            unfollow(request.user, user)
        else:
            follow(request.user, user, actor_only=False)
    return HttpResponseRedirect(reverse("profile", args=[username]))
Example #8
0
def test_reader_study_delete(client):
    rs = ReaderStudyFactory(use_display_sets=False)
    editor = UserFactory()
    reader = UserFactory()
    rs.add_editor(editor)
    rs.add_reader(reader)

    assert ReaderStudy.objects.count() == 1
    assert is_following(user=editor, obj=rs)

    response = get_view_for_user(
        viewname="reader-studies:delete",
        client=client,
        method=client.get,
        reverse_kwargs={"slug": rs.slug},
        follow=True,
        user=reader,
    )

    assert response.status_code == 403
    assert ReaderStudy.objects.count() == 1

    response = get_view_for_user(
        viewname="reader-studies:delete",
        client=client,
        method=client.get,
        reverse_kwargs={"slug": rs.slug},
        follow=True,
        user=editor,
    )

    assert response.status_code == 200
    assert "Confirm Deletion" in response.rendered_content

    response = get_view_for_user(
        viewname="reader-studies:delete",
        client=client,
        method=client.post,
        reverse_kwargs={"slug": rs.slug},
        follow=True,
        user=editor,
    )

    assert response.status_code == 200
    assert ReaderStudy.objects.count() == 0
    assert not is_following(user=editor, obj=rs)
Example #9
0
    def test_unfollow(self):
        """Test bulk unfollowing"""
        follow_foia = FOIARequestFactory()
        unfollow_foia = FOIARequestFactory()
        user = UserFactory()

        follow(user, follow_foia, actor_only=False)

        RequestList()._unfollow(
            FOIARequest.objects.filter(
                pk__in=[follow_foia.pk, unfollow_foia.pk]),
            user,
            {},
        )

        assert_false(is_following(user, follow_foia))
        assert_false(is_following(user, unfollow_foia))
Example #10
0
    def create_relationship(self, user, me):
        """Start blocking the user if exists and is not the logged in user."""
        if user.pk is me.pk:
            return HttpBadRequest("A user can't block itself.")

        me.relationships.add(user, status=RelationshipStatus.objects.blocking())
        if actions.is_following(user, me):
            actions.unfollow(user, me)
Example #11
0
def test_topic_subscribe_and_unsubscribe(client):
    user1 = UserFactory()
    user2 = UserFactory()
    f = ForumFactory(type=Forum.FORUM_POST)
    UserForumPermission.objects.create(
        permission=ForumPermission.objects.filter(
            codename="can_read_forum").get(),
        user=user1,
        forum=f,
        has_perm=True,
    )
    t = TopicFactory(forum=f, poster=user2, type=Topic.TOPIC_POST)

    assert not is_following(user1, t)

    response = get_view_for_user(
        viewname="notifications:follow-create",
        client=client,
        method=client.post,
        data={
            "user":
            user1.id,
            "content_type":
            ContentType.objects.get(
                app_label=t._meta.app_label,
                model=t._meta.model_name,
            ).id,
            "object_id":
            t.id,
            "actor_only":
            False,
        },
        user=user1,
    )
    assert response.status_code == 302
    assert is_following(user1, t)

    response = get_view_for_user(
        viewname="notifications:follow-delete",
        client=client,
        method=client.post,
        reverse_kwargs={"pk": Follow.objects.filter(user=user1).first().id},
        user=user1,
    )
    assert response.status_code == 302
    assert not is_following(user1, t)
Example #12
0
    def get_is_following(self, obj):
        user = self.context.get('user')

        if user and user.id != obj.user.id and not isinstance(
                user, AnonymousUser):
            return is_following(user, obj.user)

        return False
Example #13
0
def test_participants_follow_forum(group):
    u = UserFactory()
    c = ChallengeFactory()

    add_method = getattr(c, f"add_{group}")
    remove_method = getattr(c, f"remove_{group}")

    add_method(user=u)
    assert is_following(user=u, obj=c.forum)

    remove_method(user=u)
    assert is_following(user=u, obj=c.forum) is False

    # No actions involving the forum should be created
    for i in Action.objects.all():
        assert c.forum != i.target
        assert c.forum != i.action_object
        assert c.forum != i.actor
Example #14
0
def test_follow_clean_up_after_forum_removal():
    u = UserFactory()
    f1 = ForumFactory(type=Forum.FORUM_POST)
    f2 = ForumFactory(type=Forum.FORUM_POST)
    follow(u, f1, send_action=False)
    follow(u, f2, send_action=False)

    f1.delete()

    assert not is_following(u, f1)
Example #15
0
def test_follow_clean_up_after_topic_removal():
    u = UserFactory()
    f = ForumFactory(type=Forum.FORUM_POST)
    t1 = TopicFactory(forum=f, type=Topic.TOPIC_POST)
    t2 = TopicFactory(forum=f, type=Topic.TOPIC_POST)
    follow(u, t1, send_action=False)
    follow(u, t2, send_action=False)

    t1.delete()

    assert not is_following(u, t1)
Example #16
0
def user_timeline(request, username):
    user = User.objects.select_related('profile').get(username=username)
    user_actions = []

    if is_following(request.user, user) or not user.profile.private:
        user_actions = actor_stream(user)

    context = {
        'user': user,
        'activities': user_actions,
    }
    return render(request, 'timeline.html', context)
Example #17
0
    def add_to_agora(self, request=None, agora_name=None, agora_id=None):
        '''
        Add the user to the specified agora. The agora is specified by its full
        name or id, for example agora_name="username/agoraname" or agora_id=3.
        '''

        if agora_name:
            username, agoraname = agora_name.split("/")
            agora = get_object_or_404(Agora,
                                      name=agoraname,
                                      creator__username=username)
            agora.members.add(self.user)
            agora.save()
        else:
            agora = get_object_or_404(Agora, pk=agora_id)
            agora.members.add(self.user)
            agora.save()

        send_action(self.user,
                    verb='joined',
                    action_object=agora,
                    request=request)

        if not is_following(self.user, agora):
            follow(self.user, agora, actor_only=False, request=request)

        # Mail to the user
        if not self.has_perms('receive_email_updates'):
            return

        translation.activate(self.user.get_profile().lang_code)
        context = get_base_email_context(request)
        context.update(
            dict(agora=agora,
                 other_user=self.user,
                 notification_text=_('You just joined %(agora)s. '
                                     'Congratulations!') %
                 dict(agora=agora.get_full_name()),
                 to=self.user))

        email = EmailMultiAlternatives(
            subject=_('%(site)s - you are now member of %(agora)s') %
            dict(site=Site.objects.get_current().domain,
                 agora=agora.get_full_name()),
            body=render_to_string('agora_core/emails/agora_notification.txt',
                                  context),
            to=[self.user.email])

        email.attach_alternative(
            render_to_string('agora_core/emails/agora_notification.html',
                             context), "text/html")
        email.send()
        translation.deactivate()
Example #18
0
def test_follow_clean_up_after_post_removal():
    u = UserFactory()
    f = ForumFactory(type=Forum.FORUM_POST)
    t = TopicFactory(forum=f, type=Topic.TOPIC_POST)
    p1 = PostFactory(topic=t, poster=u)
    p2 = PostFactory(topic=t, poster=u)

    follow(u, p1)
    follow(u, p2)

    p1.delete()

    assert not is_following(u, p1)
Example #19
0
    def save(self, *args, **kwargs):
        adding = self._state.adding

        if adding:
            self.init_viewers_group()

        super().save(*args, **kwargs)

        if adding:
            self.init_permissions()
            followers = list(
                self.algorithm_image.algorithm.editors_group.user_set.all()
            )
            if self.creator:
                followers.append(self.creator)
            for follower in set(followers):
                if not is_following(
                    user=follower,
                    obj=self.algorithm_image.algorithm,
                    flag="job-active",
                ) and not is_following(
                    user=follower,
                    obj=self.algorithm_image.algorithm,
                    flag="job-inactive",
                ):
                    follow(
                        user=follower,
                        obj=self.algorithm_image.algorithm,
                        actor_only=False,
                        send_action=False,
                        flag="job-active",
                    )

        if adding or self._public_orig != self.public:
            self.update_viewer_groups_for_public()
            self._public_orig = self.public

        if self._status_orig != self.status and self.status == self.SUCCESS:
            self.algorithm_image.algorithm.update_average_duration()
Example #20
0
    def add_to_agora(self, request=None, agora_name=None, agora_id=None):
        '''
        Add the user to the specified agora. The agora is specified by its full
        name or id, for example agora_name="username/agoraname" or agora_id=3.
        '''

        if agora_name:
            username, agoraname = agora_name.split("/")
            agora = get_object_or_404(Agora, name=agoraname,
                creator__username=username)
            agora.members.add(self.user)
            agora.save()
        else:
            agora = get_object_or_404(Agora, pk=agora_id)
            agora.members.add(self.user)
            agora.save()

        send_action(self.user, verb='joined', action_object=agora, request=request)

        if not is_following(self.user, agora):
            follow(self.user, agora, actor_only=False, request=request)

        # Mail to the user
        if not self.has_perms('receive_email_updates'):
            return

        translation.activate(self.user.get_profile().lang_code)
        context = get_base_email_context(request)
        context.update(dict(
            agora=agora,
            other_user=self.user,
            notification_text=_('You just joined %(agora)s. '
                'Congratulations!') % dict(agora=agora.get_full_name()),
            to=self.user
        ))

        email = EmailMultiAlternatives(
            subject=_('%(site)s - you are now member of %(agora)s') % dict(
                        site=Site.objects.get_current().domain,
                        agora=agora.get_full_name()
                    ),
            body=render_to_string('agora_core/emails/agora_notification.txt',
                context),
            to=[self.user.email])

        email.attach_alternative(
            render_to_string('agora_core/emails/agora_notification.html',
                context), "text/html")
        email.send()
        translation.deactivate()
Example #21
0
    def handle_following(self, user, obj):
        if not user.is_authenticated():
            return False

        registry.register(obj.__class__) # TODO remove this
        following = is_following(user, obj)

        if self.action == 'follow_toggle':
            # Toggle follow!
            [follow, unfollow][int(following)](user, obj)

            # toggle what we return
            following = not following

        return following
Example #22
0
def test_failed_image_import_notification():
    image = ["corrupt.png"]
    session, _ = create_raw_upload_image_session(images=image)

    build_images(upload_session_pk=session.pk)
    session.refresh_from_db()

    assert RawImageUploadSession.objects.count() == 1
    assert is_following(
        user=RawImageUploadSession.objects.get().creator,
        obj=RawImageUploadSession.objects.get(),
    )
    assert Notification.objects.count() == 1
    assert (Notification.objects.get().user ==
            RawImageUploadSession.objects.get().creator)
def test_reader_study_create(client, uploaded_image):
    # The study creator should automatically get added to the editors group
    creator = get_rs_creator()
    ws = WorkstationFactory()

    def try_create_rs(allow_case_navigation):
        return get_view_for_user(
            viewname="reader-studies:create",
            client=client,
            method=client.post,
            data={
                "title": "foo bar",
                "logo": uploaded_image(),
                "workstation": ws.pk,
                "allow_answer_modification": True,
                "allow_case_navigation": allow_case_navigation,
            },
            follow=True,
            user=creator,
        )

    response = try_create_rs(False)
    assert "error_1_id_workstation" in response.rendered_content

    # The editor must have view permissions for the workstation to add it
    ws.add_user(user=creator)

    response = try_create_rs(False)
    assert "error_1_id_workstation" not in response.rendered_content
    assert (
        "`allow_case_navigation` must be checked if `allow_answer_modification` is"
        in response.rendered_content
    )

    response = try_create_rs(True)
    assert "error_1_id_workstation" not in response.rendered_content
    assert (
        "`allow_case_navigation` must be checked if `allow_answer_modification` is"
        not in response.rendered_content
    )
    assert response.status_code == 200

    rs = ReaderStudy.objects.get(title="foo bar")

    assert rs.slug == "foo-bar"
    assert rs.is_editor(user=creator)
    assert not rs.is_reader(user=creator)
    assert is_following(user=creator, obj=rs)
Example #24
0
def test_algorithm_create(client, uploaded_image):
    # The algorithm creator should automatically get added to the editors group
    creator = get_algorithm_creator()
    VerificationFactory(user=creator, is_verified=True)

    ws = WorkstationFactory()
    ci = ComponentInterface.objects.get(slug="generic-medical-image")

    def try_create_algorithm():
        return get_view_for_user(
            viewname="algorithms:create",
            client=client,
            method=client.post,
            data={
                "title": "foo bar",
                "logo": uploaded_image(),
                "workstation": ws.pk,
                "credits_per_job": 1,
                "image_requires_gpu": False,
                "image_requires_memory_gb": 4,
                "inputs": [ci.pk],
                "outputs": [ComponentInterfaceFactory().pk],
                "contact_email": creator.email,
                "display_editors": True,
                "access_request_handling": AccessRequestHandlingOptions.MANUAL_REVIEW,
                "view_content": "{}",
            },
            follow=True,
            user=creator,
        )

    response = try_create_algorithm()
    assert "error_1_id_workstation" in response.rendered_content

    # The editor must have view permissions for the workstation to add it
    ws.add_user(user=creator)

    response = try_create_algorithm()
    assert "error_1_id_workstation" not in response.rendered_content
    assert response.status_code == 200

    alg = Algorithm.objects.get(title="foo bar")

    assert alg.slug == "foo-bar"
    assert alg.is_editor(user=creator)
    assert not alg.is_user(user=creator)
    assert is_following(user=creator, obj=alg)
Example #25
0
    def to_representation(self, obj):
        returnObj = super(AccountSerializer, self).to_representation(obj)
        follower_count = len(followers(obj))
        print(follower_count)
        following_count = len(following(obj))
        total_posts = len(Topic.objects.filter(author = obj.id))
        new_obj = {}

        if self.context['request'].user.id == obj.id:
            new_obj["email"] = obj.email
        new_obj.update({
            "following": following_count,
            "follower": 0,
            "total_posts": total_posts,
            "am_I_following": is_following(self.context['request'].user, obj)})
        returnObj.update(new_obj)
        return returnObj
Example #26
0
    def to_representation(self, obj):
        returnObj = super(AccountSerializer,self).to_representation(obj)
        followers_count = len(followers(obj))
        following_count = len(following(obj))
        total_posts = len(Post.objects.filter(author=obj.id))
        new_obj = {}

        # if isinstance(self.context['request'].user, User):
        if self.context['request'].user.id == obj.id:
            new_obj["email"] = obj.email
        new_obj.update({
            "following": following_count,
            "followers": followers_count,
            'total_posts': total_posts,
            "am_I_following": is_following(self.context['request'].user, obj)
        })
        returnObj.update(new_obj)
        return returnObj
Example #27
0
    def save(self, *args, **kwargs):
        adding = self._state.adding

        super().save(*args, **kwargs)

        if adding:
            self.assign_permissions()
            if not is_following(self.creator, self.phase):
                follow(
                    user=self.creator,
                    obj=self.phase,
                    actor_only=False,
                    send_action=False,
                )
            e = create_evaluation.signature(
                kwargs={"submission_pk": self.pk}, immutable=True
            )
            on_commit(e.apply_async)
Example #28
0
def test_follows_deleted_when_request_deleted(client):
    base_object = AlgorithmFactory(
        access_request_handling=AccessRequestHandlingOptions.MANUAL_REVIEW)
    editor = UserFactory()
    base_object.add_editor(editor)
    permission_create_url = reverse(
        "algorithms:permission-request-create",
        kwargs={"slug": base_object.slug},
    )
    user = UserFactory()
    _ = get_view_for_user(client=client,
                          user=user,
                          url=permission_create_url,
                          method=client.post)
    pr = AlgorithmPermissionRequest.objects.get()
    assert is_following(user, pr)
    pr.delete()
    assert not Follow.objects.filter(object_id=pr.pk)
Example #29
0
    def join_action(self, request, agora, **kwargs):
        '''
        Action that an user can execute to join an agora if it has permissions
        '''
        agora.members.add(request.user)
        agora.save()

        action.send(request.user, verb='joined', action_object=agora,
            ipaddr=request.META.get('REMOTE_ADDR'),
            geolocation=json.dumps(geolocate_ip(request.META.get('REMOTE_ADDR'))))

        if not is_following(request.user, agora):
            follow(request.user, agora, actor_only=False, request=request)

        # Mail to the user
        user = request.user
        if user.get_profile().has_perms('receive_email_updates'):
            translation.activate(user.get_profile().lang_code)
            context = get_base_email_context(request)
            context.update(dict(
                agora=agora,
                other_user=user,
                notification_text=_('You just joined %(agora)s. '
                    'Congratulations!') % dict(agora=agora.get_full_name()),
                to=user
            ))

            email = EmailMultiAlternatives(
                subject=_('%(site)s - you are now member of %(agora)s') % dict(
                            site=Site.objects.get_current().domain,
                            agora=agora.get_full_name()
                        ),
                body=render_to_string('agora_core/emails/agora_notification.txt',
                    context),
                to=[user.email])

            email.attach_alternative(
                render_to_string('agora_core/emails/agora_notification.html',
                    context), "text/html")
            email.send()
            translation.deactivate()

        return self.create_response(request, dict(status="success"))
Example #30
0
def test_archive_create(client, uploaded_image):
    # The archive creator should automatically get added to the editors group
    creator = UserFactory()
    add_archive_perm = Permission.objects.get(
        codename=f"add_{Archive._meta.model_name}"
    )
    creator.user_permissions.add(add_archive_perm)

    ws = WorkstationFactory()

    def try_create_archive():
        return get_view_for_user(
            viewname="archives:create",
            client=client,
            method=client.post,
            data={
                "title": "foo bar",
                "logo": uploaded_image(),
                "workstation": ws.pk,
                "access_request_handling": AccessRequestHandlingOptions.MANUAL_REVIEW,
                "view_content": "{}",
            },
            follow=True,
            user=creator,
        )

    response = try_create_archive()
    assert "error_1_id_workstation" in response.rendered_content

    # The editor must have view permissions for the workstation to add it
    ws.add_user(user=creator)

    response = try_create_archive()
    assert "error_1_id_workstation" not in response.rendered_content
    assert response.status_code == 200

    archive = Archive.objects.get(title="foo bar")

    assert archive.slug == "foo-bar"
    assert archive.is_editor(user=creator)
    assert not archive.is_user(user=creator)
    assert is_following(user=creator, obj=archive)
Example #31
0
def test_permission_request_notifications_flow_for_accept_all(
        client, factory, namespace, request_model, request_attr):
    # when access_request_handling is set to accept all,
    # no notifications are sent, no follows are created
    # and the request is automatically accepted
    base_object = factory(
        access_request_handling=AccessRequestHandlingOptions.ACCEPT_ALL)
    if namespace == "participants":
        permission_create_url = reverse(
            f"{namespace}:registration-create",
            kwargs={"challenge_short_name": base_object.short_name},
        )
        assert base_object.admins_group.user_set.count() == 1
        editor = base_object.admins_group.user_set.get()
        # challenge creation results in a notification, delete this notification
        Notification.objects.all().delete()
    else:
        editor = UserFactory()
        base_object.add_editor(editor)
        permission_create_url = reverse(
            f"{namespace}:permission-request-create",
            kwargs={"slug": base_object.slug},
        )
        assert base_object.editors_group.user_set.count() == 1

    user3 = UserFactory()
    _ = get_view_for_user(
        client=client,
        user=user3,
        url=permission_create_url,
        method=client.post,
    )

    pr = request_model.objects.get()
    assert pr.status == request_model.ACCEPTED
    assert pr.user == user3
    assert not is_following(user=user3, obj=pr)
    assert Notification.objects.count() == 0
Example #32
0
    def request_membership_action(self, request, agora, **kwargs):
        '''
        Requests membership from authenticated user to an agora
        '''
        assign('requested_membership', request.user, agora)

        action.send(request.user, verb='requested membership', action_object=agora,
            ipaddr=request.META.get('REMOTE_ADDR'),
            geolocation=json.dumps(geolocate_ip(request.META.get('REMOTE_ADDR'))))

        if not is_following(request.user, agora):
            follow(request.user, agora, actor_only=False, request=request)

        kwargs=dict(
            agora_id=agora.id,
            user_id=request.user.id,
            is_secure=request.is_secure(),
            site_id=Site.objects.get_current().id,
            remote_addr=request.META.get('REMOTE_ADDR')
        )
        send_request_membership_mails.apply_async(kwargs=kwargs)

        return self.create_response(request, dict(status="success"))
Example #33
0
def process_registration(instance: RegistrationRequest = None,
                         created: bool = False,
                         *_,
                         **__):
    if created and not instance.challenge.require_participant_review:
        instance.status = RegistrationRequest.ACCEPTED
        RegistrationRequest.objects.filter(pk=instance.pk).update(
            status=instance.status)
    elif created and instance.challenge.require_participant_review:
        Notification.send(
            type=NotificationType.NotificationTypeChoices.ACCESS_REQUEST,
            message="requested access to",
            actor=instance.user,
            target=instance.challenge,
        )
    if not is_following(instance.user, instance):
        follow(
            user=instance.user,
            obj=instance,
            actor_only=False,
            send_action=False,
        )
    if instance.status == RegistrationRequest.ACCEPTED:
        instance.challenge.add_participant(instance.user)
        Notification.send(
            type=NotificationType.NotificationTypeChoices.REQUEST_UPDATE,
            message="was approved",
            target=instance,
        )
    elif instance.status == RegistrationRequest.REJECTED:
        instance.challenge.remove_participant(instance.user)
        Notification.send(
            type=NotificationType.NotificationTypeChoices.REQUEST_UPDATE,
            message="was rejected",
            target=instance,
        )
Example #34
0
def test_permission_request_notifications_flow_for_manual_review(
        client, factory, namespace, request_model, request_attr):
    base_object = factory(
        access_request_handling=AccessRequestHandlingOptions.MANUAL_REVIEW)
    if namespace == "participants":
        permission_create_url = reverse(
            f"{namespace}:registration-create",
            kwargs={"challenge_short_name": base_object.short_name},
        )
        assert base_object.admins_group.user_set.count() == 1
        editor = base_object.admins_group.user_set.get()
        # challenge creation results in a notification, delete this notification
        Notification.objects.all().delete()
    else:
        editor = UserFactory()
        base_object.add_editor(editor)
        permission_create_url = reverse(
            f"{namespace}:permission-request-create",
            kwargs={"slug": base_object.slug},
        )
        assert base_object.editors_group.user_set.count() == 1

    user = UserFactory()
    assert request_model.objects.count() == 0
    # editors automatically follow the base_obj
    assert is_following(user=editor, obj=base_object)

    # Create the permission request
    _ = get_view_for_user(client=client,
                          user=user,
                          url=permission_create_url,
                          method=client.post)

    pr = request_model.objects.get()
    assert pr.status == request_model.PENDING
    assert pr.user == user
    # check that requester follows the request object
    assert is_following(user=user, obj=pr)
    # check request results in notification for followers of base_obj
    assert Notification.objects.count() == 1
    assert Notification.objects.get().user == editor
    base_obj_str = format_html('<a href="{}">{}</a>',
                               base_object.get_absolute_url(), base_object)
    assert (f"{user_profile_link(user)} requested access to {base_obj_str}"
            in Notification.objects.get().print_notification(user=editor))

    if namespace == "participants":
        permission_update_url = reverse(
            f"{namespace}:registration-update",
            kwargs={
                "challenge_short_name": base_object.short_name,
                "pk": pr.pk,
            },
        )
    else:
        permission_update_url = reverse(
            f"{namespace}:permission-request-update",
            kwargs={
                "slug": base_object.slug,
                "pk": pr.pk
            },
        )

    # accepting the permission request
    _ = get_view_for_user(
        client=client,
        user=editor,
        url=permission_update_url,
        method=client.post,
        data={"status": pr.ACCEPTED},
    )

    pr.refresh_from_db()
    assert pr.status == request_model.ACCEPTED

    # check that status update results in notification for follower of request object,
    # and removal of the notification for the editor
    assert Notification.objects.count() == 1
    assert Notification.objects.all()[0].user == user
    assert (f"Your registration request for {base_obj_str} was accepted"
            in Notification.objects.all()[0].print_notification(user=user))

    # reject permission request
    _ = get_view_for_user(
        client=client,
        user=editor,
        url=permission_update_url,
        method=client.post,
        data={"status": pr.REJECTED},
    )

    pr.refresh_from_db()
    assert pr.status == request_model.REJECTED
    assert Notification.objects.count() == 2
    assert Notification.objects.all()[1].user == user
    assert (f"Your registration request for {base_obj_str} was rejected"
            in Notification.objects.all()[1].print_notification(user=user))
Example #35
0
def activity_register(_user, _action_object):
    """
    Registers and activity when an object is saved. Takes a diff with a
    previous version of edited objects, put it as message content in a
    timeline, uses the verbs 'created' or 'edited' for actions on actstream.
    """
    from lxml.html.diff import htmldiff

    from django.db.models.loading import get_model
    from django.forms import ValidationError
    from django.forms.models import model_to_dict
    from django.template.loader import render_to_string

    from actstream import action
    from actstream.actions import follow, is_following
    from actstream.models import action_object_stream

    klass = _action_object.__class__.__name__.lower()
    if klass not in ['problem', 'criteria', 'idea', 'alternative', 'comment']:
        raise forms.ValidationError(_('Wrong object type'))

    # Last activity
    last = (action_object_stream(_action_object)[:1] or [None])[0]
    _content_old = render_to_string('diffbase_' + klass + '.html', {klass: last}) if last else ''
    _content = render_to_string('diffbase_' + klass + '.html', {klass: _action_object})
    _emsg = _action_object.edit_message if hasattr(_action_object, 'edit_message') else ''
    _diff = htmldiff(_content_old, _content)

    # Set target problem
    if klass in ['comment']:
        if getattr(_action_object, 'problem'):
            _target = getattr(_action_object, 'problem')
        else:
            for attr in ['criteria', 'idea', 'alternative']:
                if getattr(_action_object, attr):
                    _target = getattr(_action_object, attr)
                    break
            _target = getattr(_target, 'problem')
    elif klass in ['criteria', 'idea', 'alternative']:
        _target = getattr(_action_object, 'problem')
    elif klass in ['problem']:
        _target = _action_object

    # Don't do anything if the problem or the action object is a draft
    if hasattr(_action_object, 'published') and not getattr(_action_object, 'published'):
        return None

    # Set verb
    _verb = 'edited'
    if klass == 'comment':
        _verb = 'commented'
        _notification = True
    elif not last:
        _verb = 'created'
        _notification = True

    # Add user as collaborator
    _target.collaborator.add(_user)
    _follow = _target

    # Action
    a = action.send(_user, verb=_verb, action_object=_action_object, target=_target)
    a[0][1].data = { 'diff': _diff, 'content': _content,
        'edit_message': _emsg, 'object': model_to_dict(_action_object)}
    a[0][1].save()
    activity_count(_target)
    follow(_user, _follow, actor_only=False) if not is_following(_user, _follow) else None
Example #36
0
def activity_register(_user, _action_object):
    """
    Registers and activity when an object is saved. Takes a diff with a
    previous version of edited objects, put it as message content in a
    timeline, uses the verbs 'created' or 'edited' for actions on actstream.
    """
    from lxml.html.diff import htmldiff

    from django.db.models.loading import get_model
    from django.forms import ValidationError
    from django.forms.models import model_to_dict
    from django.template.loader import render_to_string

    from actstream import action
    from actstream.actions import follow, is_following
    from actstream.models import action_object_stream

    klass = _action_object.__class__.__name__.lower()
    if klass not in ['problem', 'criteria', 'idea', 'alternative', 'comment']:
        raise forms.ValidationError(_('Wrong object type'))

    # Last activity
    last = (action_object_stream(_action_object)[:1] or [None])[0]
    _content_old = render_to_string('diffbase_' + klass +
                                    '.html', {klass: last}) if last else ''
    _content = render_to_string('diffbase_' + klass + '.html',
                                {klass: _action_object})
    _emsg = _action_object.edit_message if hasattr(_action_object,
                                                   'edit_message') else ''
    _diff = htmldiff(_content_old, _content)

    # Set target problem
    if klass in ['comment']:
        if getattr(_action_object, 'problem'):
            _target = getattr(_action_object, 'problem')
        else:
            for attr in ['criteria', 'idea', 'alternative']:
                if getattr(_action_object, attr):
                    _target = getattr(_action_object, attr)
                    break
            _target = getattr(_target, 'problem')
    elif klass in ['criteria', 'idea', 'alternative']:
        _target = getattr(_action_object, 'problem')
    elif klass in ['problem']:
        _target = _action_object

    # Don't do anything if the problem or the action object is a draft
    if hasattr(_action_object,
               'published') and not getattr(_action_object, 'published'):
        return None

    # Set verb
    _verb = 'edited'
    if klass == 'comment':
        _verb = 'commented'
        _notification = True
    elif not last:
        _verb = 'created'
        _notification = True

    # Add user as collaborator
    _target.collaborator.add(_user)
    _follow = _target

    # Action
    a = action.send(_user,
                    verb=_verb,
                    action_object=_action_object,
                    target=_target)
    a[0][1].data = {
        'diff': _diff,
        'content': _content,
        'edit_message': _emsg,
        'object': model_to_dict(_action_object)
    }
    a[0][1].save()
    activity_count(_target)
    follow(_user, _follow,
           actor_only=False) if not is_following(_user, _follow) else None
Example #37
0
    def save(self, *args, **kwargs):
        # invalidate older votes from the same voter to the same election
        old_votes = self.election.cast_votes.filter(is_direct=True,
            invalidated_at_date=None, voter=self.request.user)
        for old_vote in old_votes:
            old_vote.invalidated_at_date = datetime.datetime.now()
            old_vote.is_counted = False
            old_vote.save()
        vote = super(VoteForm, self).save(commit=False)

        # generate vote
        data = {
            "a": "vote",
            "answers": [],
            "election_hash": {"a": "hash/sha256/value", "value": self.election.hash},
            "election_uuid": self.election.uuid
        }
        i = 0
        for question in self.election.questions:
            data["answers"] += [self.cleaned_data['question%d' % i]]
            i += 1

        # fill the vote
        vote.voter = self.request.user
        vote.election = self.election
        vote.is_counted = self.election.has_perms('vote_counts', self.request.user)
        vote.is_direct = True

        # stablish if the vote is secret
        if self.election.is_vote_secret and self.cleaned_data['is_vote_secret']:
            vote.is_public = False
            vote.reason = None
        else:
            vote.reason = self.cleaned_data['reason']
            vote.is_public = True

        # assign data, create hash etc
        vote.data = data
        vote.casted_at_date = datetime.datetime.now()
        vote.create_hash()

        # create action
        actstream_action.send(self.request.user, verb='voted', action_object=self.election,
            target=self.election.agora,
            geolocation=json.dumps(geolocate_ip(self.request.META.get('REMOTE_ADDR'))))

        vote.action_id = Action.objects.filter(actor_object_id=self.request.user.id,
            verb='voted', action_object_object_id=self.election.id,
            target_object_id=self.election.agora.id).order_by('-timestamp').all()[0].id

        # send email

        vote.save()

        context = get_base_email_context(self.request)
        context.update(dict(
            to=self.request.user,
            election=self.election,
            election_url=self.election.get_link(),
            agora_url=self.election.get_link(),
        ))

        if self.request.user.has_perms('receive_email_updates'):
            translation.activate(self.request.user.get_profile().lang_code)
            email = EmailMultiAlternatives(
                subject=_('Vote casted for election %s') % self.election.pretty_name,
                body=render_to_string('agora_core/emails/vote_casted.txt',
                    context),
                to=[self.request.user.email])

            email.attach_alternative(
                render_to_string('agora_core/emails/vote_casted.html',
                    context), "text/html")
            email.send()
            translation.deactivate()

        if not is_following(self.request.user, self.election):
            follow(self.request.user, self.election, actor_only=False, request=self.request)

        return vote
Example #38
0
    def send(type, **kwargs):  # noqa: C901
        actor = kwargs.pop("actor", None)
        action_object = kwargs.pop("action_object", None)
        target = kwargs.pop("target", None)
        message = kwargs.pop("message", None)
        description = kwargs.pop("description", None)
        context_class = kwargs.pop("context_class", None)
        if (type == NotificationType.NotificationTypeChoices.FORUM_POST or type
                == NotificationType.NotificationTypeChoices.FORUM_POST_REPLY or
                type == NotificationType.NotificationTypeChoices.ACCESS_REQUEST
                and target._meta.model_name != "algorithm" or type
                == NotificationType.NotificationTypeChoices.REQUEST_UPDATE):
            if actor:
                receivers = [
                    follower for follower in followers(target)
                    if follower != actor
                ]
            else:
                receivers = followers(target)
        elif (type == NotificationType.NotificationTypeChoices.ACCESS_REQUEST
              and target._meta.model_name == "algorithm"):
            receivers = [
                follower
                for follower in followers(target, flag="access_request")
                if follower != actor
            ]
        elif type == NotificationType.NotificationTypeChoices.NEW_ADMIN:
            receivers = [action_object]
        elif (type ==
              NotificationType.NotificationTypeChoices.EVALUATION_STATUS):
            receivers = [
                admin for admin in target.challenge.get_admins()
                if is_following(admin, target)
            ]
            if actor and is_following(actor, target):
                receivers.append(actor)
        elif type == NotificationType.NotificationTypeChoices.MISSING_METHOD:
            receivers = [
                admin for admin in target.challenge.get_admins()
                if is_following(admin, target)
            ]
        elif type == NotificationType.NotificationTypeChoices.JOB_STATUS:
            receivers = [
                editor for editor in target.editors_group.user_set.all()
                if is_following(editor, target, flag="job-active")
            ]
            if actor and is_following(actor, target, flag="job-active"):
                receivers.append(actor)
        elif (type ==
              NotificationType.NotificationTypeChoices.IMAGE_IMPORT_STATUS):
            receivers = followers(action_object)

        for receiver in set(receivers):
            Notification.objects.create(
                user=receiver,
                type=type,
                message=message,
                actor=actor,
                action_object=action_object,
                target=target,
                description=description,
                context_class=context_class,
            )
Example #39
0
    def save(self, *args, **kwargs):
        # invalidate older votes from the same voter to the same election
        old_votes = self.agora.delegation_election.cast_votes.filter(
            is_direct=False, invalidated_at_date=None, voter=self.request.user)
        for old_vote in old_votes:
            old_vote.invalidated_at_date = timezone.now()
            old_vote.save()

        # Forge the delegation vote
        vote = CastVote()
        vote.data = {
            "a": "delegated-vote",
            "answers": [
                {
                    "a": "plaintext-delegate",
                    "choices": [
                        {
                            'user_id': self.delegate.id, # id of the User in which the voter delegates
                            'username': self.delegate.username,
                            'user_name': self.delegate.first_name, # data of the User in which the voter delegates
                        }
                    ]
                }
            ],
            "election_hash": {"a": "hash/sha256/value", "value": self.agora.delegation_election.hash},
            "election_uuid": self.agora.delegation_election.uuid
        }

        vote.voter = self.request.user
        vote.election = self.agora.delegation_election
        vote.is_counted = True # if the user can delegate, it means vote counts
        vote.is_direct = False
        vote.is_public = not self.agora.is_vote_secret
        vote.casted_at_date = timezone.now()
        vote.reason = self.cleaned_data['reason'] if not self.agora.is_vote_secret else ''
        vote.create_hash()
        vote.save()

        # Create the delegation action
        actstream_action.send(self.request.user, verb='delegated', action_object=vote,
            target=self.agora, ipaddr=self.request.META.get('REMOTE_ADDR'),
            geolocation=json.dumps(geolocate_ip(self.request.META.get('REMOTE_ADDR'))))

        vote.action_id = Action.objects.filter(actor_object_id=self.request.user.id,
            verb='delegated', action_object_object_id=vote.id,
            target_object_id=self.agora.id).order_by('-timestamp').all()[0].id


        # Send the email to the voter (and maybe to the delegate too!)
        context = get_base_email_context(self.request)
        context.update(dict(
            agora=self.agora,
            delegate=self.delegate,
            vote=vote
        ))

        # Mail to the voter
        if vote.voter.get_profile().has_perms('receive_email_updates'):
            translation.activate(self.request.user.get_profile().lang_code)
            context['to'] = vote.voter

            email = EmailMultiAlternatives(
                subject=_('%(site)s - You delegated your vote in %(agora)s') %\
                    dict(
                        site=Site.objects.get_current().domain,
                        agora=self.agora.get_full_name()
                    ),
                body=render_to_string('agora_core/emails/user_delegated.txt',
                    context),
                to=[vote.voter.email])

            email.attach_alternative(
                render_to_string('agora_core/emails/user_delegated.html',
                    context), "text/html")
            translation.deactivate()
            email.send()

        if vote.is_public and self.delegate.get_profile().has_perms('receive_email_updates'):
            translation.activate(self.request.user.get_profile().lang_code)
            context['to'] = self.delegate

            email = EmailMultiAlternatives(
                subject=_('%(site)s - You have a new delegation in %(agora)s') %\
                    dict(
                        site=Site.objects.get_current().domain,
                        agora=self.agora.get_full_name()
                    ),
                body=render_to_string('agora_core/emails/new_delegation.txt',
                    context),
                to=[self.delegate.email])

            email.attach_alternative(
                render_to_string('agora_core/emails/new_delegation.html',
                    context), "text/html")
            email.send()
            translation.deactivate()

        if not is_following(self.request.user, self.delegate) and vote.is_public:
            follow(self.request.user, self.delegate, actor_only=False,
                request=self.request)

        return vote
Example #40
0
def follow_book(request, pk):
    book = get_object_or_404(Book, pk=pk)
    if not is_following(request.user, book):
        follow(request.user, book)
        return render(request, 'detail.html', {'book': book, 'form': ReviewForm, 'message': 'You are following this book.'})
    return render(request, 'detail.html', {'book': book, 'form': ReviewForm, 'message': 'You already follow this book.'})
Example #41
0
def unfollow_book(request, pk):
    book = get_object_or_404(Book, pk=pk)
    if is_following(request.user, book):
        unfollow(request.user, book)
        return render(request, 'detail.html', {'book': book, 'form': ReviewForm(), 'message': 'You unfollowed this book.'})    
    return render(request, 'detail.html', {'book': book, 'form': ReviewForm(), 'message': 'You do not follow this book yet.'})
Example #42
0
def es_favorito(request, post):
	return is_following(request.user,post)