Prevent invitations without a workspace role

This commit is contained in:
Montana
2018-12-03 16:49:59 -05:00
parent ee18b704b2
commit 9ddac1fa61
5 changed files with 106 additions and 30 deletions

View File

@@ -112,4 +112,4 @@ class Invitation(Base, TimestampsMixin, AuditableMixin):
@property @property
def workspace_id(self): def workspace_id(self):
return self.workspace_role.workspace_id if self.workspace_role else None return self.workspace_role.workspace_id

View File

@@ -44,10 +44,15 @@ def test_accept_invitation():
def test_accept_expired_invitation(): def test_accept_expired_invitation():
user = UserFactory.create() user = UserFactory.create()
workspace = WorkspaceFactory.create()
ws_role = WorkspaceRoleFactory.create(user=user, workspace=workspace)
increment = Invitations.EXPIRATION_LIMIT_MINUTES + 1 increment = Invitations.EXPIRATION_LIMIT_MINUTES + 1
expiration_time = datetime.datetime.now() - datetime.timedelta(minutes=increment) expiration_time = datetime.datetime.now() - datetime.timedelta(minutes=increment)
invite = InvitationFactory.create( invite = InvitationFactory.create(
user=user, expiration_time=expiration_time, status=Status.PENDING user=user,
expiration_time=expiration_time,
status=Status.PENDING,
workspace_role=ws_role,
) )
with pytest.raises(ExpiredError): with pytest.raises(ExpiredError):
Invitations.accept(user, invite.token) Invitations.accept(user, invite.token)
@@ -57,30 +62,42 @@ def test_accept_expired_invitation():
def test_accept_rejected_invite(): def test_accept_rejected_invite():
user = UserFactory.create() user = UserFactory.create()
invite = InvitationFactory.create(user=user, status=Status.REJECTED_EXPIRED) workspace = WorkspaceFactory.create()
ws_role = WorkspaceRoleFactory.create(user=user, workspace=workspace)
invite = InvitationFactory.create(
user=user, status=Status.REJECTED_EXPIRED, workspace_role=ws_role
)
with pytest.raises(InvitationError): with pytest.raises(InvitationError):
Invitations.accept(user, invite.token) Invitations.accept(user, invite.token)
def test_accept_revoked_invite(): def test_accept_revoked_invite():
user = UserFactory.create() user = UserFactory.create()
invite = InvitationFactory.create(user=user, status=Status.REVOKED) workspace = WorkspaceFactory.create()
ws_role = WorkspaceRoleFactory.create(user=user, workspace=workspace)
invite = InvitationFactory.create(
user=user, status=Status.REVOKED, workspace_role=ws_role
)
with pytest.raises(InvitationError): with pytest.raises(InvitationError):
Invitations.accept(user, invite.token) Invitations.accept(user, invite.token)
def test_wrong_user_accepts_invitation(): def test_wrong_user_accepts_invitation():
user = UserFactory.create() user = UserFactory.create()
workspace = WorkspaceFactory.create()
ws_role = WorkspaceRoleFactory.create(user=user, workspace=workspace)
wrong_user = UserFactory.create() wrong_user = UserFactory.create()
invite = InvitationFactory.create(user=user) invite = InvitationFactory.create(user=user, workspace_role=ws_role)
with pytest.raises(WrongUserError): with pytest.raises(WrongUserError):
Invitations.accept(wrong_user, invite.token) Invitations.accept(wrong_user, invite.token)
def test_user_cannot_accept_invitation_accepted_by_wrong_user(): def test_user_cannot_accept_invitation_accepted_by_wrong_user():
user = UserFactory.create() user = UserFactory.create()
workspace = WorkspaceFactory.create()
ws_role = WorkspaceRoleFactory.create(user=user, workspace=workspace)
wrong_user = UserFactory.create() wrong_user = UserFactory.create()
invite = InvitationFactory.create(user=user) invite = InvitationFactory.create(user=user, workspace_role=ws_role)
with pytest.raises(WrongUserError): with pytest.raises(WrongUserError):
Invitations.accept(wrong_user, invite.token) Invitations.accept(wrong_user, invite.token)
with pytest.raises(InvitationError): with pytest.raises(InvitationError):

View File

@@ -2,22 +2,44 @@ import pytest
import datetime import datetime
from atst.models.invitation import Invitation, Status from atst.models.invitation import Invitation, Status
from atst.models.workspace_role import Status as WorkspaceRoleStatus
from tests.factories import InvitationFactory from tests.factories import (
InvitationFactory,
WorkspaceFactory,
UserFactory,
WorkspaceRoleFactory,
)
def test_expired_invite_is_not_revokable(): def test_expired_invite_is_not_revokable():
workspace = WorkspaceFactory.create()
user = UserFactory.create()
ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
)
invite = InvitationFactory.create( invite = InvitationFactory.create(
expiration_time=datetime.datetime.now() - datetime.timedelta(minutes=60) expiration_time=datetime.datetime.now() - datetime.timedelta(minutes=60),
workspace_role=ws_role,
) )
assert not invite.is_revokable assert not invite.is_revokable
def test_unexpired_invite_is_revokable(): def test_unexpired_invite_is_revokable():
invite = InvitationFactory.create() workspace = WorkspaceFactory.create()
user = UserFactory.create()
ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
)
invite = InvitationFactory.create(workspace_role=ws_role)
assert invite.is_revokable assert invite.is_revokable
def test_invite_is_not_revokable_if_invite_is_not_pending(): def test_invite_is_not_revokable_if_invite_is_not_pending():
invite = InvitationFactory.create(status=Status.ACCEPTED) workspace = WorkspaceFactory.create()
user = UserFactory.create()
ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
)
invite = InvitationFactory.create(workspace_role=ws_role, status=Status.ACCEPTED)
assert not invite.is_revokable assert not invite.is_revokable

View File

@@ -7,6 +7,7 @@ from atst.models.workspace_role import Status
from atst.models.role import Role from atst.models.role import Role
from atst.models.invitation import Status as InvitationStatus from atst.models.invitation import Status as InvitationStatus
from atst.models.audit_event import AuditEvent from atst.models.audit_event import AuditEvent
from atst.models.workspace_role import Status as WorkspaceRoleStatus
from tests.factories import ( from tests.factories import (
RequestFactory, RequestFactory,
UserFactory, UserFactory,
@@ -196,44 +197,69 @@ def test_status_when_member_is_active():
def test_status_when_invitation_has_been_rejected_for_expirations(): def test_status_when_invitation_has_been_rejected_for_expirations():
workspace_role = WorkspaceRoleFactory.create( workspace = WorkspaceFactory.create()
invitations=[InvitationFactory.create(status=InvitationStatus.REJECTED_EXPIRED)] user = UserFactory.create()
ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
) )
invitation = InvitationFactory.create(
workspace_role=ws_role, status=InvitationStatus.REJECTED_EXPIRED
)
workspace_role = WorkspaceRoleFactory.create(invitations=[invitation])
assert workspace_role.display_status == "Invite expired" assert workspace_role.display_status == "Invite expired"
def test_status_when_invitation_has_been_rejected_for_wrong_user(): def test_status_when_invitation_has_been_rejected_for_wrong_user():
workspace_role = WorkspaceRoleFactory.create( workspace = WorkspaceFactory.create()
invitations=[ user = UserFactory.create()
InvitationFactory.create(status=InvitationStatus.REJECTED_WRONG_USER) ws_role = WorkspaceRoleFactory.create(
] workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
) )
invitation = InvitationFactory.create(
workspace_role=ws_role, status=InvitationStatus.REJECTED_WRONG_USER
)
workspace_role = WorkspaceRoleFactory.create(invitations=[invitation])
assert workspace_role.display_status == "Error on invite" assert workspace_role.display_status == "Error on invite"
def test_status_when_invitation_is_expired(): def test_status_when_invitation_is_expired():
workspace_role = WorkspaceRoleFactory.create( workspace = WorkspaceFactory.create()
invitations=[ user = UserFactory.create()
InvitationFactory.create( ws_role = WorkspaceRoleFactory.create(
status=InvitationStatus.PENDING, workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1),
)
]
) )
invitation = InvitationFactory.create(
workspace_role=ws_role,
status=InvitationStatus.PENDING,
expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1),
)
workspace_role = WorkspaceRoleFactory.create(invitations=[invitation])
assert workspace_role.display_status == "Invite expired" assert workspace_role.display_status == "Invite expired"
def test_can_not_resend_invitation_if_active(): def test_can_not_resend_invitation_if_active():
workspace_role = WorkspaceRoleFactory.create( workspace = WorkspaceFactory.create()
invitations=[InvitationFactory.create(status=InvitationStatus.ACCEPTED)] user = UserFactory.create()
ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
) )
invitation = InvitationFactory.create(
workspace_role=ws_role, status=InvitationStatus.ACCEPTED
)
workspace_role = WorkspaceRoleFactory.create(invitations=[invitation])
assert not workspace_role.can_resend_invitation assert not workspace_role.can_resend_invitation
def test_can_resend_invitation_if_expired(): def test_can_resend_invitation_if_expired():
workspace_role = WorkspaceRoleFactory.create( workspace = WorkspaceFactory.create()
invitations=[InvitationFactory.create(status=InvitationStatus.REJECTED_EXPIRED)] user = UserFactory.create()
ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
) )
invitation = InvitationFactory.create(
workspace_role=ws_role, status=InvitationStatus.REJECTED_EXPIRED
)
workspace_role = WorkspaceRoleFactory.create(invitations=[invitation])
assert workspace_role.can_resend_invitation assert workspace_role.can_resend_invitation

View File

@@ -19,7 +19,9 @@ def test_existing_member_accepts_valid_invite(client, user_session):
ws_role = WorkspaceRoleFactory.create( ws_role = WorkspaceRoleFactory.create(
workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING workspace=workspace, user=user, status=WorkspaceRoleStatus.PENDING
) )
invite = InvitationFactory.create(user_id=user.id, workspace_role_id=ws_role.id) invite = InvitationFactory.create(
user_id=user.id, workspace_role=ws_role, workspace_role_id=ws_role.id
)
# the user does not have access to the workspace before accepting the invite # the user does not have access to the workspace before accepting the invite
assert len(Workspaces.for_user(user)) == 0 assert len(Workspaces.for_user(user)) == 0
@@ -76,6 +78,7 @@ def test_member_accepts_invalid_invite(client, user_session):
) )
invite = InvitationFactory.create( invite = InvitationFactory.create(
user_id=user.id, user_id=user.id,
workspace_role=ws_role,
workspace_role_id=ws_role.id, workspace_role_id=ws_role.id,
status=InvitationStatus.REJECTED_WRONG_USER, status=InvitationStatus.REJECTED_WRONG_USER,
) )
@@ -109,7 +112,9 @@ def test_user_accepts_invite_with_wrong_dod_id(client, user_session):
ws_role = WorkspaceRoleFactory.create( ws_role = WorkspaceRoleFactory.create(
user=user, workspace=workspace, status=WorkspaceRoleStatus.PENDING user=user, workspace=workspace, status=WorkspaceRoleStatus.PENDING
) )
invite = InvitationFactory.create(user_id=user.id, workspace_role_id=ws_role.id) invite = InvitationFactory.create(
user_id=user.id, workspace_role=ws_role, workspace_role_id=ws_role.id
)
user_session(different_user) user_session(different_user)
response = client.get(url_for("workspaces.accept_invitation", token=invite.token)) response = client.get(url_for("workspaces.accept_invitation", token=invite.token))
@@ -124,6 +129,7 @@ def test_user_accepts_expired_invite(client, user_session):
) )
invite = InvitationFactory.create( invite = InvitationFactory.create(
user_id=user.id, user_id=user.id,
workspace_role=ws_role,
workspace_role_id=ws_role.id, workspace_role_id=ws_role.id,
status=InvitationStatus.REJECTED_EXPIRED, status=InvitationStatus.REJECTED_EXPIRED,
expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1), expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1),
@@ -142,6 +148,7 @@ def test_revoke_invitation(client, user_session):
) )
invite = InvitationFactory.create( invite = InvitationFactory.create(
user_id=user.id, user_id=user.id,
workspace_role=ws_role,
workspace_role_id=ws_role.id, workspace_role_id=ws_role.id,
status=InvitationStatus.REJECTED_EXPIRED, status=InvitationStatus.REJECTED_EXPIRED,
expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1), expiration_time=datetime.datetime.now() - datetime.timedelta(seconds=1),
@@ -166,7 +173,10 @@ def test_resend_invitation_sends_email(client, user_session, queue):
user=user, workspace=workspace, status=WorkspaceRoleStatus.PENDING user=user, workspace=workspace, status=WorkspaceRoleStatus.PENDING
) )
invite = InvitationFactory.create( invite = InvitationFactory.create(
user_id=user.id, workspace_role_id=ws_role.id, status=InvitationStatus.PENDING user_id=user.id,
workspace_role=ws_role,
workspace_role_id=ws_role.id,
status=InvitationStatus.PENDING,
) )
user_session(workspace.owner) user_session(workspace.owner)
client.post( client.post(
@@ -190,6 +200,7 @@ def test_existing_member_invite_resent_to_email_submitted_in_form(
) )
invite = InvitationFactory.create( invite = InvitationFactory.create(
user_id=user.id, user_id=user.id,
workspace_role=ws_role,
workspace_role_id=ws_role.id, workspace_role_id=ws_role.id,
status=InvitationStatus.PENDING, status=InvitationStatus.PENDING,
email="example@example.com", email="example@example.com",