Example #1
0
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)
Example #2
0
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)
Example #4
0
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!"
Example #5
0
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"
Example #6
0
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"
Example #7
0
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"))
Example #8
0
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)
Example #10
0
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"
Example #11
0
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"
Example #12
0
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"))
Example #13
0
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"
Example #14
0
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)
Example #15
0
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
Example #16
0
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'
Example #17
0
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_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"]
Example #19
0
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'
Example #20
0
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"
Example #21
0
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"
Example #22
0
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"
Example #23
0
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")
Example #24
0
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"
Example #25
0
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"
Example #26
0
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])
Example #28
0
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"
Example #29
0
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"*****@*****.**"])
Example #31
0
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")
Example #32
0
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)
Example #33
0
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
Example #34
0
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)
Example #35
0
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
Example #36
0
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
Example #37
0
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))
Example #38
0
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"
Example #39
0
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'
Example #40
0
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))
Example #41
0
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_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)
Example #44
0
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
Example #45
0
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"] == "*"
Example #47
0
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"}))
Example #48
0
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()
Example #49
0
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"
Example #50
0
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
Example #51
0
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()) == []
Example #53
0
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
Example #54
0
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"
Example #55
0
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)
Example #56
0
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
Example #57
0
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)