def test_create_new_user_api(): """Test whether assigned manager id is present in the data of user""" with requests.Session() as session: create_next_admin(session) create_manager_payload = { "name": "manager_name", "username": "******", "password": "******", "email": "manager@email_id", } manager_creation_response = create_test_user(session, create_manager_payload) manager_id = manager_creation_response.json()["data"]["user"]["id"] user_create_payload = { "name": "user_name", "username": "******", "password": "******", "email": "user@email_id", "manager": manager_id, } user_creation_response = session.post( "http://rbac-server:8000/api/users", json=user_create_payload) user_id = user_creation_response.json()["data"]["user"]["id"] wait_for_resource_in_db("users", "name", "user_name") user_details_response = session.get( "http://rbac-server:8000/api/users/" + user_id) assert user_details_response.json()["data"]["manager"] == manager_id
def add_role_member(session, role_id, payload): """Create a proposal for adding a role member Args: session: object: current session object role_id: str: id of role that is to be added to payload: dictionary: in the format of { "id": "id of user to be added" } """ response = session.post( "http://rbac-server:8000/api/roles/{}/members".format(role_id), json=payload ) wait_for_resource_in_db("role_members", "role_id", role_id) return response
def test_approve_update_manager(user, approver, expected_status_code): """ Tests four UpdateUserManager proposal approval scenarios: 1. NextAdmin approves the proposal 2. A random user tries to approve the proposal 3. New manager (related_id of proposal) tries to approve the proposal 4. Manager of NextAdmin tries to approve the proposal Args: user: (dict) User object that will be added to the role. Dict should contain the following field: { next_id: str } approver: (dict) User object of the approver. Dict should contain the following fields: { username: str password: str } expected_status_code: (int) Expected HTTP response code (either 200 or 401) """ user_id = user["next_id"] update_user_payload = {"id": TEST_USERS[2]["next_id"]} with requests.Session() as session: # Create UpdateUserManager proposal create_next_admin(session) response = update_manager(session, user_id, update_user_payload) LOGGER.info(response) proposal_id = response.json()["proposal_id"] proposal_exists = wait_for_resource_in_db( "proposals", "proposal_id", proposal_id ) if proposal_exists: # Attempt to approve the UpdateUserManager proposal if approver != "next_admin": log_in_payload = { "id": approver["username"], "password": approver["password"], } user_login(session, log_in_payload["id"], log_in_payload["password"]) approval_response = approve_proposal(session, proposal_id) assert ( approval_response.status_code == expected_status_code ), "An error occurred while approving UpdateUserManager proposal: {}".format( approval_response.json() )
def test_add_role_owner(user, approver, expected_status_code): """ Tests three AddRoleOwner proposal approval scenarios: 1. Role owner approves the proposal 2. A random user tries to approve the proposal 3. Role owner's manager approves the proposal Args: user: (dict) User object that will be added to the role. Dict should contain the following field: { next_id: str } approver: (dict) User object of the approver. Dict should contain the following fields: { username: str password: str } expected_status_code: (int) Expected HTTP response code (either 200 or 401) """ log_in_payload = {"id": approver["username"], "password": approver["password"]} add_role_member_payload = {"id": user["next_id"]} role_id = TEST_ROLES[0]["role_id"] with requests.Session() as session: # Create AddRoleOwner proposal user_login(session, log_in_payload["id"], log_in_payload["password"]) response = add_role_owner(session, role_id, add_role_member_payload) proposal_id = response.json()["proposal_id"] proposal_exists = wait_for_resource_in_db( "proposals", "proposal_id", proposal_id ) if proposal_exists: # Attempt to approve the AddRoleOwner proposal approval_response = approve_proposal(session, proposal_id) assert ( approval_response.status_code == expected_status_code ), "An error occurred while approving AddRoleOwner proposal: {}".format( approval_response.json() )
def add_admin_accounts(): """Create the admin accounts for NEXT after waiting for server to come up.""" LOGGER.info("Waiting for RethinkDB to initialize.") is_rethink_ready = wait_for_rethink() if not is_rethink_ready: LOGGER.error( "Max attempts exceeded. There is likely an issue with RethinkDB. Exiting admin bootstrapping. :(" ) exit(1) LOGGER.info("RethinkDB has successfully initialized.") env = Env() LOGGER.info("Creating default admin user and role.") with requests.Session() as session: attempts = 0 server_ready = False while not server_ready and attempts < 100: response = session.options("http://rbac-server:8000/api/users") if response.status_code == 200: server_ready = True attempts += 1 time.sleep(0.5) if not server_ready: LOGGER.error( "Max attempts exceeded. There's likely an issue with the API server. Exiting admin bootstrapping. :(" ) exit(1) LOGGER.warning("Creating Next Admin user...") admin_user = { "name": env("NEXT_ADMIN_NAME"), "username": env("NEXT_ADMIN_USER"), "password": env("NEXT_ADMIN_PASS"), "email": env("NEXT_ADMIN_EMAIL"), } response = session.post("http://rbac-server:8000/api/users", json=admin_user) user_response_json = response.json() if response.status_code >= 300: LOGGER.error("There was an issue with creating Admin user: %s", user_response_json) exit(1) user_next_id = user_response_json["data"]["user"]["id"] is_user_ready = wait_for_resource_in_db("users", "next_id", user_next_id, max_attempts=200) if not is_user_ready: LOGGER.error( "Max attempts exceeded. %s user not found in RethinkDB", admin_user["name"], ) exit(1) login = { "id": env("NEXT_ADMIN_USER"), "password": env("NEXT_ADMIN_PASS") } response = session.post("http://rbac-server:8000/api/authorization/", json=login) token = "Bearer " + response.json()["token"] session.headers.update({"Authorization": token}) LOGGER.info("Creating NextAdmin role...") admin_role = { "name": "NextAdmins", "owners": user_next_id, "administrators": user_next_id, } role_response = session.post("http://rbac-server:8000/api/roles", json=admin_role) role_response_json = role_response.json() if role_response.status_code >= 300: LOGGER.error("There was an issue with creating Admin Role. %s", role_response_json) exit(1) role_next_id = role_response_json["data"]["id"] is_role_ready = wait_for_resource_in_db("roles", "role_id", role_next_id, max_attempts=100) if not is_role_ready: LOGGER.error( "Max attempts exceeded. %s role not found in RethinkDB.", admin_role["name"], ) exit(1) LOGGER.info("Adding Next Admin to NextAdmins role...") add_user = { "pack_id": None, "id": user_next_id, "reason": None, "metadata": None, } add_role_member_response = session.post( ("http://rbac-server:8000/api/roles/{}/members".format( role_next_id)), json=add_user, ) add_role_member_response_json = add_role_member_response.json() if add_role_member_response.status_code >= 300: LOGGER.error( "There was an issue with making the Admin a member of NextAdmins: %s", add_role_member_response_json, ) exit(1) is_member_ready = wait_for_resource_in_db("role_members", "role_id", role_next_id, max_attempts=100) if not is_member_ready: LOGGER.exit( "Max attempts exceeded. %s member not found for %s role in Rethinkdb", user_next_id, role_next_id, ) exit(1) LOGGER.info("Next Admin account and role creation complete!")
def create_next_admin(session): """Utility function to create/login as a Next admin and return logged in state Args: session: obj: a requests storage session""" env = Env() next_admin = get_user_by_username(env("NEXT_ADMIN_USER")) next_admin_role = get_role_by_name("NextAdmins") if next_admin_role: user_login(session, env("NEXT_ADMIN_USER"), env("NEXT_ADMIN_PASS")) role_members = get_role_members(next_admin_role[0]["role_id"]) if not role_members: add_role_member( session, next_admin_role[0]["role_id"], {"id": next_admin[0]["next_id"]} ) if not next_admin: admin_payload = { "name": env("NEXT_ADMIN_NAME"), "username": env("NEXT_ADMIN_USER"), "email": env("NEXT_ADMIN_EMAIL"), "password": env("NEXT_ADMIN_PASS"), } created_admin = create_test_user(session, admin_payload) admin_id = created_admin.json()["data"]["user"]["id"] wait_for_resource_in_db("auth", "next_id", admin_id) logged_in_admin = user_login( session, env("NEXT_ADMIN_USER"), env("NEXT_ADMIN_PASS") ) next_admins = { "name": "NextAdmins", "owners": admin_id, "administrators": admin_id, } role_response = create_test_role(session, next_admins) wait_for_resource_in_db("roles", "name", "NextAdmins") add_role_member(session, role_response.json()["data"]["id"], {"id": admin_id}) wait_for_resource_in_db( "role_members", "role_id", role_response.json()["data"]["id"] ) elif not next_admin_role: logged_in_admin = user_login( session, env("NEXT_ADMIN_USER"), env("NEXT_ADMIN_PASS") ) next_admins = { "name": "NextAdmins", "owners": next_admin[0]["next_id"], "administrators": next_admin[0]["next_id"], } role_response = create_test_role(session, next_admins) wait_for_resource_in_db("roles", "name", "NextAdmins") add_role_member( session, role_response.json()["data"]["id"], {"id": logged_in_admin.json()["data"]["next_id"]}, ) wait_for_resource_in_db( "role_members", "role_id", role_response.json()["data"]["id"] ) else: logged_in_admin = user_login( session, env("NEXT_ADMIN_USER"), env("NEXT_ADMIN_PASS") ) return logged_in_admin
def create_test_role(session, role_payload): """Create a role and authenticate to use api endpoints during testing.""" response = session.post("http://rbac-server:8000/api/roles", json=role_payload) wait_for_resource_in_db("roles", "name", role_payload["name"]) return response
def create_test_user(session, user_payload): """Create a user and authenticate to use api endpoints during testing.""" response = session.post("http://rbac-server:8000/api/users", json=user_payload) wait_for_resource_in_db("users", "username", user_payload["username"]) return response
def test_user_delete_api(): """Test that user has been removed from database when users delete api is hit""" user = { "name": "nadia one", "username": "******", "password": "******", "email": "*****@*****.**", } with requests.Session() as session: create_next_admin(session) response = create_test_user(session, user) next_id = response.json()["data"]["user"]["id"] wait_for_resource_in_db("users", "next_id", next_id) with requests.Session() as session: user_login(session, "nadia1", "test11") role_payload = { "name": "test_role", "owners": [next_id], "administrators": [next_id], "description": "This is a test Role", } role_resp = create_test_role(session, role_payload) role_id = role_resp.json()["data"]["id"] pack = { "name": "michael pack one", "owners": [next_id], "roles": [], "description": "Michael's test pack", } pack_response = create_test_pack(session, pack) add_role_member_payload = { "id": next_id, "reason": "Integration test of adding a member.", "metadata": "", } add_role_member(session, role_id, add_role_member_payload) wait_for_resource_in_db("role_members", "role_id", role_id) conn = connect_to_db() user_exists = (r.table("users").filter({ "next_id": next_id }).coerce_to("array").run(conn)) role_owner_exists = (r.table("role_owners").filter({ "identifiers": [next_id], "role_id": role_id }).coerce_to("array").run(conn)) role_member_exists = (r.table("role_members").filter({ "identifiers": [next_id], "role_id": role_id }).coerce_to("array").run(conn)) assert user_exists assert role_owner_exists assert role_member_exists assert get_user_mapping_entry(next_id) assert get_auth_entry(next_id) assert get_user_metadata_entry(next_id) assert check_user_is_pack_owner( pack_id=pack_response.json()["data"]["pack_id"], next_id=next_id) role_admin_is_user = (r.db("rbac").table("role_admins").filter({ "related_id": next_id }).coerce_to("array").run(conn)) role_admin = role_admin_is_user[0]["identifiers"][0] assert role_admin == next_id deletion = session.delete("http://rbac-server:8000/api/users/" + next_id) time.sleep(5) assert deletion.json() == { "message": "User {} successfully deleted".format(next_id), "deleted": 1, } role_admin_user = (r.db("rbac").table("role_admins").filter({ "related_id": next_id }).coerce_to("array").run(conn)) role_owners = ( r.db("rbac").table("role_owners").filter(lambda doc: doc[ "identifiers"].contains(next_id)).coerce_to("array").run(conn)) role_members = ( r.db("rbac").table("role_members").filter(lambda doc: doc[ "identifiers"].contains(next_id)).coerce_to("array").run(conn)) delete_role_by_name("test_role") conn.close() assert role_admin_user == [] assert role_members == [] assert role_owners == [] assert get_deleted_user_entries(next_id) == [] assert get_pack_owners_by_user(next_id) == [] delete_pack_by_name("michael pack one")
def test_delete_role_with_members(): """ Test the delete roll api Create a test user for auth Create a test role Add the first user as a member of the role Deletes the test role Check that the role member object was deleted """ with requests.Session() as session: # Create test user user_payload = { "name": "Walt the Dog", "username": "******", "password": "******", "email": "*****@*****.**", } create_next_admin(session) user_response = create_test_user(session, user_payload) assert user_response.status_code == 200, ( "Error creating user: %s" % user_response.json() ) user_id = user_response.json()["data"]["user"]["id"] with requests.Session() as session: user_login(session, "walt1", "12345678") # Create test role role_resource = { "name": "Phatt Island Jail", "owners": user_id, "administrators": user_id, } role_response = session.post( "http://rbac-server:8000/api/roles", json=role_resource ) assert role_response.status_code == 200, ( "Error creating role: %s" % role_response.json() ) # Wait for role in db role_id = role_response.json()["data"]["id"] is_role_in_db = wait_for_role_in_db(role_id) assert ( is_role_in_db is True ), "Couldn't find role in rethinkdb, maximum attempts exceeded." # Add role member role_update_payload = { "id": user_id, "reason": "Integration test of member removal on role deletion.", "metadata": "", } member_response = session.post( "http://rbac-server:8000/api/roles/{}/members".format(role_id), json=role_update_payload, ) assert member_response.status_code == 200, ( "Error adding role member: %s" % member_response.json() ) # Wait for member in rethinkdb is_member_in_db = wait_for_resource_in_db("role_members", "related_id", user_id) assert ( is_member_in_db is True, ), "Couldn't find member in rethinkdb, maximum attempts exceeded." # Delete test role delete_role_response = session.delete( "http://rbac-server:8000/api/roles/%s" % role_id ) assert delete_role_response.status_code == 200, ( "Error deleting role: %s" % delete_role_response.json() ) # Check for role members are_members_removed = wait_for_resource_removal_in_db( "role_members", "role_id", role_id ) assert are_members_removed is True # clean up delete_user_by_username("walt1")