Example #1
0
def user_admin_perm_to_auditors(session, groups):
    """Adds a USER_ADMIN permission to the "auditors" group"""
    user_admin_perm, is_new = Permission.get_or_create(
        session, name=USER_ADMIN, description="grouper.admin.users permission")
    session.commit()

    grant_permission(groups["auditors"], user_admin_perm)
Example #2
0
def user_admin_perm_to_auditors(session, groups):
    """Adds a USER_ADMIN permission to the "auditors" group"""
    user_admin_perm, is_new = Permission.get_or_create(session, name=USER_ADMIN,
        description="grouper.admin.users permission")
    session.commit()

    grant_permission(groups["auditors"], user_admin_perm)
Example #3
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"
Example #4
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 #5
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 #6
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 #7
0
def test_grant_permission(session, standard_graph, groups, permissions):
    grant_permission(groups["sad-team"], permissions["ssh"], argument="host +other-host")
    with pytest.raises(AssertionError):
        grant_permission(groups["sad-team"], permissions["ssh"], argument="question?")
    account = ServiceAccount.get(session, name="*****@*****.**")
    grant_permission_to_service_account(session, account, permissions["ssh"], argument="*")
    with pytest.raises(AssertionError):
        grant_permission_to_service_account(
            session, account, permissions["ssh"], argument="question?")
Example #8
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 #9
0
def test_regress_permreq_global_approvers(session, standard_graph, groups, grantable_permissions,
        http_client, base_url):
    """Validates that we can render a permission request form where a global approver exists"""
    perm_grant, _, perm1, _ = grantable_permissions
    perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    groupname = "sad-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url, method="GET",
            headers={'X-Grouper-User': username})
    assert resp.code == 200
Example #10
0
def test_grantable_permissions(session, standard_graph, users, groups, grantable_permissions):
    perm_grant, perm0, perm1, _ = grantable_permissions

    assert not user_grantable_permissions(session, users["*****@*****.**"]), "start with none"

    grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one")
    assert not user_grantable_permissions(session, users["*****@*****.**"]), "grant on non-existent is fine"

    grant_permission(groups["auditors"], perm_grant, argument=perm0.name)
    grants = user_grantable_permissions(session, users["*****@*****.**"])
    assert len(grants) == 1, "only specific permission grant"
    assert grants[0][0].name == perm0.name, "only specific permission grant"

    grant_permission(groups["auditors"], perm_grant, argument="grantable.*")
    grants = user_grantable_permissions(session, users["*****@*****.**"])
    assert len(grants) == 3, "wildcard grant should grab appropriat amount"
    assert sorted([x[0].name for x in grants]) == ["grantable", "grantable.one", "grantable.two"]

    args_by_perm = get_grantable_permissions(session, None)
    assert args_by_perm[perm1.name] == ["*"], "wildcard grant reflected in list of grantable"

    grant_permission(groups["auditors"], perm_grant, argument="{}/single_arg".format(perm1.name))
    args_by_perm = get_grantable_permissions(session, None)
    assert args_by_perm[perm1.name] == ["*"], "wildcard grant reflected cause no restricted perms"

    args_by_perm = get_grantable_permissions(session, [perm1.name])
    assert args_by_perm[perm1.name] == ["single_arg"], "least permissive argument shown cause of restricted perms"
Example #11
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"
Example #12
0
def test_tags(session, http_client, base_url, graph):
    perm = Permission(name=TAG_EDIT, description="Why is this not nullable?")
    perm.add(session)
    session.commit()

    perm2 = Permission(name="it.literally.does.not.matter", description="Why is this not nullable?")
    perm2.add(session)
    session.commit()

    grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*")
    grant_permission(session.query(Group).filter_by(groupname="all-teams").scalar(), session.query(Permission).filter_by(name="it.literally.does.not.matter").scalar(), "*")

    tag = PublicKeyTag(name="tyler_was_here")
    tag.add(session)
    session.commit()

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    grant_permission_to_tag(session, tag.id, perm.id, "prod")
    with pytest.raises(AssertionError):
        grant_permission_to_tag(session, tag.id, perm.id, "question?")

    user = session.query(User).filter_by(username="******").scalar()

    add_public_key(session, user, SSH_KEY_1)

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()

    add_tag_to_public_key(session, key, tag)

    user = session.query(User).filter_by(username="******").scalar()

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()
    assert len(get_public_key_permissions(session, key)) == 1, "The SSH Key should have only 1 permission"
    assert get_public_key_permissions(session, key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT"
    assert get_public_key_permissions(session, key)[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument"
    assert len(user_permissions(session, user)) > 1, "The user should have more than 1 permission"

    graph.update_from_db(session)

    fe_url = url(base_url, '/users/{}'.format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    pub_key = body['data']['user']['public_keys'][0]
    assert len(pub_key['tags']) == 1, "The public key should only have 1 tag"
    assert pub_key['fingerprint'] == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35'
    assert pub_key['fingerprint_sha256'] == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU'
    assert pub_key['tags'][0] == 'tyler_was_here', "The public key should have the tag we gave it"
Example #13
0
def test_permission_grant_to_owners(session, standard_graph, groups, grantable_permissions):
    """Test we're getting correct owners according to granted
    'grouper.permission.grant' permissions."""
    perm_grant, _, perm1, perm2 = grantable_permissions

    assert not get_owners_by_grantable_permission(session), "nothing to begin with"

    # grant a grant on a non-existent permission
    grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one")
    assert not get_owners_by_grantable_permission(session), "ignore grants for non-existent perms"

    # grant a wildcard grant -- make sure all permissions are represented and
    # the grant isn't inherited
    grant_permission(groups["all-teams"], perm_grant, argument="grantable.*")
    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    expected = [groups["all-teams"]]
    assert owners_by_arg_by_perm[perm1.name]["*"] == expected, "grants are not inherited"
    assert len(owners_by_arg_by_perm) == 2
    assert len(owners_by_arg_by_perm[perm1.name]) == 1
    assert len(owners_by_arg_by_perm[perm2.name]) == 1

    # grant on argument substring
    grant_permission(groups["team-sre"], perm_grant, argument="{}/somesubstring*".format(perm1.name))
    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    expected = [groups["all-teams"]]
    assert owners_by_arg_by_perm[perm1.name]["*"] == expected
    expected = [groups["team-sre"]]
    assert owners_by_arg_by_perm[perm1.name]["somesubstring*"] == expected

    # make sure get_owner() respect substrings
    res = [
        o for o, a in get_owner_arg_list(session, perm1, "somesubstring", owners_by_arg_by_perm=owners_by_arg_by_perm)
    ]
    assert (
        sorted(res) == sorted([groups["all-teams"], groups["team-sre"]]),
        "should include substring wildcard matches",
    )

    res = [
        o for o, a in get_owner_arg_list(session, perm1, "othersubstring", owners_by_arg_by_perm=owners_by_arg_by_perm)
    ]
    assert sorted(res) == [groups["all-teams"]], "negative test of substring wildcard matches"

    # permission admins have all the power
    perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    all_permissions = Permission.get_all(session)
    for perm in all_permissions:
        assert perm.name in owners_by_arg_by_perm, "all permission should be represented"
        assert (
            groups["security-team"] in owners_by_arg_by_perm[perm.name]["*"]
        ), "permission admin should be wildcard owners"
def test_grant_permission(session, standard_graph, groups, permissions):
    grant_permission(groups["sad-team"],
                     permissions["ssh"],
                     argument="host +other-host")
    with pytest.raises(AssertionError):
        grant_permission(groups["sad-team"],
                         permissions["ssh"],
                         argument="question?")
    account = ServiceAccount.get(session, name="*****@*****.**")
    grant_permission_to_service_account(session,
                                        account,
                                        permissions["ssh"],
                                        argument="*")
    with pytest.raises(AssertionError):
        grant_permission_to_service_account(session,
                                            account,
                                            permissions["ssh"],
                                            argument="question?")
Example #15
0
def test_regress_permreq_global_approvers(session, standard_graph, groups,
                                          grantable_permissions, http_client,
                                          base_url):
    """Validates that we can render a permission request form where a global approver exists"""
    perm_grant, _, perm1, _ = grantable_permissions
    perm_admin, _ = Permission.get_or_create(session,
                                             name=PERMISSION_ADMIN,
                                             description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    groupname = "sad-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="GET",
                                   headers={'X-Grouper-User': username})
    assert resp.code == 200
Example #16
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"
Example #17
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 #18
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 #19
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"
def expiring_graph(session, graph, users, groups, permissions):
    now = datetime.utcnow()
    note_exp_now = now + timedelta(settings.expiration_notice_days)
    week = timedelta(7)

    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"],
               users["*****@*****.**"],
               expiration=note_exp_now + week)
    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["team-sre"],
               users["*****@*****.**"],
               role="owner",
               expiration=note_exp_now + week)
    revoke_member(groups["team-sre"], users["*****@*****.**"])
    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")

    add_member(groups["serving-team"], users["*****@*****.**"], role="owner")
    add_member(groups["serving-team"],
               groups["team-sre"],
               expiration=note_exp_now + week)
    add_member(groups["serving-team"], groups["tech-ops"])
    grant_permission(groups["serving-team"], permissions["audited"])

    add_member(groups["tech-ops"], users["*****@*****.**"], role="owner")
    add_member(groups["tech-ops"],
               users["*****@*****.**"],
               expiration=note_exp_now + 2 * week)
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")

    return graph
def test_limited_permissions(session, standard_graph, groups,
                             grantable_permissions, http_client, base_url):
    """Test that notifications are not sent to wildcard grant owners unless necessary."""
    perm_grant, _, perm1, _ = grantable_permissions
    # one super wildcard, one wildcard grant and one specific grant
    grant_permission(groups["sad-team"], perm_grant, argument="*")
    grant_permission(groups["all-teams"], perm_grant, argument="grantable.*")
    grant_permission(groups["security-team"],
                     perm_grant,
                     argument="{}/specific_arg".format(perm1.name))

    security_team_members = {
        name
        for (t, name) in groups['security-team'].my_members().keys()
        if t == 'User'
    }

    # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team'
    groupname = "sad-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "permission_name": perm1.name,
                                       "argument": "specific_arg",
                                       "reason": "blah blah black sheep",
                                       "argument_type": "text"
                                   }),
                                   headers={'X-Grouper-User': username})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert_same_recipients(emails, [u"*****@*****.**"])
Example #22
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 #23
0
def test_grantable_permissions(session, standard_graph, users, groups,
                               grantable_permissions):
    perm_grant, perm0, perm1, _ = grantable_permissions

    assert not user_grantable_permissions(
        session, users["*****@*****.**"]), "start with none"

    grant_permission(groups["auditors"],
                     perm_grant,
                     argument="notgrantable.one")
    assert not user_grantable_permissions(
        session, users["*****@*****.**"]), "grant on non-existent is fine"

    grant_permission(groups["auditors"], perm_grant, argument=perm0.name)
    grants = user_grantable_permissions(session, users["*****@*****.**"])
    assert len(grants) == 1, "only specific permission grant"
    assert grants[0][0].name == perm0.name, "only specific permission grant"

    grant_permission(groups["auditors"], perm_grant, argument="grantable.*")
    grants = user_grantable_permissions(session, users["*****@*****.**"])
    assert len(grants) == 3, "wildcard grant should grab appropriat amount"
    assert sorted([x[0].name for x in grants
                   ]) == ["grantable", "grantable.one", "grantable.two"]

    args_by_perm = get_grantable_permissions(session, None)
    assert args_by_perm[perm1.name] == [
        "*"
    ], "wildcard grant reflected in list of grantable"

    grant_permission(groups["auditors"],
                     perm_grant,
                     argument="{}/single_arg".format(perm1.name))
    args_by_perm = get_grantable_permissions(session, None)
    assert args_by_perm[perm1.name] == [
        "*"
    ], "wildcard grant reflected cause no restricted perms"

    args_by_perm = get_grantable_permissions(session, [perm1.name])
    assert args_by_perm[perm1.name] == ["single_arg"], \
            "least permissive argument shown cause of restricted perms"
Example #24
0
def test_basic_permission(standard_graph, session, users, groups, permissions):  # noqa
    """ Test adding some permissions to various groups and ensuring that the permissions are all
        implemented as expected. This also tests permissions inheritance in the graph. """

    graph = standard_graph  # noqa

    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")
    grant_permission(groups["team-infra"], permissions["sudo"], argument="shell")

    session.commit()
    graph.update_from_db(session)

    assert sorted(get_group_permissions(graph, "team-sre")) == ["ssh:*", "sudo:shell"]
    assert sorted(get_group_permissions(graph, "tech-ops")) == ["ssh:shell", "sudo:shell"]
    assert sorted(get_group_permissions(graph, "team-infra")) == ["sudo:shell"]
    assert sorted(get_group_permissions(graph, "all-teams")) == []

    assert sorted(get_user_permissions(graph, "gary")) == ["ssh:*", "ssh:shell", "sudo:shell"]
    assert sorted(get_user_permissions(graph, "zay")) == ["ssh:*", "ssh:shell", "sudo:shell"]
    assert sorted(get_user_permissions(graph, "zorkian")) == ["ssh:*", "sudo:shell"]
    assert sorted(get_user_permissions(graph, "testuser")) == []
Example #25
0
def expiring_graph(session, graph, users, groups, permissions):
    now = datetime.utcnow()
    note_exp_now = now + timedelta(settings.expiration_notice_days)
    week = timedelta(7)

    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"], expiration=note_exp_now+week)
    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner", expiration=note_exp_now+week)
    revoke_member(groups["team-sre"], users["*****@*****.**"])
    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")

    add_member(groups["serving-team"], users["*****@*****.**"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"], expiration=note_exp_now+week)
    add_member(groups["serving-team"], groups["tech-ops"])
    grant_permission(groups["serving-team"], permissions["audited"])

    add_member(groups["tech-ops"], users["*****@*****.**"], role="owner")
    add_member(groups["tech-ops"], users["*****@*****.**"], expiration=note_exp_now+2*week)
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")

    return graph
Example #26
0
def test_permission_request_flow(session, standard_graph, groups, grantable_permissions, http_client, base_url):
    """Test that a permission request gets into the system correctly and
    notifications are sent correctly."""
    perm_grant, _, perm1, perm2 = grantable_permissions
    grant_permission(groups["all-teams"], perm_grant, argument="grantable.*")

    # REQUEST: 'grantable.one', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode(
            {
                "permission_name": "grantable.one",
                "argument": "some argument",
                "reason": "blah blah black sheep",
                "argument_type": "text",
            }
        ),
        headers={"X-Grouper-User": username},
    )
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "only one user (and no group) should receive notification for request"

    perms = _load_permissions_by_group_name(session, "serving-team")
    assert len(perms) == 1
    assert "grantable.one" not in perms, "requested permission shouldn't be granted immediately"

    user = User.get(session, name="*****@*****.**")
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 0, "random user shouldn't have a request"

    user = User.get(session, name="*****@*****.**")
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 1, "user in group with grant should have a request"

    # APPROVE grant: have '*****@*****.**' action this request as owner of
    # 'all-teams' which has the grant permission for the requested permission
    request_id = request_tuple.requests[0].id
    fe_url = url(base_url, "/permissions/requests/{}".format(request_id))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"status": "actioned", "reason": "lgtm"}),
        headers={"X-Grouper-User": user.name},
    )
    assert resp.code == 200

    perms = _load_permissions_by_group_name(session, "serving-team")
    assert len(perms) == 2
    assert "grantable.one" in perms, "requested permission shouldn't be granted immediately"

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "requester should receive email as well"

    # (re)REQUEST: 'grantable.one', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode(
            {
                "permission_name": "grantable.one",
                "argument": "some argument",
                "reason": "blah blah black sheep",
                "argument_type": "text",
            }
        ),
        headers={"X-Grouper-User": username},
    )
    assert resp.code == 200

    user = User.get(session, name="*****@*****.**")
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 0, "request for existing perm should fail"

    # REQUEST: 'grantable.two', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode(
            {
                "permission_name": "grantable.two",
                "argument": "some argument",
                "reason": "blah blah black sheep",
                "argument_type": "text",
            }
        ),
        headers={"X-Grouper-User": username},
    )
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "only one user (and no group) should receive notification for request"

    perms = _load_permissions_by_group_name(session, "serving-team")
    assert len(perms) == 2
    assert "grantable.two" not in perms, "requested permission shouldn't be granted immediately"

    user = User.get(session, name="*****@*****.**")
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 0, "random user shouldn't have a request"

    user = User.get(session, name="*****@*****.**")
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10, 0)
    assert len(request_tuple.requests) == 1, "user in group with grant should have a request"

    # CANCEL request: have '*****@*****.**' cancel this request
    request_id = request_tuple.requests[0].id
    fe_url = url(base_url, "/permissions/requests/{}".format(request_id))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"status": "cancelled", "reason": "heck no"}),
        headers={"X-Grouper-User": user.name},
    )
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "rejection email should be sent"

    perms = _load_permissions_by_group_name(session, "serving-team")
    assert len(perms) == 2
    assert "grantable.two" not in perms, "no new permissions should be granted for this"
Example #27
0
def standard_graph(session, graph, users, groups, permissions):
    add_member(groups["team-sre"], users["gary"], role="owner")
    add_member(groups["team-sre"], users["zay"])
    add_member(groups["team-sre"], users["zorkian"])
    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")

    add_member(groups["serving-team"], users["zorkian"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"])
    add_member(groups["serving-team"], groups["tech-ops"])
    grant_permission(groups["serving-team"], permissions["audited"])

    add_member(groups["tech-ops"], users["zay"], role="owner")
    add_member(groups["tech-ops"], users["gary"])
    add_member(groups["tech-ops"], users["figurehead"], role="np-owner")
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")

    add_member(groups["security-team"], users["oliver"], role="owner")
    add_member(groups["security-team"], users["figurehead"], role="member")

    add_member(groups["sad-team"], users["zorkian"], role="owner")
    add_member(groups["sad-team"], users["oliver"])

    add_member(groups["audited-team"], users["zorkian"], role="owner")
    grant_permission(groups["audited-team"], permissions["audited"])

    add_member(groups["team-infra"], users["gary"], role="owner")
    add_member(groups["team-infra"], groups["serving-team"])
    add_member(groups["team-infra"], groups["security-team"])
    grant_permission(groups["team-infra"],
                     permissions["sudo"],
                     argument="shell")

    add_member(groups["auditors"], users["zorkian"], role="owner")
    grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR])

    add_member(groups["all-teams"], users["testuser"], role="owner")
    add_member(groups["all-teams"], groups["team-infra"])

    session.commit()
    graph.update_from_db(session)

    return graph
Example #28
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 #29
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 #30
0
def standard_graph(session, graph, users, groups, permissions):
    """Setup a standard graph used for many tests. In graph form:

    +-----------------------+
    |                       |
    |  team-sre             |
    |    * gary (o)         +---------------------------------+
    |    * zay              |                                 |
    |    * zorkian          |                     +-----------v-----------+
    |                       |                     |                       |
    +-----------------------+                     |  serving-team         |
    +-----------------------+           +--------->    * zorkian (o)      |
    |                       |           |         |                       |
    |  tech-ops             |           |         +-----------+-----------+
    |    * zay (o)          |           |                     |
    |    * gary             +-----------+                     |
    |    * figurehead (np)  |                                 |
    |                       |                                 |
    +-----------------------+                                 |
    +-----------------------+                     +-----------v-----------+
    |                       |                     |                       |
    |  security-team        |                     |  team-infra           |
    |    * oliver (o)       +--------------------->    * gary (o)         |
    |    * figurehead       |                     |                       |
    |                       |                     +-----------+-----------+
    +-----------------------+                                 |
    +-----------------------+                                 |
    |                       |                                 |
    |  sad-team             |                                 |
    |    * zorkian (o)      |                                 |
    |    * oliver           |                     +-----------v-----------+
    |                       |                     |                       |
    +-----------------------+                     |  all-teams            |
    +-----------------------+                     |    * testuser (o)     |
    |                       |                     |                       |
    |  audited-team         |                     +-----------------------+
    |    * zorkian (o)      |
    |                       |
    |                       |
    +-----------------------+
    +-----------------------+
    |                       |
    |  auditors             |
    |    * zorkian (o)      |
    |                       |
    +-----------------------+
    +-----------------------+
    |                       |
    |  user-admins          |
    |    * tyleromeara (o)  |
    |                       |
    +-----------------------+

    Arrows denote member of the source in the destination group. (o) for
    owners, (np) for non-permissioned owners.
    """
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["team-sre"], users["*****@*****.**"])
    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")
    grant_permission(groups["team-sre"], permissions["team-sre"], argument="*")

    add_member(groups["serving-team"], users["*****@*****.**"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"])
    add_member(groups["serving-team"], groups["tech-ops"])
    grant_permission(groups["serving-team"], permissions["audited"])

    add_member(groups["tech-ops"], users["*****@*****.**"], role="owner")
    add_member(groups["tech-ops"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"], role="np-owner")
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")

    add_member(groups["security-team"], users["*****@*****.**"], role="owner")
    add_member(groups["security-team"],
               users["*****@*****.**"],
               role="member")

    add_member(groups["sad-team"], users["*****@*****.**"], role="owner")
    add_member(groups["sad-team"], users["*****@*****.**"])

    add_member(groups["audited-team"], users["*****@*****.**"], role="owner")
    grant_permission(groups["audited-team"], permissions["audited"])

    add_member(groups["team-infra"], users["*****@*****.**"], role="owner")
    add_member(groups["team-infra"], groups["serving-team"])
    add_member(groups["team-infra"], groups["security-team"])
    grant_permission(groups["team-infra"],
                     permissions["sudo"],
                     argument="shell")

    add_member(groups["auditors"], users["*****@*****.**"], role="owner")
    grant_permission(groups["auditors"], permissions[AUDIT_MANAGER])
    grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR])

    add_member(groups["all-teams"], users["*****@*****.**"], role="owner")
    add_member(groups["all-teams"], groups["team-infra"])

    add_member(groups["user-admins"], users["*****@*****.**"], role="owner")
    grant_permission(groups["user-admins"], permissions[USER_ADMIN])

    session.commit()
    graph.update_from_db(session)

    return graph
Example #31
0
def test_permission_request_flow(session, standard_graph, groups,
                                 grantable_permissions, http_client, base_url):
    """Test that a permission request gets into the system correctly and
    notifications are sent correctly."""
    perm_grant, _, perm1, perm2 = grantable_permissions
    grant_permission(groups["all-teams"], perm_grant, argument="grantable.*")

    # REQUEST: 'grantable.one', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "permission_name": "grantable.one",
                                       "argument": "some argument",
                                       "reason": "blah blah black sheep",
                                       "argument_type": "text"
                                   }),
                                   headers={'X-Grouper-User': username})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(
        emails
    ) == 1, "only one user (and no group) should receive notification for request"

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 1
    assert "grantable.one" not in perms, "requested permission shouldn't be granted immediately"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10,
                                                 0)
    assert len(
        request_tuple.requests) == 0, "random user shouldn't have a request"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10,
                                                 0)
    assert len(request_tuple.requests
               ) == 1, "user in group with grant should have a request"

    # APPROVE grant: have '*****@*****.**' action this request as owner of
    # 'all-teams' which has the grant permission for the requested permission
    request_id = request_tuple.requests[0].id
    fe_url = url(base_url, "/permissions/requests/{}".format(request_id))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "status": "actioned",
                                       "reason": "lgtm"
                                   }),
                                   headers={'X-Grouper-User': user.name})
    assert resp.code == 200

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 2
    assert "grantable.one" in perms, "requested permission shouldn't be granted immediately"

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "requester should receive email as well"

    # (re)REQUEST: 'grantable.one', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "permission_name": "grantable.one",
                                       "argument": "some argument",
                                       "reason": "blah blah black sheep",
                                       "argument_type": "text"
                                   }),
                                   headers={'X-Grouper-User': username})
    assert resp.code == 200

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10,
                                                 0)
    assert len(
        request_tuple.requests) == 0, "request for existing perm should fail"

    # REQUEST: 'grantable.two', 'some argument' for 'serving-team'
    groupname = "serving-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "permission_name": "grantable.two",
                                       "argument": "some argument",
                                       "reason": "blah blah black sheep",
                                       "argument_type": "text"
                                   }),
                                   headers={'X-Grouper-User': username})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(
        emails
    ) == 1, "only one user (and no group) should receive notification for request"

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 2
    assert "grantable.two" not in perms, "requested permission shouldn't be granted immediately"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10,
                                                 0)
    assert len(
        request_tuple.requests) == 0, "random user shouldn't have a request"

    user = User.get(session, name='*****@*****.**')
    request_tuple, total = get_requests_by_owner(session, user, "pending", 10,
                                                 0)
    assert len(request_tuple.requests
               ) == 1, "user in group with grant should have a request"

    # CANCEL request: have '*****@*****.**' cancel this request
    request_id = request_tuple.requests[0].id
    fe_url = url(base_url, "/permissions/requests/{}".format(request_id))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "status": "cancelled",
                                       "reason": "heck no"
                                   }),
                                   headers={'X-Grouper-User': user.name})
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert len(emails) == 1, "rejection email should be sent"

    perms = _load_permissions_by_group_name(session, 'serving-team')
    assert len(perms) == 2
    assert "grantable.two" not in perms, "no new permissions should be granted for this"
Example #32
0
def test_permission_grant_to_owners(session, standard_graph, groups,
                                    grantable_permissions):
    """Test we're getting correct owners according to granted
    'grouper.permission.grant' permissions."""
    perm_grant, _, perm1, perm2 = grantable_permissions

    assert not get_owners_by_grantable_permission(
        session), 'nothing to begin with'

    # grant a grant on a non-existent permission
    grant_permission(groups["auditors"],
                     perm_grant,
                     argument="notgrantable.one")
    assert not get_owners_by_grantable_permission(
        session), 'ignore grants for non-existent perms'

    # grant a wildcard grant -- make sure all permissions are represented and
    # the grant isn't inherited
    grant_permission(groups["all-teams"], perm_grant, argument="grantable.*")
    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    expected = [groups['all-teams']]
    assert owners_by_arg_by_perm[
        perm1.name]['*'] == expected, 'grants are not inherited'
    assert len(owners_by_arg_by_perm) == 2
    assert len(owners_by_arg_by_perm[perm1.name]) == 1
    assert len(owners_by_arg_by_perm[perm2.name]) == 1

    # grant on argument substring
    grant_permission(groups["team-sre"],
                     perm_grant,
                     argument="{}/somesubstring*".format(perm1.name))
    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    expected = [groups['all-teams']]
    assert owners_by_arg_by_perm[perm1.name]['*'] == expected
    expected = [groups["team-sre"]]
    assert owners_by_arg_by_perm[perm1.name]['somesubstring*'] == expected

    # make sure get_owner() respect substrings
    res = [
        o for o, a in get_owner_arg_list(
            session,
            perm1,
            "somesubstring",
            owners_by_arg_by_perm=owners_by_arg_by_perm)
    ]
    assert sorted(res) == sorted([groups["all-teams"], groups["team-sre"]]), \
            "should include substring wildcard matches"

    res = [
        o for o, a in get_owner_arg_list(
            session,
            perm1,
            "othersubstring",
            owners_by_arg_by_perm=owners_by_arg_by_perm)
    ]
    assert sorted(res) == [groups["all-teams"]
                           ], "negative test of substring wildcard matches"

    # permission admins have all the power
    perm_admin, _ = Permission.get_or_create(session,
                                             name=PERMISSION_ADMIN,
                                             description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    all_permissions = Permission.get_all(session)
    for perm in all_permissions:
        assert perm.name in owners_by_arg_by_perm, 'all permission should be represented'
        assert groups["security-team"] in owners_by_arg_by_perm[perm.name]["*"], \
                'permission admin should be wildcard owners'
Example #33
0
def test_tags(session, http_client, base_url, graph):
    perm = Permission(name=TAG_EDIT, description="Why is this not nullable?")
    perm.add(session)
    session.commit()

    perm2 = Permission(name="it.literally.does.not.matter",
                       description="Why is this not nullable?")
    perm2.add(session)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        session.query(Permission).filter_by(name=TAG_EDIT).scalar(), "*")
    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        session.query(Permission).filter_by(
            name="it.literally.does.not.matter").scalar(), "*")

    tag = PublicKeyTag(name="tyler_was_here")
    tag.add(session)
    session.commit()

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    grant_permission_to_tag(session, tag.id, perm.id, "prod")
    with pytest.raises(AssertionError):
        grant_permission_to_tag(session, tag.id, perm.id, "question?")

    user = session.query(User).filter_by(username="******").scalar()

    add_public_key(session, user, SSH_KEY_1)

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()

    add_tag_to_public_key(session, key, tag)

    user = session.query(User).filter_by(username="******").scalar()

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()
    assert len(get_public_key_permissions(
        session, key)) == 1, "The SSH Key should have only 1 permission"
    assert get_public_key_permissions(
        session,
        key)[0].name == TAG_EDIT, "The SSH key's permission should be TAG_EDIT"
    assert get_public_key_permissions(
        session, key
    )[0].argument == "prod", "The SSH key's permission argument should be restricted to the tag's argument"
    assert len(user_permissions(
        session, user)) > 1, "The user should have more than 1 permission"

    graph.update_from_db(session)

    fe_url = url(base_url, '/users/{}'.format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    pub_key = body['data']['user']['public_keys'][0]
    assert len(pub_key['tags']) == 1, "The public key should only have 1 tag"
    assert pub_key[
        'fingerprint'] == 'e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35'
    assert pub_key[
        'fingerprint_sha256'] == 'MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU'
    assert pub_key['tags'][
        0] == 'tyler_was_here', "The public key should have the tag we gave it"
Example #34
0
def standard_graph(session, graph, users, groups, permissions):
    add_member(groups["team-sre"], users["gary"], role="owner")
    add_member(groups["team-sre"], users["zay"])
    add_member(groups["team-sre"], users["zorkian"])
    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")

    add_member(groups["serving-team"], users["zorkian"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"])
    add_member(groups["serving-team"], groups["tech-ops"])
    grant_permission(groups["serving-team"], permissions["audited"])

    add_member(groups["tech-ops"], users["zay"], role="owner")
    add_member(groups["tech-ops"], users["gary"])
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")

    add_member(groups["security-team"], users["oliver"], role="owner")

    add_member(groups["sad-team"], users["zorkian"], role="owner")
    add_member(groups["sad-team"], users["oliver"])

    add_member(groups["audited-team"], users["zorkian"], role="owner")
    grant_permission(groups["audited-team"], permissions["audited"])

    add_member(groups["team-infra"], users["gary"], role="owner")
    add_member(groups["team-infra"], groups["serving-team"])
    add_member(groups["team-infra"], groups["security-team"])
    grant_permission(groups["team-infra"], permissions["sudo"], argument="shell")

    add_member(groups["auditors"], users["zorkian"], role="owner")
    grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR])

    add_member(groups["all-teams"], users["testuser"], role="owner")
    add_member(groups["all-teams"], groups["team-infra"])

    session.commit()
    graph.update_from_db(session)

    return graph
Example #35
0
def standard_graph(session, graph, users, groups, permissions):
    """Setup a standard graph used for many tests. In graph form:

    +-----------------------+
    |                       |
    |  team-sre             |
    |    * gary (o)         +---------------------------------+
    |    * zay              |                                 |
    |    * zorkian          |                     +-----------v-----------+
    |                       |                     |                       |
    +-----------------------+                     |  serving-team         |
    +-----------------------+           +--------->    * zorkian (o)      |
    |                       |           |         |                       |
    |  tech-ops             |           |         +-----------+-----------+
    |    * zay (o)          |           |                     |
    |    * gary             +-----------+                     |
    |    * figurehead (np)  |                                 |
    |                       |                                 |
    +-----------------------+                                 |
    +-----------------------+                     +-----------v-----------+
    |                       |                     |                       |
    |  security-team        |                     |  team-infra           |
    |    * oliver (o)       +--------------------->    * gary (o)         |
    |    * figurehead       |                     |                       |
    |                       |                     +-----------+-----------+
    +-----------------------+                                 |
    +-----------------------+                                 |
    |                       |                                 |
    |  sad-team             |                                 |
    |    * zorkian (o)      |                                 |
    |    * oliver           |                     +-----------v-----------+
    |                       |                     |                       |
    +-----------------------+                     |  all-teams            |
    +-----------------------+                     |    * testuser (o)     |
    |                       |                     |                       |
    |  audited-team         |                     +-----------------------+
    |    * zorkian (o)      |
    |                       |
    |                       |
    +-----------------------+
    +-----------------------+
    |                       |
    |  auditors             |
    |    * zorkian (o)      |
    |                       |
    +-----------------------+

    Arrows denote member of the source in the destination group. (o) for
    owners, (np) for non-permissioned owners.
    """
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["team-sre"], users["*****@*****.**"])
    grant_permission(groups["team-sre"], permissions["ssh"], argument="*")

    add_member(groups["serving-team"], users["*****@*****.**"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"])
    add_member(groups["serving-team"], groups["tech-ops"])
    grant_permission(groups["serving-team"], permissions["audited"])

    add_member(groups["tech-ops"], users["*****@*****.**"], role="owner")
    add_member(groups["tech-ops"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"], role="np-owner")
    grant_permission(groups["tech-ops"], permissions["ssh"], argument="shell")

    add_member(groups["security-team"], users["*****@*****.**"], role="owner")
    add_member(groups["security-team"], users["*****@*****.**"], role="member")

    add_member(groups["sad-team"], users["*****@*****.**"], role="owner")
    add_member(groups["sad-team"], users["*****@*****.**"])

    add_member(groups["audited-team"], users["*****@*****.**"], role="owner")
    grant_permission(groups["audited-team"], permissions["audited"])

    add_member(groups["team-infra"], users["*****@*****.**"], role="owner")
    add_member(groups["team-infra"], groups["serving-team"])
    add_member(groups["team-infra"], groups["security-team"])
    grant_permission(groups["team-infra"], permissions["sudo"], argument="shell")

    add_member(groups["auditors"], users["*****@*****.**"], role="owner")
    grant_permission(groups["auditors"], permissions[AUDIT_MANAGER])
    grant_permission(groups["auditors"], permissions[PERMISSION_AUDITOR])

    add_member(groups["all-teams"], users["*****@*****.**"], role="owner")
    add_member(groups["all-teams"], groups["team-infra"])

    session.commit()
    graph.update_from_db(session)

    return graph
Example #36
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"