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
예제 #2
0
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
예제 #3
0
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()
            )
예제 #4
0
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()
            )
예제 #5
0
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!")
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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")