def user_admin_perm_to_auditors(session, groups): """Adds a USER_ADMIN permission to the "auditors" group""" user_admin_perm, is_new = Permission.get_or_create( session, name=USER_ADMIN, description="grouper.admin.users permission") session.commit() grant_permission(groups["auditors"], user_admin_perm)
def user_admin_perm_to_auditors(session, groups): """Adds a USER_ADMIN permission to the "auditors" group""" user_admin_perm, is_new = Permission.get_or_create(session, name=USER_ADMIN, description="grouper.admin.users permission") session.commit() grant_permission(groups["auditors"], user_admin_perm)
def test_limited_permissions_global_approvers(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Test that notifications are not sent to global approvers.""" perm_grant, _, perm1, _ = grantable_permissions perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() # one circuit-breaking admin grant, one wildcard grant grant_permission(groups["sad-team"], perm_admin, argument="") grant_permission(groups["security-team"], perm_grant, argument="grantable.*") security_team_members = {name for (t, name) in groups['security-team'].my_members().keys() if t == 'User'} # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team' groupname = "sad-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({"permission_name": perm1.name, "argument": "specific_arg", "reason": "blah blah black sheep", "argument_type": "text"}), headers={'X-Grouper-User': username}) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 2, "email only sent to security-team" assert not security_team_members.difference(e.email for e in emails), \ "only security-team members get notification"
def test_edit_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") assert tag.description == "Test Tag Please Ignore", "The description should match what we created it with" user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/tags/{}/edit'.format(tag.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({"description": "Don't tag me bro"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") assert tag.description == "Don't tag me bro", "The description should have been updated"
def test_grant_and_revoke(session, standard_graph, graph, groups, permissions, http_client, base_url): """Test that permission grant and revokes are reflected correctly.""" group_name = "team-sre" permission_name = "sudo" user_name = "*****@*****.**" def _check_graph_for_perm(graph): return any(map(lambda x: x.permission == permission_name, graph.permission_metadata[group_name])) # make some permission admins perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() grant_permission(groups["security-team"], perm_admin) # grant attempt by non-permission admin fe_url = url(base_url, "/permissions/grant/{}".format(group_name)) with pytest.raises(HTTPError): yield http_client.fetch(fe_url, method="POST", body=urlencode({"permission": permission_name, "argument": "specific_arg"}), headers={'X-Grouper-User': "******"}) graph.update_from_db(session) assert not _check_graph_for_perm(graph), "no permissions granted" # grant by permission admin resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({"permission": permission_name, "argument": "specific_arg"}), headers={'X-Grouper-User': user_name}) assert resp.code == 200 graph.update_from_db(session) assert _check_graph_for_perm(graph), "permissions granted, successfully" # figure out mapping_id of grant permission_id = Permission.get(session, name=permission_name).id group_id = Group.get(session, name=group_name).id mapping = session.query(PermissionMap).filter( PermissionMap.permission_id == permission_id, PermissionMap.group_id == group_id).first() # revoke permission by non-admin fe_url = url(base_url, "/permissions/{}/revoke/{}".format(permission_name, mapping.id)) with pytest.raises(HTTPError): yield http_client.fetch(fe_url, method="POST", body=urlencode({}), headers={'X-Grouper-User': "******"}) graph.update_from_db(session) assert _check_graph_for_perm(graph), "permissions not revoked" # revoke permission for realz resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({}), headers={'X-Grouper-User': user_name}) assert resp.code == 200 graph.update_from_db(session) assert not _check_graph_for_perm(graph), "permissions revoked successfully"
def test_revoke_permission_from_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'tagname': "tyler_was_here", "description": "Test Tag Please Ignore" }), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'permission': TAG_EDIT, "argument": "*" }), headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") perm = Permission.get(session, TAG_EDIT) assert len(get_public_key_tag_permissions( session, tag)) == 1, "The tag should have exactly 1 permission" user = session.query(User).filter_by(username="******").scalar() mapping = get_public_key_tag_permissions(session, tag)[0] fe_url = url( base_url, '/permissions/{}/revoke_tag/{}'.format(TAG_EDIT, mapping.mapping_id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") assert len(get_public_key_tag_permissions( session, tag)) == 0, "The tag should have no permissions"
def test_grant_permission(session, standard_graph, groups, permissions): grant_permission(groups["sad-team"], permissions["ssh"], argument="host +other-host") with pytest.raises(AssertionError): grant_permission(groups["sad-team"], permissions["ssh"], argument="question?") account = ServiceAccount.get(session, name="*****@*****.**") grant_permission_to_service_account(session, account, permissions["ssh"], argument="*") with pytest.raises(AssertionError): grant_permission_to_service_account( session, account, permissions["ssh"], argument="question?")
def test_permissions(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() perm = Permission(name="it.literally.does.not.matter", description="Why is this not nullable?") perm.add(session) session.commit() grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name="it.literally.does.not.matter").scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'permission': TAG_EDIT, "argument": "prod"}), headers={'X-Grouper-User': user.username}) user = session.query(User).filter_by(username="******").scalar() # add SSH key fe_url = url(base_url, '/users/{}/public-key/add'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'public_key': key_1}), headers={'X-Grouper-User': user.username}) key = session.query(PublicKey).filter_by(user_id=user.id).scalar() user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here"}), headers={'X-Grouper-User': user.username}) user = session.query(User).filter_by(username="******").scalar() key = session.query(PublicKey).filter_by(user_id=user.id).scalar() assert len(get_public_key_permissions(session, key)) == 1, "The SSH Key should have only 1 permission" assert get_public_key_permissions(session, key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT" assert get_public_key_permissions(session, key)[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument" assert len(user_permissions(session, user)) > 1, "The user should have more than 1 permission"
def test_regress_permreq_global_approvers(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Validates that we can render a permission request form where a global approver exists""" perm_grant, _, perm1, _ = grantable_permissions perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() grant_permission(groups["security-team"], perm_admin) groupname = "sad-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="GET", headers={'X-Grouper-User': username}) assert resp.code == 200
def test_grantable_permissions(session, standard_graph, users, groups, grantable_permissions): perm_grant, perm0, perm1, _ = grantable_permissions assert not user_grantable_permissions(session, users["*****@*****.**"]), "start with none" grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one") assert not user_grantable_permissions(session, users["*****@*****.**"]), "grant on non-existent is fine" grant_permission(groups["auditors"], perm_grant, argument=perm0.name) grants = user_grantable_permissions(session, users["*****@*****.**"]) assert len(grants) == 1, "only specific permission grant" assert grants[0][0].name == perm0.name, "only specific permission grant" grant_permission(groups["auditors"], perm_grant, argument="grantable.*") grants = user_grantable_permissions(session, users["*****@*****.**"]) assert len(grants) == 3, "wildcard grant should grab appropriat amount" assert sorted([x[0].name for x in grants]) == ["grantable", "grantable.one", "grantable.two"] args_by_perm = get_grantable_permissions(session, None) assert args_by_perm[perm1.name] == ["*"], "wildcard grant reflected in list of grantable" grant_permission(groups["auditors"], perm_grant, argument="{}/single_arg".format(perm1.name)) args_by_perm = get_grantable_permissions(session, None) assert args_by_perm[perm1.name] == ["*"], "wildcard grant reflected cause no restricted perms" args_by_perm = get_grantable_permissions(session, [perm1.name]) assert args_by_perm[perm1.name] == ["single_arg"], "least permissive argument shown cause of restricted perms"
def test_tags(session, users, http_client, base_url, graph): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() perm2 = Permission(name="it.literally.does.not.matter", description="Why is this not nullable?") perm2.add(session) session.commit() grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name="it.literally.does.not.matter").scalar(), "*") tag = PublicKeyTag(name="tyler_was_here") tag.add(session) session.commit() tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() grant_permission_to_tag(session, tag.id, perm.id, "prod") user = session.query(User).filter_by(username="******").scalar() add_public_key(session, user, key1) key = session.query(PublicKey).filter_by(user_id=user.id).scalar() user = session.query(User).filter_by(username="******").scalar() add_tag_to_public_key(session, key, tag) user = session.query(User).filter_by(username="******").scalar() key = session.query(PublicKey).filter_by(user_id=user.id).scalar() assert len(get_public_key_permissions(session, key)) == 1, "The SSH Key should have only 1 permission" assert get_public_key_permissions(session, key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT" assert get_public_key_permissions(session, key)[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument" assert len(user_permissions(session, user)) > 1, "The user should have more than 1 permission" graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) pub_key = body['data']['user']['public_keys'][0] assert len(pub_key['tags']) == 1, "The public key should only have 1 tag" assert pub_key['tags'][0] == 'tyler_was_here', "The public key should have the tag we gave it"
def test_tags(session, http_client, base_url, graph): perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() perm2 = Permission(name="it.literally.does.not.matter", description="Why is this not nullable?") perm2.add(session) session.commit() grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name="it.literally.does.not.matter").scalar(), "*") tag = PublicKeyTag(name="tyler_was_here") tag.add(session) session.commit() tag = PublicKeyTag.get(session, name="tyler_was_here") grant_permission_to_tag(session, tag.id, perm.id, "prod") with pytest.raises(AssertionError): grant_permission_to_tag(session, tag.id, perm.id, "question?") user = session.query(User).filter_by(username="******").scalar() add_public_key(session, user, SSH_KEY_1) key = session.query(PublicKey).filter_by(user_id=user.id).scalar() add_tag_to_public_key(session, key, tag) user = session.query(User).filter_by(username="******").scalar() key = session.query(PublicKey).filter_by(user_id=user.id).scalar() assert len(get_public_key_permissions(session, key)) == 1, "The SSH Key should have only 1 permission" assert get_public_key_permissions(session, key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT" assert get_public_key_permissions(session, key)[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument" assert len(user_permissions(session, user)) > 1, "The user should have more than 1 permission" graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) pub_key = body['data']['user']['public_keys'][0] assert len(pub_key['tags']) == 1, "The public key should only have 1 tag" assert pub_key['fingerprint'] == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35' assert pub_key['fingerprint_sha256'] == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU' assert pub_key['tags'][0] == 'tyler_was_here', "The public key should have the tag we gave it"
def test_permission_grant_to_owners(session, standard_graph, groups, grantable_permissions): """Test we're getting correct owners according to granted 'grouper.permission.grant' permissions.""" perm_grant, _, perm1, perm2 = grantable_permissions assert not get_owners_by_grantable_permission(session), "nothing to begin with" # grant a grant on a non-existent permission grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one") assert not get_owners_by_grantable_permission(session), "ignore grants for non-existent perms" # grant a wildcard grant -- make sure all permissions are represented and # the grant isn't inherited grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups["all-teams"]] assert owners_by_arg_by_perm[perm1.name]["*"] == expected, "grants are not inherited" assert len(owners_by_arg_by_perm) == 2 assert len(owners_by_arg_by_perm[perm1.name]) == 1 assert len(owners_by_arg_by_perm[perm2.name]) == 1 # grant on argument substring grant_permission(groups["team-sre"], perm_grant, argument="{}/somesubstring*".format(perm1.name)) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups["all-teams"]] assert owners_by_arg_by_perm[perm1.name]["*"] == expected expected = [groups["team-sre"]] assert owners_by_arg_by_perm[perm1.name]["somesubstring*"] == expected # make sure get_owner() respect substrings res = [ o for o, a in get_owner_arg_list(session, perm1, "somesubstring", owners_by_arg_by_perm=owners_by_arg_by_perm) ] assert ( sorted(res) == sorted([groups["all-teams"], groups["team-sre"]]), "should include substring wildcard matches", ) res = [ o for o, a in get_owner_arg_list(session, perm1, "othersubstring", owners_by_arg_by_perm=owners_by_arg_by_perm) ] assert sorted(res) == [groups["all-teams"]], "negative test of substring wildcard matches" # permission admins have all the power perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() grant_permission(groups["security-team"], perm_admin) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) all_permissions = Permission.get_all(session) for perm in all_permissions: assert perm.name in owners_by_arg_by_perm, "all permission should be represented" assert ( groups["security-team"] in owners_by_arg_by_perm[perm.name]["*"] ), "permission admin should be wildcard owners"
def test_grant_permission(session, standard_graph, groups, permissions): grant_permission(groups["sad-team"], permissions["ssh"], argument="host +other-host") with pytest.raises(AssertionError): grant_permission(groups["sad-team"], permissions["ssh"], argument="question?") account = ServiceAccount.get(session, name="*****@*****.**") grant_permission_to_service_account(session, account, permissions["ssh"], argument="*") with pytest.raises(AssertionError): grant_permission_to_service_account(session, account, permissions["ssh"], argument="question?")
def test_limited_permissions_global_approvers(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Test that notifications are not sent to global approvers.""" perm_grant, _, perm1, _ = grantable_permissions perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() # one circuit-breaking admin grant, one wildcard grant grant_permission(groups["sad-team"], perm_admin, argument="") grant_permission(groups["security-team"], perm_grant, argument="grantable.*") security_team_members = { name for (t, name) in groups['security-team'].my_members().keys() if t == 'User' } # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team' groupname = "sad-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission_name": perm1.name, "argument": "specific_arg", "reason": "blah blah black sheep", "argument_type": "text" }), headers={'X-Grouper-User': username}) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 2, "email only sent to security-team" assert not security_team_members.difference(e.email for e in emails), \ "only security-team members get notification"
def test_revoke_permission_from_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'permission': TAG_EDIT, "argument": "*"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") perm = Permission.get(session, TAG_EDIT) assert len(get_public_key_tag_permissions(session, tag)) == 1, "The tag should have exactly 1 permission" user = session.query(User).filter_by(username="******").scalar() mapping = get_public_key_tag_permissions(session, tag)[0] fe_url = url(base_url, '/permissions/{}/revoke_tag/{}'.format(TAG_EDIT, mapping.mapping_id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") assert len(get_public_key_tag_permissions(session, tag)) == 0, "The tag should have no permissions"
def test_grant_permission_to_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'tagname': "tyler_was_here", "description": "Test Tag Please Ignore"}), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'permission': TAG_EDIT, "argument": "*"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") perm = Permission.get(session, TAG_EDIT) assert len(get_public_key_tag_permissions(session, tag)) == 1, "The tag should have exactly 1 permission" assert get_public_key_tag_permissions(session, tag)[0].name == perm.name, "The tag's permission should be the one we added" assert get_public_key_tag_permissions(session, tag)[0].argument == "*", "The tag's permission should be the one we added" # Make sure trying to add a permission to a tag doesn't fail horribly if it's already there user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'permission': TAG_EDIT, "argument": "*"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200
def test_limited_permissions(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Test that notifications are not sent to wildcard grant owners unless necessary.""" perm_grant, _, perm1, _ = grantable_permissions # one super wildcard, one wildcard grant and one specific grant grant_permission(groups["sad-team"], perm_grant, argument="*") grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") grant_permission(groups["security-team"], perm_grant, argument="{}/specific_arg".format(perm1.name)) security_team_members = {name for (t, name) in groups["security-team"].my_members().keys() if t == "User"} # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team' groupname = "sad-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode( { "permission_name": perm1.name, "argument": "specific_arg", "reason": "blah blah black sheep", "argument_type": "text", } ), headers={"X-Grouper-User": username}, ) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 2, "email only sent to security-team" assert not security_team_members.difference(e.email for e in emails), "only security-team members get notification"
def expiring_graph(session, graph, users, groups, permissions): now = datetime.utcnow() note_exp_now = now + timedelta(settings.expiration_notice_days) week = timedelta(7) add_member(groups["team-sre"], users["*****@*****.**"], role="owner") add_member(groups["team-sre"], users["*****@*****.**"], role="owner") add_member(groups["team-sre"], users["*****@*****.**"], expiration=note_exp_now + week) add_member(groups["team-sre"], users["*****@*****.**"]) add_member(groups["team-sre"], users["*****@*****.**"], role="owner", expiration=note_exp_now + week) revoke_member(groups["team-sre"], users["*****@*****.**"]) grant_permission(groups["team-sre"], permissions["ssh"], argument="*") add_member(groups["serving-team"], users["*****@*****.**"], role="owner") add_member(groups["serving-team"], groups["team-sre"], expiration=note_exp_now + week) add_member(groups["serving-team"], groups["tech-ops"]) grant_permission(groups["serving-team"], permissions["audited"]) add_member(groups["tech-ops"], users["*****@*****.**"], role="owner") add_member(groups["tech-ops"], users["*****@*****.**"], expiration=note_exp_now + 2 * week) grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") return graph
def test_limited_permissions(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Test that notifications are not sent to wildcard grant owners unless necessary.""" perm_grant, _, perm1, _ = grantable_permissions # one super wildcard, one wildcard grant and one specific grant grant_permission(groups["sad-team"], perm_grant, argument="*") grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") grant_permission(groups["security-team"], perm_grant, argument="{}/specific_arg".format(perm1.name)) security_team_members = { name for (t, name) in groups['security-team'].my_members().keys() if t == 'User' } # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team' groupname = "sad-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission_name": perm1.name, "argument": "specific_arg", "reason": "blah blah black sheep", "argument_type": "text" }), headers={'X-Grouper-User': username}) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert_same_recipients(emails, [u"*****@*****.**"])
def test_edit_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'tagname': "tyler_was_here", "description": "Test Tag Please Ignore" }), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") assert tag.description == "Test Tag Please Ignore", "The description should match what we created it with" user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/tags/{}/edit'.format(tag.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode( {"description": "Don't tag me bro"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") assert tag.description == "Don't tag me bro", "The description should have been updated"
def test_grantable_permissions(session, standard_graph, users, groups, grantable_permissions): perm_grant, perm0, perm1, _ = grantable_permissions assert not user_grantable_permissions( session, users["*****@*****.**"]), "start with none" grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one") assert not user_grantable_permissions( session, users["*****@*****.**"]), "grant on non-existent is fine" grant_permission(groups["auditors"], perm_grant, argument=perm0.name) grants = user_grantable_permissions(session, users["*****@*****.**"]) assert len(grants) == 1, "only specific permission grant" assert grants[0][0].name == perm0.name, "only specific permission grant" grant_permission(groups["auditors"], perm_grant, argument="grantable.*") grants = user_grantable_permissions(session, users["*****@*****.**"]) assert len(grants) == 3, "wildcard grant should grab appropriat amount" assert sorted([x[0].name for x in grants ]) == ["grantable", "grantable.one", "grantable.two"] args_by_perm = get_grantable_permissions(session, None) assert args_by_perm[perm1.name] == [ "*" ], "wildcard grant reflected in list of grantable" grant_permission(groups["auditors"], perm_grant, argument="{}/single_arg".format(perm1.name)) args_by_perm = get_grantable_permissions(session, None) assert args_by_perm[perm1.name] == [ "*" ], "wildcard grant reflected cause no restricted perms" args_by_perm = get_grantable_permissions(session, [perm1.name]) assert args_by_perm[perm1.name] == ["single_arg"], \ "least permissive argument shown cause of restricted perms"
def test_basic_permission(standard_graph, session, users, groups, permissions): # noqa """ Test adding some permissions to various groups and ensuring that the permissions are all implemented as expected. This also tests permissions inheritance in the graph. """ graph = standard_graph # noqa grant_permission(groups["team-sre"], permissions["ssh"], argument="*") grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") grant_permission(groups["team-infra"], permissions["sudo"], argument="shell") session.commit() graph.update_from_db(session) assert sorted(get_group_permissions(graph, "team-sre")) == ["ssh:*", "sudo:shell"] assert sorted(get_group_permissions(graph, "tech-ops")) == ["ssh:shell", "sudo:shell"] assert sorted(get_group_permissions(graph, "team-infra")) == ["sudo:shell"] assert sorted(get_group_permissions(graph, "all-teams")) == [] assert sorted(get_user_permissions(graph, "gary")) == ["ssh:*", "ssh:shell", "sudo:shell"] assert sorted(get_user_permissions(graph, "zay")) == ["ssh:*", "ssh:shell", "sudo:shell"] assert sorted(get_user_permissions(graph, "zorkian")) == ["ssh:*", "sudo:shell"] assert sorted(get_user_permissions(graph, "testuser")) == []
def expiring_graph(session, graph, users, groups, permissions): now = datetime.utcnow() note_exp_now = now + timedelta(settings.expiration_notice_days) week = timedelta(7) add_member(groups["team-sre"], users["*****@*****.**"], role="owner") add_member(groups["team-sre"], users["*****@*****.**"], role="owner") add_member(groups["team-sre"], users["*****@*****.**"], expiration=note_exp_now+week) add_member(groups["team-sre"], users["*****@*****.**"]) add_member(groups["team-sre"], users["*****@*****.**"], role="owner", expiration=note_exp_now+week) revoke_member(groups["team-sre"], users["*****@*****.**"]) grant_permission(groups["team-sre"], permissions["ssh"], argument="*") add_member(groups["serving-team"], users["*****@*****.**"], role="owner") add_member(groups["serving-team"], groups["team-sre"], expiration=note_exp_now+week) add_member(groups["serving-team"], groups["tech-ops"]) grant_permission(groups["serving-team"], permissions["audited"]) add_member(groups["tech-ops"], users["*****@*****.**"], role="owner") add_member(groups["tech-ops"], users["*****@*****.**"], expiration=note_exp_now+2*week) grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") return graph
def test_permission_request_flow(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Test that a permission request gets into the system correctly and notifications are sent correctly.""" perm_grant, _, perm1, perm2 = grantable_permissions grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") # REQUEST: 'grantable.one', 'some argument' for 'serving-team' groupname = "serving-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode( { "permission_name": "grantable.one", "argument": "some argument", "reason": "blah blah black sheep", "argument_type": "text", } ), headers={"X-Grouper-User": username}, ) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 1, "only one user (and no group) should receive notification for request" perms = _load_permissions_by_group_name(session, "serving-team") assert len(perms) == 1 assert "grantable.one" not in perms, "requested permission shouldn't be granted immediately" user = User.get(session, name="*****@*****.**") request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests) == 0, "random user shouldn't have a request" user = User.get(session, name="*****@*****.**") request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests) == 1, "user in group with grant should have a request" # APPROVE grant: have '*****@*****.**' action this request as owner of # 'all-teams' which has the grant permission for the requested permission request_id = request_tuple.requests[0].id fe_url = url(base_url, "/permissions/requests/{}".format(request_id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"status": "actioned", "reason": "lgtm"}), headers={"X-Grouper-User": user.name}, ) assert resp.code == 200 perms = _load_permissions_by_group_name(session, "serving-team") assert len(perms) == 2 assert "grantable.one" in perms, "requested permission shouldn't be granted immediately" emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 1, "requester should receive email as well" # (re)REQUEST: 'grantable.one', 'some argument' for 'serving-team' groupname = "serving-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode( { "permission_name": "grantable.one", "argument": "some argument", "reason": "blah blah black sheep", "argument_type": "text", } ), headers={"X-Grouper-User": username}, ) assert resp.code == 200 user = User.get(session, name="*****@*****.**") request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests) == 0, "request for existing perm should fail" # REQUEST: 'grantable.two', 'some argument' for 'serving-team' groupname = "serving-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode( { "permission_name": "grantable.two", "argument": "some argument", "reason": "blah blah black sheep", "argument_type": "text", } ), headers={"X-Grouper-User": username}, ) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 1, "only one user (and no group) should receive notification for request" perms = _load_permissions_by_group_name(session, "serving-team") assert len(perms) == 2 assert "grantable.two" not in perms, "requested permission shouldn't be granted immediately" user = User.get(session, name="*****@*****.**") request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests) == 0, "random user shouldn't have a request" user = User.get(session, name="*****@*****.**") request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests) == 1, "user in group with grant should have a request" # CANCEL request: have '*****@*****.**' cancel this request request_id = request_tuple.requests[0].id fe_url = url(base_url, "/permissions/requests/{}".format(request_id)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"status": "cancelled", "reason": "heck no"}), headers={"X-Grouper-User": user.name}, ) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 1, "rejection email should be sent" perms = _load_permissions_by_group_name(session, "serving-team") assert len(perms) == 2 assert "grantable.two" not in perms, "no new permissions should be granted for this"
def standard_graph(session, graph, users, groups, permissions): add_member(groups["team-sre"], users["gary"], role="owner") add_member(groups["team-sre"], users["zay"]) add_member(groups["team-sre"], users["zorkian"]) grant_permission(groups["team-sre"], permissions["ssh"], argument="*") add_member(groups["serving-team"], users["zorkian"], role="owner") add_member(groups["serving-team"], groups["team-sre"]) add_member(groups["serving-team"], groups["tech-ops"]) grant_permission(groups["serving-team"], permissions["audited"]) add_member(groups["tech-ops"], users["zay"], role="owner") add_member(groups["tech-ops"], users["gary"]) add_member(groups["tech-ops"], users["figurehead"], role="np-owner") grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") add_member(groups["security-team"], users["oliver"], role="owner") add_member(groups["security-team"], users["figurehead"], role="member") add_member(groups["sad-team"], users["zorkian"], role="owner") add_member(groups["sad-team"], users["oliver"]) add_member(groups["audited-team"], users["zorkian"], role="owner") grant_permission(groups["audited-team"], permissions["audited"]) add_member(groups["team-infra"], users["gary"], role="owner") add_member(groups["team-infra"], groups["serving-team"]) add_member(groups["team-infra"], groups["security-team"]) grant_permission(groups["team-infra"], permissions["sudo"], argument="shell") add_member(groups["auditors"], users["zorkian"], role="owner") grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR]) add_member(groups["all-teams"], users["testuser"], role="owner") add_member(groups["all-teams"], groups["team-infra"]) session.commit() graph.update_from_db(session) return graph
def test_grant_permission_to_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'tagname': "tyler_was_here", "description": "Test Tag Please Ignore" }), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'permission': TAG_EDIT, "argument": "*" }), headers={'X-Grouper-User': user.username}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") perm = Permission.get(session, TAG_EDIT) assert len(get_public_key_tag_permissions( session, tag)) == 1, "The tag should have exactly 1 permission" assert get_public_key_tag_permissions( session, tag )[0].name == perm.name, "The tag's permission should be the one we added" assert get_public_key_tag_permissions( session, tag )[0].argument == "*", "The tag's permission should be the one we added" # Make sure trying to add a permission to a tag doesn't fail horribly if it's already there user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'permission': TAG_EDIT, "argument": "*" }), headers={'X-Grouper-User': user.username}) assert resp.code == 200
def test_grant_and_revoke(session, standard_graph, graph, groups, permissions, http_client, base_url): """Test that permission grant and revokes are reflected correctly.""" group_name = "team-sre" permission_name = "sudo" user_name = "*****@*****.**" def _check_graph_for_perm(graph): return any( map(lambda x: x.permission == permission_name, graph.permission_metadata[group_name])) # make some permission admins perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() grant_permission(groups["security-team"], perm_admin) # grant attempt by non-permission admin fe_url = url(base_url, "/permissions/grant/{}".format(group_name)) with pytest.raises(HTTPError): yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission": permission_name, "argument": "specific_arg" }), headers={'X-Grouper-User': "******"}) graph.update_from_db(session) assert not _check_graph_for_perm(graph), "no permissions granted" # grant by permission admin resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission": permission_name, "argument": "specific_arg" }), headers={'X-Grouper-User': user_name}) assert resp.code == 200 graph.update_from_db(session) assert _check_graph_for_perm(graph), "permissions granted, successfully" # figure out mapping_id of grant permission_id = Permission.get(session, name=permission_name).id group_id = Group.get(session, name=group_name).id mapping = session.query(PermissionMap).filter( PermissionMap.permission_id == permission_id, PermissionMap.group_id == group_id).first() # revoke permission by non-admin fe_url = url( base_url, "/permissions/{}/revoke/{}".format(permission_name, mapping.id)) with pytest.raises(HTTPError): yield http_client.fetch(fe_url, method="POST", body=urlencode({}), headers={'X-Grouper-User': "******"}) graph.update_from_db(session) assert _check_graph_for_perm(graph), "permissions not revoked" # revoke permission for realz resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({}), headers={'X-Grouper-User': user_name}) assert resp.code == 200 graph.update_from_db(session) assert not _check_graph_for_perm(graph), "permissions revoked successfully"
def standard_graph(session, graph, users, groups, permissions): """Setup a standard graph used for many tests. In graph form: +-----------------------+ | | | team-sre | | * gary (o) +---------------------------------+ | * zay | | | * zorkian | +-----------v-----------+ | | | | +-----------------------+ | serving-team | +-----------------------+ +---------> * zorkian (o) | | | | | | | tech-ops | | +-----------+-----------+ | * zay (o) | | | | * gary +-----------+ | | * figurehead (np) | | | | | +-----------------------+ | +-----------------------+ +-----------v-----------+ | | | | | security-team | | team-infra | | * oliver (o) +---------------------> * gary (o) | | * figurehead | | | | | +-----------+-----------+ +-----------------------+ | +-----------------------+ | | | | | sad-team | | | * zorkian (o) | | | * oliver | +-----------v-----------+ | | | | +-----------------------+ | all-teams | +-----------------------+ | * testuser (o) | | | | | | audited-team | +-----------------------+ | * zorkian (o) | | | | | +-----------------------+ +-----------------------+ | | | auditors | | * zorkian (o) | | | +-----------------------+ +-----------------------+ | | | user-admins | | * tyleromeara (o) | | | +-----------------------+ Arrows denote member of the source in the destination group. (o) for owners, (np) for non-permissioned owners. """ add_member(groups["team-sre"], users["*****@*****.**"], role="owner") add_member(groups["team-sre"], users["*****@*****.**"]) add_member(groups["team-sre"], users["*****@*****.**"]) grant_permission(groups["team-sre"], permissions["ssh"], argument="*") grant_permission(groups["team-sre"], permissions["team-sre"], argument="*") add_member(groups["serving-team"], users["*****@*****.**"], role="owner") add_member(groups["serving-team"], groups["team-sre"]) add_member(groups["serving-team"], groups["tech-ops"]) grant_permission(groups["serving-team"], permissions["audited"]) add_member(groups["tech-ops"], users["*****@*****.**"], role="owner") add_member(groups["tech-ops"], users["*****@*****.**"]) add_member(groups["tech-ops"], users["*****@*****.**"], role="np-owner") grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") add_member(groups["security-team"], users["*****@*****.**"], role="owner") add_member(groups["security-team"], users["*****@*****.**"], role="member") add_member(groups["sad-team"], users["*****@*****.**"], role="owner") add_member(groups["sad-team"], users["*****@*****.**"]) add_member(groups["audited-team"], users["*****@*****.**"], role="owner") grant_permission(groups["audited-team"], permissions["audited"]) add_member(groups["team-infra"], users["*****@*****.**"], role="owner") add_member(groups["team-infra"], groups["serving-team"]) add_member(groups["team-infra"], groups["security-team"]) grant_permission(groups["team-infra"], permissions["sudo"], argument="shell") add_member(groups["auditors"], users["*****@*****.**"], role="owner") grant_permission(groups["auditors"], permissions[AUDIT_MANAGER]) grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR]) add_member(groups["all-teams"], users["*****@*****.**"], role="owner") add_member(groups["all-teams"], groups["team-infra"]) add_member(groups["user-admins"], users["*****@*****.**"], role="owner") grant_permission(groups["user-admins"], permissions[USER_ADMIN]) session.commit() graph.update_from_db(session) return graph
def test_permission_request_flow(session, standard_graph, groups, grantable_permissions, http_client, base_url): """Test that a permission request gets into the system correctly and notifications are sent correctly.""" perm_grant, _, perm1, perm2 = grantable_permissions grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") # REQUEST: 'grantable.one', 'some argument' for 'serving-team' groupname = "serving-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission_name": "grantable.one", "argument": "some argument", "reason": "blah blah black sheep", "argument_type": "text" }), headers={'X-Grouper-User': username}) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len( emails ) == 1, "only one user (and no group) should receive notification for request" perms = _load_permissions_by_group_name(session, 'serving-team') assert len(perms) == 1 assert "grantable.one" not in perms, "requested permission shouldn't be granted immediately" user = User.get(session, name='*****@*****.**') request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len( request_tuple.requests) == 0, "random user shouldn't have a request" user = User.get(session, name='*****@*****.**') request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests ) == 1, "user in group with grant should have a request" # APPROVE grant: have '*****@*****.**' action this request as owner of # 'all-teams' which has the grant permission for the requested permission request_id = request_tuple.requests[0].id fe_url = url(base_url, "/permissions/requests/{}".format(request_id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "status": "actioned", "reason": "lgtm" }), headers={'X-Grouper-User': user.name}) assert resp.code == 200 perms = _load_permissions_by_group_name(session, 'serving-team') assert len(perms) == 2 assert "grantable.one" in perms, "requested permission shouldn't be granted immediately" emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 1, "requester should receive email as well" # (re)REQUEST: 'grantable.one', 'some argument' for 'serving-team' groupname = "serving-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission_name": "grantable.one", "argument": "some argument", "reason": "blah blah black sheep", "argument_type": "text" }), headers={'X-Grouper-User': username}) assert resp.code == 200 user = User.get(session, name='*****@*****.**') request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len( request_tuple.requests) == 0, "request for existing perm should fail" # REQUEST: 'grantable.two', 'some argument' for 'serving-team' groupname = "serving-team" username = "******" fe_url = url(base_url, "/groups/{}/permission/request".format(groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "permission_name": "grantable.two", "argument": "some argument", "reason": "blah blah black sheep", "argument_type": "text" }), headers={'X-Grouper-User': username}) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len( emails ) == 1, "only one user (and no group) should receive notification for request" perms = _load_permissions_by_group_name(session, 'serving-team') assert len(perms) == 2 assert "grantable.two" not in perms, "requested permission shouldn't be granted immediately" user = User.get(session, name='*****@*****.**') request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len( request_tuple.requests) == 0, "random user shouldn't have a request" user = User.get(session, name='*****@*****.**') request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0) assert len(request_tuple.requests ) == 1, "user in group with grant should have a request" # CANCEL request: have '*****@*****.**' cancel this request request_id = request_tuple.requests[0].id fe_url = url(base_url, "/permissions/requests/{}".format(request_id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "status": "cancelled", "reason": "heck no" }), headers={'X-Grouper-User': user.name}) assert resp.code == 200 emails = _get_unsent_and_mark_as_sent_emails(session) assert len(emails) == 1, "rejection email should be sent" perms = _load_permissions_by_group_name(session, 'serving-team') assert len(perms) == 2 assert "grantable.two" not in perms, "no new permissions should be granted for this"
def test_permission_grant_to_owners(session, standard_graph, groups, grantable_permissions): """Test we're getting correct owners according to granted 'grouper.permission.grant' permissions.""" perm_grant, _, perm1, perm2 = grantable_permissions assert not get_owners_by_grantable_permission( session), 'nothing to begin with' # grant a grant on a non-existent permission grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one") assert not get_owners_by_grantable_permission( session), 'ignore grants for non-existent perms' # grant a wildcard grant -- make sure all permissions are represented and # the grant isn't inherited grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups['all-teams']] assert owners_by_arg_by_perm[ perm1.name]['*'] == expected, 'grants are not inherited' assert len(owners_by_arg_by_perm) == 2 assert len(owners_by_arg_by_perm[perm1.name]) == 1 assert len(owners_by_arg_by_perm[perm2.name]) == 1 # grant on argument substring grant_permission(groups["team-sre"], perm_grant, argument="{}/somesubstring*".format(perm1.name)) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups['all-teams']] assert owners_by_arg_by_perm[perm1.name]['*'] == expected expected = [groups["team-sre"]] assert owners_by_arg_by_perm[perm1.name]['somesubstring*'] == expected # make sure get_owner() respect substrings res = [ o for o, a in get_owner_arg_list( session, perm1, "somesubstring", owners_by_arg_by_perm=owners_by_arg_by_perm) ] assert sorted(res) == sorted([groups["all-teams"], groups["team-sre"]]), \ "should include substring wildcard matches" res = [ o for o, a in get_owner_arg_list( session, perm1, "othersubstring", owners_by_arg_by_perm=owners_by_arg_by_perm) ] assert sorted(res) == [groups["all-teams"] ], "negative test of substring wildcard matches" # permission admins have all the power perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="") session.commit() grant_permission(groups["security-team"], perm_admin) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) all_permissions = Permission.get_all(session) for perm in all_permissions: assert perm.name in owners_by_arg_by_perm, 'all permission should be represented' assert groups["security-team"] in owners_by_arg_by_perm[perm.name]["*"], \ 'permission admin should be wildcard owners'
def test_tags(session, http_client, base_url, graph): perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() perm2 = Permission(name="it.literally.does.not.matter", description="Why is this not nullable?") perm2.add(session) session.commit() grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by( name="it.literally.does.not.matter").scalar(), "*") tag = PublicKeyTag(name="tyler_was_here") tag.add(session) session.commit() tag = PublicKeyTag.get(session, name="tyler_was_here") grant_permission_to_tag(session, tag.id, perm.id, "prod") with pytest.raises(AssertionError): grant_permission_to_tag(session, tag.id, perm.id, "question?") user = session.query(User).filter_by(username="******").scalar() add_public_key(session, user, SSH_KEY_1) key = session.query(PublicKey).filter_by(user_id=user.id).scalar() add_tag_to_public_key(session, key, tag) user = session.query(User).filter_by(username="******").scalar() key = session.query(PublicKey).filter_by(user_id=user.id).scalar() assert len(get_public_key_permissions( session, key)) == 1, "The SSH Key should have only 1 permission" assert get_public_key_permissions( session, key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT" assert get_public_key_permissions( session, key )[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument" assert len(user_permissions( session, user)) > 1, "The user should have more than 1 permission" graph.update_from_db(session) fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url) assert resp.code == 200 body = json.loads(resp.body) pub_key = body['data']['user']['public_keys'][0] assert len(pub_key['tags']) == 1, "The public key should only have 1 tag" assert pub_key[ 'fingerprint'] == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35' assert pub_key[ 'fingerprint_sha256'] == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU' assert pub_key['tags'][ 0] == 'tyler_was_here', "The public key should have the tag we gave it"
def standard_graph(session, graph, users, groups, permissions): add_member(groups["team-sre"], users["gary"], role="owner") add_member(groups["team-sre"], users["zay"]) add_member(groups["team-sre"], users["zorkian"]) grant_permission(groups["team-sre"], permissions["ssh"], argument="*") add_member(groups["serving-team"], users["zorkian"], role="owner") add_member(groups["serving-team"], groups["team-sre"]) add_member(groups["serving-team"], groups["tech-ops"]) grant_permission(groups["serving-team"], permissions["audited"]) add_member(groups["tech-ops"], users["zay"], role="owner") add_member(groups["tech-ops"], users["gary"]) grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") add_member(groups["security-team"], users["oliver"], role="owner") add_member(groups["sad-team"], users["zorkian"], role="owner") add_member(groups["sad-team"], users["oliver"]) add_member(groups["audited-team"], users["zorkian"], role="owner") grant_permission(groups["audited-team"], permissions["audited"]) add_member(groups["team-infra"], users["gary"], role="owner") add_member(groups["team-infra"], groups["serving-team"]) add_member(groups["team-infra"], groups["security-team"]) grant_permission(groups["team-infra"], permissions["sudo"], argument="shell") add_member(groups["auditors"], users["zorkian"], role="owner") grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR]) add_member(groups["all-teams"], users["testuser"], role="owner") add_member(groups["all-teams"], groups["team-infra"]) session.commit() graph.update_from_db(session) return graph
def standard_graph(session, graph, users, groups, permissions): """Setup a standard graph used for many tests. In graph form: +-----------------------+ | | | team-sre | | * gary (o) +---------------------------------+ | * zay | | | * zorkian | +-----------v-----------+ | | | | +-----------------------+ | serving-team | +-----------------------+ +---------> * zorkian (o) | | | | | | | tech-ops | | +-----------+-----------+ | * zay (o) | | | | * gary +-----------+ | | * figurehead (np) | | | | | +-----------------------+ | +-----------------------+ +-----------v-----------+ | | | | | security-team | | team-infra | | * oliver (o) +---------------------> * gary (o) | | * figurehead | | | | | +-----------+-----------+ +-----------------------+ | +-----------------------+ | | | | | sad-team | | | * zorkian (o) | | | * oliver | +-----------v-----------+ | | | | +-----------------------+ | all-teams | +-----------------------+ | * testuser (o) | | | | | | audited-team | +-----------------------+ | * zorkian (o) | | | | | +-----------------------+ +-----------------------+ | | | auditors | | * zorkian (o) | | | +-----------------------+ Arrows denote member of the source in the destination group. (o) for owners, (np) for non-permissioned owners. """ add_member(groups["team-sre"], users["*****@*****.**"], role="owner") add_member(groups["team-sre"], users["*****@*****.**"]) add_member(groups["team-sre"], users["*****@*****.**"]) grant_permission(groups["team-sre"], permissions["ssh"], argument="*") add_member(groups["serving-team"], users["*****@*****.**"], role="owner") add_member(groups["serving-team"], groups["team-sre"]) add_member(groups["serving-team"], groups["tech-ops"]) grant_permission(groups["serving-team"], permissions["audited"]) add_member(groups["tech-ops"], users["*****@*****.**"], role="owner") add_member(groups["tech-ops"], users["*****@*****.**"]) add_member(groups["tech-ops"], users["*****@*****.**"], role="np-owner") grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell") add_member(groups["security-team"], users["*****@*****.**"], role="owner") add_member(groups["security-team"], users["*****@*****.**"], role="member") add_member(groups["sad-team"], users["*****@*****.**"], role="owner") add_member(groups["sad-team"], users["*****@*****.**"]) add_member(groups["audited-team"], users["*****@*****.**"], role="owner") grant_permission(groups["audited-team"], permissions["audited"]) add_member(groups["team-infra"], users["*****@*****.**"], role="owner") add_member(groups["team-infra"], groups["serving-team"]) add_member(groups["team-infra"], groups["security-team"]) grant_permission(groups["team-infra"], permissions["sudo"], argument="shell") add_member(groups["auditors"], users["*****@*****.**"], role="owner") grant_permission(groups["auditors"], permissions[AUDIT_MANAGER]) grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR]) add_member(groups["all-teams"], users["*****@*****.**"], role="owner") add_member(groups["all-teams"], groups["team-infra"]) session.commit() graph.update_from_db(session) return graph
def test_permissions(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").scalar() perm = Permission(name=TAG_EDIT, description="Why is this not nullable?") perm.add(session) session.commit() perm = Permission(name="it.literally.does.not.matter", description="Why is this not nullable?") perm.add(session) session.commit() grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*") grant_permission( session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by( name="it.literally.does.not.matter").scalar(), "*") fe_url = url(base_url, '/tags') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'tagname': "tyler_was_here", "description": "Test Tag Please Ignore" }), headers={'X-Grouper-User': user.username}) tag = PublicKeyTag.get(session, name="tyler_was_here") user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/permissions/grant_tag/{}'.format(tag.name)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ 'permission': TAG_EDIT, "argument": "prod" }), headers={'X-Grouper-User': user.username}) user = session.query(User).filter_by(username="******").scalar() # add SSH key fe_url = url(base_url, '/users/{}/public-key/add'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'public_key': key_1}), headers={'X-Grouper-User': user.username}) key = session.query(PublicKey).filter_by(user_id=user.id).scalar() user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/users/{}/public-key/{}/tag'.format(user.username, key.id)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode( {'tagname': "tyler_was_here"}), headers={'X-Grouper-User': user.username}) user = session.query(User).filter_by(username="******").scalar() key = session.query(PublicKey).filter_by(user_id=user.id).scalar() assert len(get_public_key_permissions( session, key)) == 1, "The SSH Key should have only 1 permission" assert get_public_key_permissions( session, key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT" assert get_public_key_permissions( session, key )[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument" assert len(user_permissions( session, user)) > 1, "The user should have more than 1 permission"