Ejemplo n.º 1
0
    def test_added_as_collaborator_email(
            self, pyramid_request, pyramid_config, monkeypatch):

        stub_user = pretend.stub(
            email='*****@*****.**',
            username='******',
            name="",
        )
        stub_submitter_user = pretend.stub(
            email='submiteremail',
            username='******'
        )
        subject_renderer = pyramid_config.testing_add_renderer(
            'email/added-as-collaborator.subject.txt'
        )
        subject_renderer.string_response = 'Email Subject'
        body_renderer = pyramid_config.testing_add_renderer(
            'email/added-as-collaborator.body.txt'
        )
        body_renderer.string_response = 'Email Body'

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None)
        )
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email
        )
        monkeypatch.setattr(email, 'send_email', send_email)

        result = email.send_added_as_collaborator_email(
            pyramid_request,
            submitter=stub_submitter_user,
            project_name='test_project',
            role='Owner',
            user=stub_user,
        )

        assert result == {
            'project': 'test_project',
            'role': 'Owner',
            'submitter': stub_submitter_user.username
        }
        subject_renderer.assert_()
        body_renderer.assert_(submitter=stub_submitter_user.username)
        body_renderer.assert_(project='test_project')
        body_renderer.assert_(role='Owner')

        assert pyramid_request.task.calls == [
            pretend.call(send_email),
        ]
        assert send_email.delay.calls == [
            pretend.call(
                'Email Subject',
                'Email Body',
                recipient="username <*****@*****.**>",
            ),
        ]
Ejemplo n.º 2
0
    def test_added_as_collaborator_email(
            self, pyramid_request, pyramid_config, monkeypatch):

        stub_user = pretend.stub(
            email='email',
            username='******',
        )
        stub_submitter_user = pretend.stub(
            email='submiteremail',
            username='******'
        )
        subject_renderer = pyramid_config.testing_add_renderer(
            'email/added-as-collaborator.subject.txt'
        )
        subject_renderer.string_response = 'Email Subject'
        body_renderer = pyramid_config.testing_add_renderer(
            'email/added-as-collaborator.body.txt'
        )
        body_renderer.string_response = 'Email Body'

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None)
        )
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email
        )
        monkeypatch.setattr(email, 'send_email', send_email)

        result = email.send_added_as_collaborator_email(
            pyramid_request,
            submitter=stub_submitter_user,
            project_name='test_project',
            role='Owner',
            user_email=stub_user.email
        )

        assert result == {
            'project': 'test_project',
            'role': 'Owner',
            'submitter': stub_submitter_user.username
        }
        subject_renderer.assert_()
        body_renderer.assert_(submitter=stub_submitter_user.username)
        body_renderer.assert_(project='test_project')
        body_renderer.assert_(role='Owner')

        assert pyramid_request.task.calls == [
            pretend.call(send_email),
        ]
        assert send_email.delay.calls == [
            pretend.call(
                'Email Body',
                'Email Subject',
                recipients=[stub_user.email],
            ),
        ]
Ejemplo n.º 3
0
    def test_added_as_collaborator_email_unverified(
        self, pyramid_request, pyramid_config, monkeypatch
    ):

        stub_user = pretend.stub(
            username="******",
            name="",
            email="*****@*****.**",
            primary_email=pretend.stub(email="*****@*****.**", verified=False),
        )
        stub_submitter_user = pretend.stub(
            username="******", email="submiteremail"
        )
        subject_renderer = pyramid_config.testing_add_renderer(
            "email/added-as-collaborator/subject.txt"
        )
        subject_renderer.string_response = "Email Subject"
        body_renderer = pyramid_config.testing_add_renderer(
            "email/added-as-collaborator/body.txt"
        )
        body_renderer.string_response = "Email Body"
        html_renderer = pyramid_config.testing_add_renderer(
            "email/added-as-collaborator/body.html"
        )
        html_renderer.string_response = "Email HTML Body"

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None)
        )
        pyramid_request.task = pretend.call_recorder(lambda *args, **kwargs: send_email)
        monkeypatch.setattr(email, "send_email", send_email)

        result = email.send_added_as_collaborator_email(
            pyramid_request,
            stub_user,
            submitter=stub_submitter_user,
            project_name="test_project",
            role="Owner",
        )

        assert result == {
            "project": "test_project",
            "role": "Owner",
            "submitter": stub_submitter_user.username,
        }
        subject_renderer.assert_()
        body_renderer.assert_(submitter=stub_submitter_user.username)
        body_renderer.assert_(project="test_project")
        body_renderer.assert_(role="Owner")
        html_renderer.assert_(submitter=stub_submitter_user.username)
        html_renderer.assert_(project="test_project")
        html_renderer.assert_(role="Owner")

        assert pyramid_request.task.calls == []
        assert send_email.delay.calls == []
Ejemplo n.º 4
0
    def test_added_as_collaborator_email_unverified(self, pyramid_request,
                                                    pyramid_config,
                                                    monkeypatch):

        stub_user = pretend.stub(
            username="******",
            name="",
            email="*****@*****.**",
            primary_email=pretend.stub(email="*****@*****.**",
                                       verified=False),
        )
        stub_submitter_user = pretend.stub(username="******",
                                           email="submiteremail")
        subject_renderer = pyramid_config.testing_add_renderer(
            "email/added-as-collaborator/subject.txt")
        subject_renderer.string_response = "Email Subject"
        body_renderer = pyramid_config.testing_add_renderer(
            "email/added-as-collaborator/body.txt")
        body_renderer.string_response = "Email Body"
        html_renderer = pyramid_config.testing_add_renderer(
            "email/added-as-collaborator/body.html")
        html_renderer.string_response = "Email HTML Body"

        send_email = pretend.stub(
            delay=pretend.call_recorder(lambda *args, **kwargs: None))
        pyramid_request.task = pretend.call_recorder(
            lambda *args, **kwargs: send_email)
        monkeypatch.setattr(email, "send_email", send_email)

        result = email.send_added_as_collaborator_email(
            pyramid_request,
            stub_user,
            submitter=stub_submitter_user,
            project_name="test_project",
            role="Owner",
        )

        assert result == {
            "project": "test_project",
            "role": "Owner",
            "submitter": stub_submitter_user.username,
        }
        subject_renderer.assert_()
        body_renderer.assert_(submitter=stub_submitter_user.username)
        body_renderer.assert_(project="test_project")
        body_renderer.assert_(role="Owner")
        html_renderer.assert_(submitter=stub_submitter_user.username)
        html_renderer.assert_(project="test_project")
        html_renderer.assert_(role="Owner")

        assert pyramid_request.task.calls == []
        assert send_email.delay.calls == []
Ejemplo n.º 5
0
def manage_project_roles(project, request, _form_class=CreateRoleForm):
    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)

    if request.method == "POST" and form.validate():
        username = form.username.data
        role_name = form.role_name.data
        userid = user_service.find_userid(username)
        user = user_service.get_user(userid)

        if request.db.query(
                request.db.query(Role).filter(
                    Role.user == user, Role.project == project,
                    Role.role_name == role_name).exists()).scalar():
            request.session.flash(
                f"User '{username}' already has {role_name} role for project",
                queue="error",
            )
        elif user.primary_email is None or not user.primary_email.verified:
            request.session.flash(
                f"User '{username}' does not have a verified primary email "
                f"address and cannot be added as a {role_name} for project",
                queue="error",
            )
        else:
            request.db.add(
                Role(user=user, project=project,
                     role_name=form.role_name.data))
            request.db.add(
                JournalEntry(
                    name=project.name,
                    action=f"add {role_name} {username}",
                    submitted_by=request.user,
                    submitted_from=request.remote_addr,
                ))
            project.record_event(
                tag="project:role:add",
                ip_address=request.remote_addr,
                additional={
                    "submitted_by": request.user.username,
                    "role_name": role_name,
                    "target_user": username,
                },
            )

            owner_roles = (request.db.query(Role).join(Role.user).filter(
                Role.role_name == "Owner", Role.project == project))
            owner_users = {owner.user for owner in owner_roles}

            # Don't send to the owner that added the new role
            owner_users.discard(request.user)

            # Don't send owners email to new user if they are now an owner
            owner_users.discard(user)

            send_collaborator_added_email(
                request,
                owner_users,
                user=user,
                submitter=request.user,
                project_name=project.name,
                role=form.role_name.data,
            )

            send_added_as_collaborator_email(
                request,
                user,
                submitter=request.user,
                project_name=project.name,
                role=form.role_name.data,
            )

            request.session.flash(f"Added collaborator '{form.username.data}'",
                                  queue="success")
        form = _form_class(user_service=user_service)

    roles = request.db.query(Role).join(User).filter(
        Role.project == project).all()

    # TODO: The following lines are a hack to handle multiple roles for a
    # single user and should be removed when fixing GH-2745
    roles_by_user = defaultdict(list)
    for role in roles:
        roles_by_user[role.user.username].append(role)

    return {"project": project, "roles_by_user": roles_by_user, "form": form}
Ejemplo n.º 6
0
def verify_project_role(request):
    token_service = request.find_service(ITokenService, name="email")
    user_service = request.find_service(IUserService, context=None)

    def _error(message):
        request.session.flash(message, queue="error")
        return HTTPSeeOther(request.route_path("manage.projects"))

    try:
        token = request.params.get("token")
        data = token_service.loads(token)
    except TokenExpired:
        return _error(request._("Expired token: request a new project role invite"))
    except TokenInvalid:
        return _error(request._("Invalid token: request a new project role invite"))
    except TokenMissing:
        return _error(request._("Invalid token: no token supplied"))

    # Check whether this token is being used correctly
    if data.get("action") != "email-project-role-verify":
        return _error(request._("Invalid token: not a collaboration invitation token"))

    user = user_service.get_user(data.get("user_id"))
    if user != request.user:
        return _error(request._("Role invitation is not valid."))

    project = (
        request.db.query(Project).filter(Project.id == data.get("project_id")).one()
    )
    desired_role = data.get("desired_role")

    role_invite = (
        request.db.query(RoleInvitation)
        .filter(RoleInvitation.project == project)
        .filter(RoleInvitation.user == user)
        .one_or_none()
    )

    if not role_invite:
        return _error(request._("Role invitation no longer exists."))

    # Use the renderer to bring up a confirmation page
    # before adding as contributor
    if request.method == "GET":
        return {
            "project_name": project.name,
            "desired_role": desired_role,
        }
    elif request.method == "POST" and "decline" in request.POST:
        request.db.delete(role_invite)
        request.session.flash(
            request._(
                "Invitation for '${project_name}' is declined.",
                mapping={"project_name": project.name},
            ),
            queue="success",
        )
        return HTTPSeeOther(request.route_path("manage.projects"))

    request.db.add(Role(user=user, project=project, role_name=desired_role))
    request.db.delete(role_invite)
    request.db.add(
        JournalEntry(
            name=project.name,
            action=f"accepted {desired_role} {user.username}",
            submitted_by=request.user,
            submitted_from=request.remote_addr,
        )
    )
    project.record_event(
        tag="project:role:accepted",
        ip_address=request.remote_addr,
        additional={
            "submitted_by": request.user.username,
            "role_name": desired_role,
            "target_user": user.username,
        },
    )
    user.record_event(
        tag="account:role:accepted",
        ip_address=request.remote_addr,
        additional={
            "submitted_by": request.user.username,
            "project_name": project.name,
            "role_name": desired_role,
        },
    )

    owner_roles = (
        request.db.query(Role)
        .filter(Role.project == project)
        .filter(Role.role_name == "Owner")
        .all()
    )
    owner_users = {owner.user for owner in owner_roles}

    # Don't send email to new user if they are now an owner
    owner_users.discard(user)

    submitter_user = user_service.get_user(data.get("submitter_id"))
    send_collaborator_added_email(
        request,
        owner_users,
        user=user,
        submitter=submitter_user,
        project_name=project.name,
        role=desired_role,
    )

    send_added_as_collaborator_email(
        request,
        user,
        submitter=submitter_user,
        project_name=project.name,
        role=desired_role,
    )

    request.session.flash(
        request._(
            "You are now ${role} of the '${project_name}' project.",
            mapping={"project_name": project.name, "role": desired_role},
        ),
        queue="success",
    )

    if desired_role == "Owner":
        return HTTPSeeOther(
            request.route_path("manage.project.roles", project_name=project.name)
        )
    else:
        return HTTPSeeOther(request.route_path("packaging.project", name=project.name))
Ejemplo n.º 7
0
def manage_project_roles(project, request, _form_class=CreateRoleForm):
    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)

    if request.method == "POST" and form.validate():
        username = form.username.data
        role_name = form.role_name.data
        userid = user_service.find_userid(username)
        user = user_service.get_user(userid)

        if request.db.query(
            request.db.query(Role)
            .filter(
                Role.user == user, Role.project == project, Role.role_name == role_name
            )
            .exists()
        ).scalar():
            request.session.flash(
                f"User '{username}' already has {role_name} role for project",
                queue="error",
            )
        elif user.primary_email is None or not user.primary_email.verified:
            request.session.flash(
                f"User '{username}' does not have a verified primary email "
                f"address and cannot be added as a {role_name} for project.",
                queue="error",
            )
        else:
            request.db.add(
                Role(user=user, project=project, role_name=form.role_name.data)
            )
            request.db.add(
                JournalEntry(
                    name=project.name,
                    action=f"add {role_name} {username}",
                    submitted_by=request.user,
                    submitted_from=request.remote_addr,
                )
            )

            owner_roles = (
                request.db.query(Role)
                .join(Role.user)
                .filter(Role.role_name == "Owner", Role.project == project)
            )
            owner_users = {owner.user for owner in owner_roles}

            # Don't send to the owner that added the new role
            owner_users.discard(request.user)

            # Don't send owners email to new user if they are now an owner
            owner_users.discard(user)

            send_collaborator_added_email(
                request,
                owner_users,
                user=user,
                submitter=request.user,
                project_name=project.name,
                role=form.role_name.data,
            )

            send_added_as_collaborator_email(
                request,
                user,
                submitter=request.user,
                project_name=project.name,
                role=form.role_name.data,
            )

            request.session.flash(
                f"Added collaborator '{form.username.data}'", queue="success"
            )
        form = _form_class(user_service=user_service)

    roles = request.db.query(Role).join(User).filter(Role.project == project).all()

    # TODO: The following lines are a hack to handle multiple roles for a
    # single user and should be removed when fixing GH-2745
    roles_by_user = defaultdict(list)
    for role in roles:
        roles_by_user[role.user.username].append(role)

    return {"project": project, "roles_by_user": roles_by_user, "form": form}
Ejemplo n.º 8
0
def manage_project_roles(project, request, _form_class=CreateRoleForm):
    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)

    if request.method == "POST" and form.validate():
        username = form.username.data
        role_name = form.role_name.data
        userid = user_service.find_userid(username)
        user = user_service.get_user(userid)

        if (request.db.query(
                request.db.query(Role).filter(
                    Role.user == user,
                    Role.project == project,
                    Role.role_name == role_name,
                )
                .exists()).scalar()):
            request.session.flash(
                f"User '{username}' already has {role_name} role for project",
                queue="error"
            )
        else:
            request.db.add(
                Role(user=user, project=project, role_name=form.role_name.data)
            )
            request.db.add(
                JournalEntry(
                    name=project.name,
                    action=f"add {role_name} {username}",
                    submitted_by=request.user,
                    submitted_from=request.remote_addr,
                ),
            )

            owners = (
                request.db.query(Role)
                .join(Role.user)
                .filter(Role.role_name == 'Owner', Role.project == project)
            )
            owner_emails = [owner.user.email for owner in owners]
            owner_emails.remove(request.user.email)

            send_collaborator_added_email(
                request,
                user,
                request.user,
                project.name,
                form.role_name.data,
                owner_emails
            )

            send_added_as_collaborator_email(
                request,
                request.user,
                project.name,
                form.role_name.data,
                user.email
            )

            request.session.flash(
                f"Added collaborator '{form.username.data}'",
                queue="success"
            )
        form = _form_class(user_service=user_service)

    roles = (
        request.db.query(Role)
        .join(User)
        .filter(Role.project == project)
        .all()
    )

    # TODO: The following lines are a hack to handle multiple roles for a
    # single user and should be removed when fixing GH-2745
    roles_by_user = defaultdict(list)
    for role in roles:
        roles_by_user[role.user.username].append(role)

    return {
        "project": project,
        "roles_by_user": roles_by_user,
        "form": form,
    }
Ejemplo n.º 9
0
def manage_project_roles(project, request, _form_class=CreateRoleForm):
    user_service = request.find_service(IUserService, context=None)
    form = _form_class(request.POST, user_service=user_service)

    if request.method == "POST" and form.validate():
        username = form.username.data
        role_name = form.role_name.data
        userid = user_service.find_userid(username)
        user = user_service.get_user(userid)

        if (request.db.query(
                request.db.query(Role).filter(
                    Role.user == user,
                    Role.project == project,
                    Role.role_name == role_name,
                ).exists()).scalar()):
            request.session.flash(
                f"User '{username}' already has {role_name} role for project",
                queue="error")
        else:
            request.db.add(
                Role(user=user, project=project,
                     role_name=form.role_name.data))
            request.db.add(
                JournalEntry(
                    name=project.name,
                    action=f"add {role_name} {username}",
                    submitted_by=request.user,
                    submitted_from=request.remote_addr,
                ), )

            owners = (request.db.query(Role).join(Role.user).filter(
                Role.role_name == 'Owner', Role.project == project))
            owner_emails = [owner.user.email for owner in owners]
            owner_emails.remove(request.user.email)

            send_collaborator_added_email(request, user, request.user,
                                          project.name, form.role_name.data,
                                          owner_emails)

            send_added_as_collaborator_email(request, request.user,
                                             project.name, form.role_name.data,
                                             user.email)

            request.session.flash(f"Added collaborator '{form.username.data}'",
                                  queue="success")
        form = _form_class(user_service=user_service)

    roles = (request.db.query(Role).join(User).filter(
        Role.project == project).all())

    # TODO: The following lines are a hack to handle multiple roles for a
    # single user and should be removed when fixing GH-2745
    roles_by_user = defaultdict(list)
    for role in roles:
        roles_by_user[role.user.username].append(role)

    return {
        "project": project,
        "roles_by_user": roles_by_user,
        "form": form,
    }