From c4debe011c72e618b079701c2d9a75604af62ffd Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Fri, 16 Mar 2018 17:13:27 -0400 Subject: [PATCH] Fix team add/invite logic around when an invite is required We were accidentally skipping the invite if the user was a member of *any* organization, rather than the specific organization (as intended) Fixes https://jira.coreos.com/browse/QUAY-880 --- data/model/team.py | 12 ++++++----- data/model/test/test_team.py | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 data/model/test/test_team.py diff --git a/data/model/team.py b/data/model/team.py index 923951299..febf668f4 100644 --- a/data/model/team.py +++ b/data/model/team.py @@ -128,11 +128,13 @@ def add_or_invite_to_team(inviter, team, user_obj=None, email=None, requires_inv raise InvalidTeamMemberException('Cannot add the specified robot to this team, ' + 'as it is not a member of the organization') else: - Org = User.alias() - found = User.select(User.username) - found = found.where(User.username == user_obj.username).join(TeamMember).join(Team) - found = found.join(Org, on=(Org.username == orgname)).limit(1) - requires_invite = not any(found) + query = (TeamMember + .select() + .where(TeamMember.user == user_obj) + .join(Team) + .join(User) + .where(User.username == orgname, User.organization == True)) + requires_invite = not any(query) # If we have a valid user and no invite is required, simply add the user to the team. if user_obj and not requires_invite: diff --git a/data/model/test/test_team.py b/data/model/test/test_team.py new file mode 100644 index 000000000..bcb814ec6 --- /dev/null +++ b/data/model/test/test_team.py @@ -0,0 +1,41 @@ +import pytest + +from data.model.team import (add_or_invite_to_team, get_organization_team, + create_team, confirm_team_invite, list_team_users) +from data.model.organization import create_organization +from data.model.user import get_user, create_user_noverify + +from test.fixtures import * + +def is_in_team(team, user): + return user.username in {u.username for u in list_team_users(team)} + +def test_invite_to_team(initialized_db): + first_user = get_user('devtable') + second_user = create_user_noverify('newuser', 'foo@example.com') + + def run_invite_flow(orgname): + # Create an org owned by `devtable`. + org = create_organization(orgname, orgname + '@example.com', first_user) + + # Create another team and add `devtable` to it. Since `devtable` is already + # in the org, it should be done directly. + other_team = create_team('otherteam', org, 'admin') + invite = add_or_invite_to_team(first_user, other_team, user_obj=first_user) + assert invite is None + assert is_in_team(other_team, first_user) + + # Try to add `newuser` to the team, which should require an invite. + invite = add_or_invite_to_team(first_user, other_team, user_obj=second_user) + assert invite is not None + assert not is_in_team(other_team, second_user) + + # Accept the invite. + confirm_team_invite(invite.invite_token, second_user) + assert is_in_team(other_team, second_user) + + # Run for a new org. + run_invite_flow('firstorg') + + # Create another org and repeat, ensuring the same operations perform the same way. + run_invite_flow('secondorg')