def remove_member(portfolio_id, portfolio_role_id): portfolio_role = PortfolioRoles.get_by_id(portfolio_role_id) if g.current_user.id == portfolio_role.user_id: raise UnauthorizedError(g.current_user, "you cant remove yourself from the portfolio") portfolio = Portfolios.get(user=g.current_user, portfolio_id=portfolio_id) if portfolio_role.user_id == portfolio.owner.id: raise UnauthorizedError( g.current_user, "you can't delete the portfolios PPoC from the portfolio") if (portfolio_role.latest_invitation and portfolio_role.status == PortfolioRoleStatus.PENDING): PortfolioInvitations.revoke(portfolio_role.latest_invitation.token) else: PortfolioRoles.disable(portfolio_role=portfolio_role) flash("portfolio_member_removed", member_name=portfolio_role.full_name) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio_id, _anchor="portfolio-members", fragment="portfolio-members", ))
def test_wrong_user_accepts_invitation(): user = UserFactory.create() portfolio = PortfolioFactory.create() role = PortfolioRoleFactory.create(portfolio=portfolio) wrong_user = UserFactory.create() invite = PortfolioInvitationFactory.create(role=role, dod_id=user.dod_id) with pytest.raises(WrongUserError): PortfolioInvitations.accept(wrong_user, invite.token) assert invite.role.status == PortfolioRoleStatus.PENDING
def test_accept_invitation_twice(): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create(portfolio=portfolio) invite = PortfolioInvitationFactory.create(role=role, dod_id=user.dod_id) PortfolioInvitations.accept(user, invite.token) with pytest.raises(InvitationError): PortfolioInvitations.accept(user, invite.token) assert invite.role.is_active
def test_revoke_invitation(): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create(user=user, portfolio=portfolio) invite = PortfolioInvitationFactory.create(role=role, dod_id=user.dod_id) assert invite.is_pending PortfolioInvitations.revoke(invite.token) assert invite.is_revoked assert invite.role.status == PortfolioRoleStatus.DISABLED
def revoke_invitation(portfolio_id, portfolio_token): PortfolioInvitations.revoke(portfolio_token) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio_id, _anchor="portfolio-members", fragment="portfolio-members", ))
def test_accept_revoked_invite(): user = UserFactory.create() portfolio = PortfolioFactory.create() role = PortfolioRoleFactory.create(portfolio=portfolio) invite = PortfolioInvitationFactory.create(status=InvitationStatus.REVOKED, role=role, dod_id=user.dod_id) with pytest.raises(InvitationError): PortfolioInvitations.accept(user, invite.token) assert invite.role.status == PortfolioRoleStatus.PENDING
def test_accept_invitation(): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create(user=user, portfolio=portfolio) invite = PortfolioInvitations.create(portfolio.owner, role, user.to_dictionary(), commit=True) assert invite.is_pending accepted_invite = PortfolioInvitations.accept(user, invite.token) assert accepted_invite.is_accepted assert accepted_invite.role.is_active
class PortfolioInvitationFactory(Base): class Meta: model = PortfolioInvitation email = factory.Faker("email") status = InvitationStatus.PENDING expiration_time = PortfolioInvitations.current_expiration_time()
class ApplicationInvitationFactory(Base): class Meta: model = ApplicationInvitation email = factory.Faker("email") status = InvitationStatus.PENDING expiration_time = PortfolioInvitations.current_expiration_time() role = factory.SubFactory(ApplicationRoleFactory)
def test_accept_expired_invitation(): user = UserFactory.create() portfolio = PortfolioFactory.create() role = PortfolioRoleFactory.create(portfolio=portfolio) increment = PortfolioInvitations.EXPIRATION_LIMIT_MINUTES + 1 expiration_time = datetime.datetime.now() - datetime.timedelta( minutes=increment) invite = PortfolioInvitationFactory.create( expiration_time=expiration_time, status=InvitationStatus.PENDING, role=role, dod_id=user.dod_id, ) with pytest.raises(ExpiredError): PortfolioInvitations.accept(user, invite.token) assert invite.is_rejected assert invite.role.status == PortfolioRoleStatus.PENDING
def test_resend_invitation(session): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create(portfolio=portfolio) first_invite = PortfolioInvitationFactory.create(role=role, dod_id=user.dod_id) assert first_invite.is_pending second_invite = PortfolioInvitations.resend(user, first_invite.token) assert first_invite.is_revoked assert second_invite.is_pending
def test_audit_event_for_accepted_invite(): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create(portfolio=portfolio) invite = PortfolioInvitationFactory.create(role=role, dod_id=user.dod_id) invite = PortfolioInvitations.accept(user, invite.token) accepted_event = AuditLog.get_by_resource(invite.id)[0] assert "email" in accepted_event.event_details assert "dod_id" in accepted_event.event_details
def invite(cls, portfolio, inviter, member_data): permission_sets = PortfolioRoles._permission_sets_for_names( member_data.get("permission_sets", [])) role = PortfolioRole(portfolio=portfolio, permission_sets=permission_sets) invitation = PortfolioInvitations.create( inviter=inviter, role=role, member_data=member_data["user_data"]) PortfoliosQuery.add_and_commit(role) return invitation
def test_create_invitation(): portfolio = PortfolioFactory.create() user = UserFactory.create() role = PortfolioRoleFactory.create(user=user, portfolio=portfolio) invite = PortfolioInvitations.create(portfolio.owner, role, user.to_dictionary(), commit=True) assert invite.role == role assert invite.inviter == portfolio.owner assert invite.status == InvitationStatus.PENDING assert re.match(r"^[\w\-_]+$", invite.token) assert invite.role.status == PortfolioRoleStatus.PENDING
def resend_invitation(portfolio_id, portfolio_token): invite = PortfolioInvitations.resend(g.current_user, portfolio_token) send_portfolio_invitation( invitee_email=invite.email, inviter_name=g.current_user.full_name, token=invite.token, ) flash("resend_portfolio_invitation", user_name=invite.user_name) return redirect( url_for( "portfolios.admin", portfolio_id=portfolio_id, fragment="portfolio-members", _anchor="portfolio-members", ))
class PortfolioInvitationFactory(Base): class Meta: model = PortfolioInvitation email = factory.Faker("email") status = InvitationStatus.PENDING expiration_time = PortfolioInvitations.current_expiration_time() dod_id = factory.LazyFunction(random_dod_id) first_name = factory.Faker("first_name") last_name = factory.Faker("last_name") @classmethod def _create(cls, model_class, *args, **kwargs): inviter_id = kwargs.pop("inviter_id", UserFactory.create().id) return super()._create(model_class, inviter_id=inviter_id, *args, **kwargs)
def accept_invitation(portfolio_token): invite = PortfolioInvitations.accept(g.current_user, portfolio_token) return redirect( url_for("applications.portfolio_applications", portfolio_id=invite.portfolio.id))