def test_sa_pubkeys(session, users, http_client, base_url): user = users['*****@*****.**'] # Add account create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin') u = User.get(session, name="*****@*****.**") g = Group.get(session, name="*****@*****.**") assert u is not None assert g is not None assert is_role_user(session, user=u) assert is_role_user(session, group=g) assert get_role_user(session, user=u).group.id == g.id assert get_role_user(session, group=g).user.id == u.id assert not is_role_user(session, user=user) assert not is_role_user(session, group=Group.get(session, name="team-sre")) assert not get_public_keys_of_user(session, user.id) with pytest.raises(HTTPError): # add it fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'public_key': SSH_KEY_1}), headers={'X-Grouper-User': "******"}) # add it fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'public_key': SSH_KEY_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 # add bad key -- shouldn't add fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'public_key': SSH_KEY_BAD}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 sa = User.get(session, name="*****@*****.**") keys = get_public_keys_of_user(session, sa.id) assert len(keys) == 1 assert keys[0].public_key == SSH_KEY_1 with pytest.raises(HTTPError): # delete it fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format("*****@*****.**", keys[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body='', headers={'X-Grouper-User': "******"}) # delete it fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format("*****@*****.**", keys[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body='', headers={'X-Grouper-User': user.username}) assert resp.code == 200 sa = User.get(session, name="*****@*****.**") assert not get_public_keys_of_user(session, sa.id)
def test_user_tok_acls(session, graph, users, user_admin_perm_to_auditors, http_client, base_url): role_user = "******" admin = "*****@*****.**" pleb = "*****@*****.**" # admin creating token for role user fe_url = url(base_url, "/users/{}/tokens/add".format(role_user)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": admin}, body=urlencode({"name": "foo"})) assert resp.code == 200 with pytest.raises(HTTPError): # non-admin creating token for role user resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": pleb}, body=urlencode({"name": "foo2"})) fe_url = url(base_url, "/users/{}/tokens/add".format(pleb)) with pytest.raises(HTTPError): # admin creating token for normal (non-role) user resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": admin}, body=urlencode({"name": "foo3"}))
def test_public_key(session, users, http_client, base_url): user = users['*****@*****.**'] assert not get_public_keys_of_user(session, user.id) # add it 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': SSH_KEY_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) keys = get_public_keys_of_user(session, user.id) assert len(keys) == 1 assert keys[0].public_key == SSH_KEY_1 assert keys[ 0].fingerprint == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35' assert keys[ 0].fingerprint_sha256 == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU' assert keys[0].comment == 'some-comment' # delete it fe_url = url( base_url, '/users/{}/public-key/{}/delete'.format(user.username, keys[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body='', headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert not get_public_keys_of_user(session, user.id)
def test_shell(session, users, http_client, base_url, graph): user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/bash") 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) assert body["data"]["user"]["metadata"] != [], "There should be metadata" assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_key"] == "shell", "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_value"] == "/bin/bash", "The shell should be set to the correct value" set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/zsh") 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) assert body["data"]["user"]["metadata"] != [], "There should be metadata" assert body["data"]["user"]["metadata"][0]["data_key"] == "shell", "There should only be 1 metadata!" assert body["data"]["user"]["metadata"][0]["data_value"] == "/bin/zsh", "The shell should be set to the correct value" assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!"
def test_passwords_api(session, users, http_client, base_url, graph): user = users['*****@*****.**'] TEST_PASSWORD = "******" add_new_user_password(session, "test", TEST_PASSWORD, user.id) assert len(user_passwords(session, user)) == 1, "The user should only have a single password" graph.update_from_db(session) c = Counter.get(session, name="updates") api_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert body["checkpoint"] == c.count, "The API response is not up to date" assert body["data"]["user"]["passwords"] != [], "The user should not have an empty passwords field" assert body["data"]["user"]["passwords"][0]["name"] == "test", "The password should have the same name" assert body["data"]["user"]["passwords"][0]["func"] == "crypt(3)-$6$", "This test does not support any hash functions other than crypt(3)-$6$" assert body["data"]["user"]["passwords"][0]["hash"] == crypt.crypt(TEST_PASSWORD, body["data"]["user"]["passwords"][0]["salt"]), "The hash should be the same as hashing the password and the salt together using the hashing function" assert body["data"]["user"]["passwords"][0]["hash"] != crypt.crypt("hello", body["data"]["user"]["passwords"][0]["salt"]), "The hash should not be the same as hashing the wrong password and the salt together using the hashing function" delete_user_password(session, "test", user.id) c = Counter.get(session, name="updates") graph.update_from_db(session) api_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert body["checkpoint"] == c.count, "The API response is not up to date" assert body["data"]["user"]["passwords"] == [], "The user should not have any passwords"
def test_add_service_account(session, users, http_client, base_url): user = users['*****@*****.**'] # Add account fe_url = url(base_url, '/service/create') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': '*****@*****.**', "description": "Hi", "canjoin": "canjoin"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert User.get(session, name="*****@*****.**") is None assert Group.get(session, name="*****@*****.**") is None # Add account fe_url = url(base_url, '/service/create') resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': '*****@*****.**', "description": "Hi", "canjoin": "canjoin"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 u = User.get(session, name="*****@*****.**") g = Group.get(session, name="*****@*****.**") assert u is not None assert g is not None assert is_service_account(session, user=u) assert is_service_account(session, group=g) assert get_service_account(session, user=u).group.id == g.id assert get_service_account(session, group=g).user.id == u.id assert not is_service_account(session, user=user) assert not is_service_account(session, group=Group.get(session, name="team-sre"))
def test_remove_last_owner_via_audit(async_server, browser, users, groups, session): future = datetime.utcnow() + timedelta(1) add_member(groups["auditors"], users["*****@*****.**"], role="owner") add_member(groups["audited-team"], users["*****@*****.**"], role="owner", expiration=future) session.commit() fe_url = url(async_server, "/audits/create") browser.get(fe_url) page = AuditsCreatePage(browser) page.set_end_date(future.strftime("%m/%d/%Y")) page.submit() fe_url = url(async_server, "/groups/audited-team") browser.get(fe_url) page = GroupViewPage(browser) audit_modal = page.get_audit_modal() audit_modal.find_member_row("*****@*****.**").set_audit_status("remove") audit_modal.confirm() assert page.current_url.endswith("/groups/audited-team") assert page.has_text(group_ownership_policy.EXCEPTION_MESSAGE)
def test_public_key_admin(session, users, http_client, base_url): user = users['*****@*****.**'] assert not get_public_keys_of_user(session, user.id) # add it 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': SSH_KEY_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) keys = get_public_keys_of_user(session, user.id) assert len(keys) == 1 assert keys[0].public_key == SSH_KEY_1 # have an admin delete it fe_url = url( base_url, '/users/{}/public-key/{}/delete'.format(user.username, keys[0].id)) resp = yield http_client.fetch( fe_url, method="POST", body='', headers={'X-Grouper-User': "******"}) assert resp.code == 200 user = User.get(session, name=user.username) assert not get_public_keys_of_user(session, user.id)
def test_group_disable(session, groups, http_client, base_url): # create global audit fe_url = url(base_url, '/audits/create') ends_at = date.today() + timedelta(days=7) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({"ends_at": ends_at.strftime("%m/%d/%Y")})) assert resp.code == 200 serving_team, just_created = Group.get_or_create(session, groupname="serving-team") assert not just_created assert serving_team.audit assert not serving_team.audit.complete # disable with insufficient permissions fe_url = url(base_url, '/groups/serving-team/disable') with pytest.raises(HTTPError): resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({"name": "serving-team"})) # disable fe_url = url(base_url, '/groups/serving-team/disable') resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({"name": "serving-team"})) assert resp.code == 200 serving_team, just_created = Group.get_or_create(session, groupname="serving-team") assert not just_created assert serving_team.audit assert serving_team.audit.complete, "disabling group should complete any outstanding audit"
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_public_key(session, users, http_client, base_url): user = users['*****@*****.**'] assert not get_public_keys_of_user(session, user.id) # add it 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': SSH_KEY_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) keys = get_public_keys_of_user(session, user.id) assert len(keys) == 1 assert keys[0].public_key == SSH_KEY_1 assert keys[0].fingerprint == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35' assert keys[0].fingerprint_sha256 == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU' assert keys[0].comment == 'some-comment' # delete it fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format(user.username, keys[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body='', headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert not get_public_keys_of_user(session, user.id)
def test_usertokens(session, users, http_client, base_url): user = users['*****@*****.**'] assert len(user.tokens) == 0 # Add token fe_url = url(base_url, '/users/{}/tokens/add'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': 'myFoobarToken'}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 # Verify add fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url, method="GET", headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Added token: myFoobarToken" in resp.body # Disable token fe_url = url(base_url, '/users/{}/tokens/1/disable'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 # Verify disable fe_url = url(base_url, '/users/{}'.format(user.username)) resp = yield http_client.fetch(fe_url, method="GET", headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Disabled token: myFoobarToken" in resp.body
def test_group_request(session, users, groups, http_client, base_url): user = users['*****@*****.**'] group = groups['sad-team'] # Request to join fe_url = url(base_url, '/groups/{}/join'.format(group.groupname)) resp = yield http_client.fetch( fe_url, method='POST', headers={'X-Grouper-User': user.username}, body=urlencode({'reason': 'Test Request', 'member': 'User: [email protected]'}), ) assert resp.code == 200 request = Request.get(session, requester_id=user.id, requesting_id=group.id) assert request.status == 'pending' # Approve request fe_url = url(base_url, '/groups/{}/requests/{}'.format(group.groupname, request.id)) resp = yield http_client.fetch( fe_url, method='POST', headers={'X-Grouper-User': '******'}, body=urlencode({'reason': 'Test Request', 'status': 'actioned'}), ) assert resp.code == 200 request = Request.get(session, requester_id=user.id, requesting_id=group.id) assert request.status == 'actioned'
def test_service_account_fe_disable(session, standard_graph, http_client, base_url): graph = standard_graph admin = "*****@*****.**" owner = "*****@*****.**" plebe = "*****@*****.**" # Unrelated people cannot disable the service account. fe_url = url(base_url, "/groups/security-team/service/[email protected]/disable") with pytest.raises(HTTPError): yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": plebe}, body=urlencode({})) # Group members can disable the service account. resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": owner}, body=urlencode({})) assert resp.code == 200 graph.update_from_db(session) metadata = graph.user_metadata["*****@*****.**"] assert not metadata["enabled"] group_details = graph.get_group_details("team-sre") assert "service_accounts" not in group_details # The group owner cannot enable the account, since the group ownership has been lost fe_url = url(base_url, "/service/[email protected]/enable") with pytest.raises(HTTPError): yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": owner}, body=urlencode({"owner": "team-sre"})) # A global admin can enable the account. resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": admin}, body=urlencode({"owner": "team-sre"})) assert resp.code == 200 graph.update_from_db(session) metadata = graph.user_metadata["*****@*****.**"] assert metadata["enabled"] assert metadata["service_account"]["owner"] == "team-sre" group_details = graph.get_group_details("team-sre") assert group_details["service_accounts"] == ["*****@*****.**"] # And can also disable the account even though they're not a member of the group. fe_url = url(base_url, "/groups/security-team/service/[email protected]/disable") resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": admin}, body=urlencode({})) assert resp.code == 200 graph.update_from_db(session) metadata = graph.user_metadata["*****@*****.**"] assert not metadata["enabled"]
def test_user_disable(session, graph, users, user_admin_perm_to_auditors, http_client, base_url): username = u"*****@*****.**" old_groups = sorted(get_groups(graph, username)) # disable user fe_url = url(base_url, "/users/{}/disable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({})) assert resp.code == 200 # enable user, PRESERVE groups fe_url = url(base_url, "/users/{}/enable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({"preserve_membership": "true"})) assert resp.code == 200 graph.update_from_db(session) assert old_groups == sorted(get_groups(graph, username)), 'nothing should be removed' # disable and enable, PURGE groups fe_url = url(base_url, "/users/{}/disable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({})) assert resp.code == 200 fe_url = url(base_url, "/users/{}/enable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({})) assert resp.code == 200 graph.update_from_db(session) assert len(get_groups(graph, username)) == 0, 'all group membership should be removed'
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_fe_password_add(session, users, http_client, base_url): user = users["*****@*****.**"] fe_url = url(base_url, "/users/{}/passwords/add".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"name": "test", "password": TEST_PASSWORD}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 user = session.query(User).filter_by(name="*****@*****.**").scalar() assert len(user_passwords(session, user)) == 1, "The user should have a password now" assert user_passwords(session, user)[0].name == "test", "The password should have the name given" assert ( user_passwords(session, user)[0].password_hash != TEST_PASSWORD ), "The password should not be available as plain text" with pytest.raises(HTTPError): fe_url = url(base_url, "/users/{}/passwords/add".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"name": "test", "password": TEST_PASSWORD}), headers={"X-Grouper-User": "******"}, ) fe_url = url(base_url, "/users/{}/passwords/add".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"name": "test", "password": TEST_PASSWORD}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 user = session.query(User).filter_by(name="*****@*****.**").scalar() assert len(user_passwords(session, user)) == 1, "Adding a password with the same name should fail" user = session.query(User).filter_by(name="*****@*****.**").scalar() fe_url = url(base_url, "/users/{}/passwords/add".format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({"name": "test", "password": TEST_PASSWORD}), headers={"X-Grouper-User": user.username}, ) assert resp.code == 200 user = session.query(User).filter_by(name="*****@*****.**").scalar() assert ( len(user_passwords(session, user)) == 1 ), "The user should have a password now (duplicate names are permitted for distinct users)" assert user_passwords(session, user)[0].name == "test", "The password should have the name given" assert ( user_passwords(session, user)[0].password_hash != TEST_PASSWORD ), "The password should not be available as plain text"
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_shell(session, users, http_client, base_url): with patch('grouper.fe.handlers.user_shell.settings') as mock_settings: mock_settings.shell = [['/bin/bash', 'bash'], ['/bin/zsh', 'zsh']] user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) user = User.get(session, name=user.username) fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({'shell': "/bin/bash"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash") fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({'shell': "/bin/fish"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) is not None, \ "The user should have shell metadata" assert get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash" fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch( fe_url, method="POST", body=urlencode({'shell': "/bin/zsh"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key( session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh")
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_permissions(permissions, http_client, base_url, session, graph): api_url = url(base_url, '/permissions') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["permissions"]) == sorted(permissions) api_url = url(base_url, '/permissions/{}'.format("team-sre")) resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok"
def test_request_emails_reference(session, groups, permissions, users, base_url, http_client): tech = groups["tech-ops"] tech.canjoin = "canask" tech.add(session) session.commit() # Explicitly requery because pulling from the users dict causes DetachedSessionErrors user = session.query(User).filter_by(username="******").scalar() fe_url = url(base_url, '/groups/{}/join'.format(tech.groupname)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({ "reason": "Test Request Please Ignore", "member": "User: {}".format(user.name) }), headers={'X-Grouper-User': user.username}) assert resp.code == 200 zay_emails = _get_unsent_and_mark_as_sent_emails_with_username( session, "*****@*****.**") assert any(["References: " in email.body for email in zay_emails])
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 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_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_shell(session, users, http_client, base_url): with patch('grouper.fe.handlers.user_shell.settings') as mock_settings: mock_settings.shell = [['/bin/bash', 'bash'], ['/bin/zsh', 'zsh']] user = users['*****@*****.**'] assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) user = User.get(session, name=user.username) fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'shell': "/bin/bash"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash") fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'shell': "/bin/fish"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) is not None, \ "The user should have shell metadata" assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash" fe_url = url(base_url, '/users/{}/shell'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'shell': "/bin/zsh"}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY) is not None, \ "The user should have shell metadata" assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh")
def test_groups(groups, http_client, base_url): api_url = url(base_url, '/groups') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["groups"]) == sorted(groups)
def test_users(users, http_client, base_url): all_users = sorted(users.keys() + ["*****@*****.**"]) users_wo_role = sorted([u for u in users if u != u"*****@*****.**"]) api_url = url(base_url, "/users") resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["users"]) == users_wo_role api_url = url(base_url, "/users?include_role_users=yes") resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["users"]) == all_users
def test_service_accounts(users, http_client, base_url): api_url = url(base_url, '/service_accounts') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) service_accounts = sorted([user.name for user in users.values() if user.role_user]) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["service_accounts"]) == service_accounts
def test_list_groups(async_server, browser, groups): # noqa: F811 fe_url = url(async_server, "/groups") browser.get(fe_url) page = GroupsViewPage(browser) for name, _ in groups.iteritems(): row = page.find_group_row(name) assert row.href.endswith("/groups/{}".format(name))
def test_fe_password_delete(session, users, http_client, base_url): user = users['*****@*****.**'] fe_url = url(base_url, '/users/{}/passwords/add'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': "test", "password": TEST_PASSWORD}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = session.query(User).filter_by(name="*****@*****.**").scalar() assert len(user_passwords(session, user)) == 1, "The user should have a password now" assert user_passwords(session, user)[0].name == "test", "The password should have the name given" assert user_passwords(session, user)[0].password_hash != TEST_PASSWORD, "The password should not be available as plain text" user = session.query(User).filter_by(name="*****@*****.**").scalar() fe_url = url(base_url, '/users/{}/passwords/add'.format(user.username)) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': "test", "password": TEST_PASSWORD}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = session.query(User).filter_by(name="*****@*****.**").scalar() assert len(user_passwords(session, user)) == 1, "The user should have a password now (duplicate names are permitted for distinct users)" assert user_passwords(session, user)[0].name == "test", "The password should have the name given" assert user_passwords(session, user)[0].password_hash != TEST_PASSWORD, "The password should not be available as plain text" with pytest.raises(HTTPError): user = session.query(User).filter_by(name="*****@*****.**").scalar() fe_url = url(base_url, '/users/{}/passwords/{}/delete'.format(user.username, user_passwords(session, user)[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': "******"}) user = session.query(User).filter_by(name="*****@*****.**").scalar() fe_url = url(base_url, '/users/{}/passwords/{}/delete'.format(user.username, user_passwords(session, user)[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = session.query(User).filter_by(name="*****@*****.**").scalar() assert len(user_passwords(session, user)) == 0, "The password should have been deleted" user = session.query(User).filter_by(name="*****@*****.**").scalar() assert len(user_passwords(session, user)) == 1, "Other user's passwords should not have been deleted"
def test_user_disable(session, graph, users, user_admin_perm_to_auditors, http_client, base_url): username = u"*****@*****.**" old_groups = sorted(get_groups(graph, username)) # disable user fe_url = url(base_url, "/users/{}/disable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({})) assert resp.code == 200 # enable user, PRESERVE groups fe_url = url(base_url, "/users/{}/enable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode( {"preserve_membership": "true"})) assert resp.code == 200 graph.update_from_db(session) assert old_groups == sorted(get_groups( graph, username)), 'nothing should be removed' # disable and enable, PURGE groups fe_url = url(base_url, "/users/{}/disable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({})) assert resp.code == 200 fe_url = url(base_url, "/users/{}/enable".format(username)) resp = yield http_client.fetch(fe_url, method="POST", headers={"X-Grouper-User": "******"}, body=urlencode({})) assert resp.code == 200 graph.update_from_db(session) assert len(get_groups( graph, username)) == 0, 'all group membership should be removed'
def test_show_group(async_server, browser, groups): # noqa: F811 fe_url = url(async_server, "/groups/team-sre") browser.get(fe_url) page = GroupViewPage(browser) members = groups["team-sre"].my_members() for [_, username], _ in members.iteritems(): row = page.find_member_row(username) assert row.href.endswith("/users/{}".format(username))
def test_bad_public_key(session, users, http_client, base_url): user = users['*****@*****.**'] 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': SSH_KEY_BAD}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Public key appears to be invalid" in resp.body assert not get_public_keys_of_user(session, user.id)
def test_group_request(session, users, groups, http_client, base_url): user = users['*****@*****.**'] group = groups['sad-team'] # Request to join fe_url = url(base_url, '/groups/{}/join'.format(group.groupname)) resp = yield http_client.fetch( fe_url, method='POST', headers={'X-Grouper-User': user.username}, body=urlencode({ 'reason': 'Test Request', 'member': 'User: [email protected]' }), ) assert resp.code == 200 request = Request.get(session, requester_id=user.id, requesting_id=group.id) assert request.status == 'pending' # Approve request fe_url = url(base_url, '/groups/{}/requests/{}'.format(group.groupname, request.id)) resp = yield http_client.fetch( fe_url, method='POST', headers={'X-Grouper-User': '******'}, body=urlencode({ 'reason': 'Test Request', 'status': 'actioned' }), ) assert resp.code == 200 request = Request.get(session, requester_id=user.id, requesting_id=group.id) assert request.status == 'actioned'
def test_users(users, http_client, base_url): api_url = url(base_url, '/users') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) users_wo_role = sorted((u for u in users if u != u"*****@*****.**")) print 'user_wo_role={}'.format(users_wo_role) print 'res={}'.format(sorted(body["data"]["users"])) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["users"]) == users_wo_role
def test_service_accounts(session, standard_graph, users, http_client, base_url): graph = standard_graph service_accounts = sorted([u.name for u in users.values() if u.role_user] + ["*****@*****.**"]) api_url = url(base_url, "/service_accounts") resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"]["service_accounts"]) == service_accounts # TODO: test cutoff # Retrieve a single service account and check its metadata. api_url = url(base_url, "/service_accounts/[email protected]") resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" data = body["data"]["user"] assert "service_account" in data assert data["service_account"]["description"] == "some service account" assert data["service_account"]["machine_set"] == "some machines" assert data["service_account"]["owner"] == "team-sre" assert body["data"]["permissions"] == [] # Delegate a permission to the service account and check for it. service_account = ServiceAccount.get(session, name="*****@*****.**") permission = Permission.get(session, name="team-sre") grant_permission_to_service_account(session, service_account, permission, "*") graph.update_from_db(session) resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" permissions = body["data"]["permissions"] assert permissions[0]["permission"] == "team-sre" assert permissions[0]["argument"] == "*"
def test_public_key(session, users, http_client, base_url): user = users['*****@*****.**'] assert not user.my_public_keys() good_key = ('ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCUQeasspT/etEJR2WUoR+h2sMOQYbJgr0Q' 'E+J8p97gEhmz107KWZ+3mbOwyIFzfWBcJZCEg9wy5Paj+YxbGONqbpXAhPdVQ2TLgxr41bNXvbcR' 'AxZC+Q12UZywR4Klb2kungKz4qkcmSZzouaKK12UxzGB3xQ0N+3osKFj3xA1+B6HqrVreU19XdVo' 'AJh0xLZwhw17/NDM+dAcEdMZ9V89KyjwjraXtOVfFhQF0EDF0ame8d6UkayGrAiXC2He0P2Cja+J' '371P27AlNLHFJij8WGxvcGGSeAxMLoVSDOOllLCYH5UieV8mNpX1kNe2LeA58ciZb0AXHaipSmCH' 'gh/ some-comment') bad_key = 'ssh-rsa AAAblahblahkey some-comment' # add it 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': good_key}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 # add bad key -- shouldn't add 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': bad_key}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) keys = user.my_public_keys() assert len(keys) == 1 assert keys[0].public_key == good_key # delete it fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format(user.username, keys[0].id)) resp = yield http_client.fetch(fe_url, method="POST", body='', headers={'X-Grouper-User': user.username}) assert resp.code == 200 user = User.get(session, name=user.username) assert not user.my_public_keys()
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_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_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_multi_users(users, http_client, base_url): def make_url(*usernames): query_args = urlencode({'username': usernames}, doseq=True) return url(base_url, '/multi/users?{}'.format(query_args)) # Test case when no usernames are provided api_url = make_url() resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" # Service Accounts should be included assert sorted(body["data"].iterkeys()) == sorted(users.keys() + ['*****@*****.**']) # Test case when only valid usernames are provided api_url = make_url('*****@*****.**', '*****@*****.**', '*****@*****.**') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" # Service Accounts should be included assert sorted(body["data"].iterkeys()) == [ '*****@*****.**', '*****@*****.**', '*****@*****.**' ] # Verify that we return the same data as the single user endpoint for username, data in body["data"].iteritems(): r = yield http_client.fetch(url(base_url, '/users/{}'.format(username))) rbody = json.loads(r.body) assert data == rbody["data"] # Ensure that nonexistent usernames are ignored api_url = make_url('*****@*****.**', '*****@*****.**', '*****@*****.**') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"].iterkeys()) == ['*****@*****.**', '*****@*****.**'] # Test when only nonexistent usernames are given api_url = make_url('*****@*****.**', '*****@*****.**') resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert resp.code == 200 assert body["status"] == "ok" assert sorted(body["data"].iterkeys()) == []
def test_groups_email(groups, session, graph, http_client, base_url): expected_address = "*****@*****.**" sad = groups['sad-team'] sad.email_address = expected_address session.commit() Counter.incr(session, "updates") graph.update_from_db(session) api_url = url(base_url, '/groups/{}'.format(sad.name)) resp = yield http_client.fetch(api_url) body = json.loads(resp.body) assert body["data"]["group"]["contacts"]["email"] == expected_address
def test_create_tag(users, http_client, base_url, session): user = session.query(User).filter_by(username="******").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}) assert resp.code == 200 tag = PublicKeyTag.get(session, name="tyler_was_here") assert tag is not None, "The tag should be created" assert tag.name == "tyler_was_here", "The tag's name should be tyler_was_here"
def test_rejected_public_key(session, users, http_client, base_url): user = users['*****@*****.**'] with patch('grouper.public_key.add_public_key') as add_public_key: add_public_key.side_effect = BadPublicKey("Your key is bad and you should feel bad") 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': SSH_KEY_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Your key is bad and you should feel bad" in resp.body assert not get_public_keys_of_user(session, user.id)
def test_sa_tokens(session, users, http_client, base_url): user = users['*****@*****.**'] # Add account create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin') u = User.get(session, name="*****@*****.**") g = Group.get(session, name="*****@*****.**") assert u is not None assert g is not None assert is_role_user(session, user=u) assert is_role_user(session, group=g) assert get_role_user(session, user=u).group.id == g.id assert get_role_user(session, group=g).user.id == u.id assert not is_role_user(session, user=user) assert not is_role_user(session, group=Group.get(session, name="team-sre")) with pytest.raises(HTTPError): # Add token fe_url = url(base_url, '/users/{}/tokens/add'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': 'myDHDToken'}), headers={'X-Grouper-User': "******"}) # Add token fe_url = url(base_url, '/users/{}/tokens/add'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({'name': 'myDHDToken'}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 # Verify add fe_url = url(base_url, '/users/{}'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="GET", headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Added token: myDHDToken" in resp.body with pytest.raises(HTTPError): # Disable token fe_url = url(base_url, '/users/{}/tokens/1/disable'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': "******"}) # Disable token fe_url = url(base_url, '/users/{}/tokens/1/disable'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="POST", body="", headers={'X-Grouper-User': user.username}) assert resp.code == 200 # Verify disable fe_url = url(base_url, '/users/{}'.format("*****@*****.**")) resp = yield http_client.fetch(fe_url, method="GET", headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Disabled token: myDHDToken" in resp.body
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_rejected_public_key(session, users, http_client, base_url): user = users['*****@*****.**'] with patch('grouper.public_key.add_public_key') as add_public_key: add_public_key.side_effect = BadPublicKey( "Your key is bad and you should feel bad") 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': SSH_KEY_1}), headers={'X-Grouper-User': user.username}) assert resp.code == 200 assert "Your key is bad and you should feel bad" in resp.body assert not get_public_keys_of_user(session, user.id)