Beispiel #1
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"
def test_group_logdump(make_session, session, users, groups, tmpdir):
    make_session.return_value = session

    groupname = 'team-sre'
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join('out.csv').strpath

    call_main('group', 'log_dump', groupname, yesterday.isoformat(), '--outfile', fn)
    with open(fn, 'r') as fh:
        out = fh.read()

    assert not out, 'nothing yet'

    AuditLog.log(session, users['*****@*****.**'].id, 'make_noise', 'making some noise',
            on_group_id=group_id)
    session.commit()

    call_main('group', 'log_dump', groupname, yesterday.isoformat(), '--outfile', fn)
    with open(fn, 'r') as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, 'should capture our new audit log entry'

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
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"
Beispiel #4
0
def test_graph_desc_to_ances(session, graph, users, groups):  # noqa
    """ Test adding members where all descendants already exist."""

    setup_desc_to_ances(session, users, groups)
    session.commit()
    graph.update_from_db(session)

    assert get_users(graph, "team-sre") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "tech-ops") == set(["*****@*****.**", "*****@*****.**"])

    assert get_users(graph, "team-infra") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "team-infra", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "all-teams") == set(["*****@*****.**", "*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "all-teams", cutoff=1) == set(["*****@*****.**"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "all-teams", "tech-ops",
            "team-infra"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre", "tech-ops", "team-infra"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "all-teams", "tech-ops", "team-infra"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre", "tech-ops"])

    assert get_groups(graph, "*****@*****.**") == set(["all-teams"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["all-teams"])
Beispiel #5
0
def test_group_logdump(make_session, session, users, groups, tmpdir):
    make_session.return_value = session

    groupname = "team-sre"
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join("out.csv").strpath

    call_main("group", "log_dump", groupname, yesterday.isoformat(), "--outfile", fn)
    with open(fn, "r") as fh:
        out = fh.read()

    assert not out, "nothing yet"

    AuditLog.log(session, users["*****@*****.**"].id, "make_noise", "making some noise", on_group_id=group_id)
    session.commit()

    call_main("group", "log_dump", groupname, yesterday.isoformat(), "--outfile", fn)
    with open(fn, "r") as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, "should capture our new audit log entry"

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
def test_basic_request(graph, groups, permissions, session, standard_graph,
                       users):
    group_sre = groups["team-sre"]
    group_not_sre = [g for name, g in groups.items() if name != "team-sre"]

    assert not any([
        get_requests_by_group(session, group, status="pending").all()
        for group in groups.values()
    ]), "no group should start with pending requests"

    group_sre.add_member(users["*****@*****.**"],
                         users["*****@*****.**"],
                         reason="for the lulz")
    session.commit()

    request_not_sre = [
        get_requests_by_group(session, group, status="pending").all()
        for group in group_not_sre
    ]
    assert not any(
        request_not_sre), "only affected group should show pending requests"
    request_sre = get_requests_by_group(session, group_sre,
                                        status="pending").all()
    assert len(request_sre) == 1, "affected group should have request"

    request = session.query(Request).filter_by(id=request_sre[0].id).scalar()
    request.update_status(users["*****@*****.**"], "actioned",
                          "for being a good person")
    session.commit()

    assert not any([
        get_requests_by_group(session, group, status="pending").all()
        for group in groups.values()
    ]), "no group should have requests after being actioned"
Beispiel #7
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)
Beispiel #8
0
def test_graph_desc_to_ances(session, graph, users, groups):  # noqa
    """ Test adding members where all descendants already exist."""

    setup_desc_to_ances(session, users, groups)
    session.commit()
    graph.update_from_db(session)

    assert get_users(graph, "team-sre") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "tech-ops") == set(["*****@*****.**", "*****@*****.**"])

    assert get_users(graph, "team-infra") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "team-infra", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "all-teams") == set(
        ["*****@*****.**", "*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "all-teams", cutoff=1) == set(["*****@*****.**"])

    assert get_groups(graph, "*****@*****.**") == set(
        ["team-sre", "all-teams", "tech-ops", "team-infra"])
    assert get_groups(graph, "*****@*****.**",
                      cutoff=1) == set(["team-sre", "tech-ops", "team-infra"])

    assert get_groups(graph, "*****@*****.**") == set(
        ["team-sre", "all-teams", "tech-ops", "team-infra"])
    assert get_groups(graph, "*****@*****.**",
                      cutoff=1) == set(["team-sre", "tech-ops"])

    assert get_groups(graph, "*****@*****.**") == set(["all-teams"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["all-teams"])
Beispiel #9
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)
def test_request_emails_reference(session, groups, permissions, users,
                                  base_url, http_client):
    tech = groups["tech-ops"]

    tech.canjoin = "canask"
    tech.add(session)
    session.commit()

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    fe_url = url(base_url, '/groups/{}/join'.format(tech.groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "reason":
                                       "Test Request Please Ignore",
                                       "member":
                                       "User: {}".format(user.name)
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    zay_emails = _get_unsent_and_mark_as_sent_emails_with_username(
        session, "*****@*****.**")
    assert any(["References: " in email.body for email in zay_emails])
def test_group_logdump(make_session, session, users, groups, tmpdir):
    make_session.return_value = session

    groupname = 'team-sre'
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join('out.csv').strpath

    call_main('group', 'log_dump', groupname, yesterday.isoformat(),
              '--outfile', fn)
    with open(fn, 'r') as fh:
        out = fh.read()

    assert not out, 'nothing yet'

    AuditLog.log(session,
                 users['*****@*****.**'].id,
                 'make_noise',
                 'making some noise',
                 on_group_id=group_id)
    session.commit()

    call_main('group', 'log_dump', groupname, yesterday.isoformat(),
              '--outfile', fn)
    with open(fn, 'r') as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, 'should capture our new audit log entry'

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
Beispiel #12
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)
Beispiel #13
0
def grantable_permissions(session, standard_graph):
    perm_grant, _ = Permission.get_or_create(session, name=PERMISSION_GRANT, description="")
    perm0, _ = Permission.get_or_create(session, name="grantable", description="")
    perm1, _ = Permission.get_or_create(session, name="grantable.one", description="")
    perm2, _ = Permission.get_or_create(session, name="grantable.two", description="")
    session.commit()

    return perm_grant, perm0, perm1, perm2
Beispiel #14
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"
Beispiel #15
0
def _get_unsent_and_mark_as_sent_emails(session):
    """Helper to count unsent emails and then mark them as sent."""
    emails = session.query(AsyncNotification).filter(AsyncNotification.sent == False).all()

    for email in emails:
        email.sent = True

    session.commit()
    return emails
Beispiel #16
0
def _get_unsent_and_mark_as_sent_emails_with_username(session, username):
    """Helper to count unsent emails and then mark them as sent."""
    emails = session.query(AsyncNotification).filter_by(sent=False, email=username).all()

    for email in emails:
        email.sent = True

    session.commit()
    return emails
Beispiel #17
0
def _get_unsent_and_mark_as_sent_emails_with_username(session, username):
    """Helper to count unsent emails and then mark them as sent."""
    emails = session.query(AsyncNotification).filter_by(sent=False, email=username).all()

    for email in emails:
        email.sent = True

    session.commit()
    return emails
Beispiel #18
0
def _get_unsent_emails_and_send(session):
    """Helper to count unsent emails and then mark them as sent."""
    emails = session.query(AsyncNotification).filter_by(sent=False).all()

    for email in emails:
        email.sent = True

    session.commit()
    return emails
Beispiel #19
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"
Beispiel #20
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"
Beispiel #21
0
def test_merge(session, initial_items, items_to_merge):
    items = {
        1: {'id': 1, 'change': '1', 'a': 'a', 'b': 'b'},
    }
    session.execute(insert(Foo, initial_items.values()))
    session.execute(Merge(Foo, items.values()))
    session.commit()
    foos = {
        foo.id: foo._asdict()
        for foo in session.query(Foo.id, Foo.change, Foo.a, Foo.b).all()
    }
    assert dict(initial_items, **items) == foos
Beispiel #22
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
Beispiel #23
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"
Beispiel #24
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
Beispiel #25
0
def test_aggregate_request(graph, groups, permissions, session, standard_graph, users):
    gary = users["*****@*****.**"]
    testuser = users["*****@*****.**"]
    not_involved = [user for name,user in users.items() if name not in ("*****@*****.**",
            "*****@*****.**")]

    assert not any([user_requests_aggregate(session, u).all() for u in users.values()]), \
            "should have no pending requests to begin with"

    # one request to one team
    groups["team-sre"].add_member(users["*****@*****.**"], users["*****@*****.**"],
            reason="for the lulz")
    session.commit()

    assert len(user_requests_aggregate(session, gary).all()) == 1, "one pending request for owner"
    assert not any([user_requests_aggregate(session, u).all() for u in not_involved]), \
            "no pending requests if you're not the owner"

    # two request to two teams, same owner
    groups["team-infra"].add_member(users["*****@*****.**"], users["*****@*****.**"],
            reason="for the lulz")
    session.commit()

    request_gary = user_requests_aggregate(session, gary).all()
    assert len(request_gary) == 2, "two pending request for owner"
    assert not any([user_requests_aggregate(session, u).all() for u in not_involved]), \
            "no pending requests if you're not the owner"

    # resolving one request should reflect
    request = session.query(Request).filter_by(id=request_gary[0].id).scalar()
    request.update_status(users["*****@*****.**"], "actioned", "for being a good person")
    session.commit()

    assert len(user_requests_aggregate(session, gary).all()) == 1, "one pending request for owner"
    assert not any([user_requests_aggregate(session, u).all() for u in not_involved]), \
            "no pending requests if you're not the owner"

    # requests to dependent teams should reflect apprpriately
    groups["security-team"].add_member(users["*****@*****.**"], users["*****@*****.**"],
            reason="for the lulz")
    session.commit()

    assert len(user_requests_aggregate(session, gary).all()) == 1, "super owner should not get request"
    assert len(user_requests_aggregate(session, users["*****@*****.**"]).all()) == 1, "owner should get request"
    user_not_gary_oliver = [u for n,u in users.items() if n not in ("*****@*****.**","*****@*****.**")]
    assert not any([user_requests_aggregate(session, u).all() for u in user_not_gary_oliver])

    # manager and np-owner should get requests
    figurehead = users["*****@*****.**"]
    add_member(groups["audited-team"], figurehead, role="manager")
    assert len(user_requests_aggregate(session, figurehead).all()) == 0, "no request for np-owner at first"

    groups["tech-ops"].add_member(users["*****@*****.**"], users["*****@*****.**"],
            reason="for the lulz")
    assert len(user_requests_aggregate(session, figurehead).all()) == 1, "request for np-owner"

    groups["audited-team"].add_member(users["*****@*****.**"], users["*****@*****.**"],
            reason="for the lulz")
    assert len(user_requests_aggregate(session, figurehead).all()) == 2, "request for np-owner and manager"
Beispiel #26
0
def grantable_permissions(session, standard_graph):
    perm_grant, _ = Permission.get_or_create(session,
                                             name=PERMISSION_GRANT,
                                             description="")
    perm0, _ = Permission.get_or_create(session,
                                        name="grantable",
                                        description="")
    perm1, _ = Permission.get_or_create(session,
                                        name="grantable.one",
                                        description="")
    perm2, _ = Permission.get_or_create(session,
                                        name="grantable.two",
                                        description="")
    session.commit()

    return perm_grant, perm0, perm1, perm2
Beispiel #27
0
def test_graph_cycle_indirect(session, graph, users, groups):  # noqa
    """ Test adding a member that will create a cycle.

        gary         zay            testuser
         |            |                |
        sre <----- tech-ops <----- team-infra <--
         |                                       |
         |                                       |
          --------> all-teams --------------------

    """

    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"])
    add_member(groups["team-infra"], users["*****@*****.**"])

    add_member(groups["team-sre"], groups["tech-ops"])
    add_member(groups["tech-ops"], groups["team-infra"])
    add_member(groups["team-infra"], groups["all-teams"])

    add_member(groups["all-teams"], groups["team-sre"])

    session.commit()
    graph.update_from_db(session)
    all_users = set(["*****@*****.**", "*****@*****.**", "*****@*****.**"])
    all_groups = set(["team-sre", "all-teams", "tech-ops", "team-infra"])

    assert get_users(graph, "team-sre") == all_users
    assert get_users(graph, "team-sre", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "tech-ops") == all_users
    assert get_users(graph, "tech-ops", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "team-infra") == all_users
    assert get_users(graph, "team-infra", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "all-teams") == all_users
    assert get_users(graph, "all-teams", cutoff=1) == set([])

    assert get_groups(graph, "*****@*****.**") == all_groups
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre"])

    assert get_groups(graph, "*****@*****.**") == all_groups
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["tech-ops"])

    assert get_groups(graph, "*****@*****.**") == all_groups
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-infra"])
Beispiel #28
0
def test_graph_cycle_indirect(session, graph, users, groups):  # noqa
    """ Test adding a member that will create a cycle.

        gary         zay            testuser
         |            |                |
        sre <----- tech-ops <----- team-infra <--
         |                                       |
         |                                       |
          --------> all-teams --------------------

    """

    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"])
    add_member(groups["team-infra"], users["*****@*****.**"])

    add_member(groups["team-sre"], groups["tech-ops"])
    add_member(groups["tech-ops"], groups["team-infra"])
    add_member(groups["team-infra"], groups["all-teams"])

    add_member(groups["all-teams"], groups["team-sre"])

    session.commit()
    graph.update_from_db(session)
    all_users = set(["*****@*****.**", "*****@*****.**", "*****@*****.**"])
    all_groups = set(["team-sre", "all-teams", "tech-ops", "team-infra"])

    assert get_users(graph, "team-sre") == all_users
    assert get_users(graph, "team-sre", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "tech-ops") == all_users
    assert get_users(graph, "tech-ops", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "team-infra") == all_users
    assert get_users(graph, "team-infra", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "all-teams") == all_users
    assert get_users(graph, "all-teams", cutoff=1) == set([])

    assert get_groups(graph, "*****@*****.**") == all_groups
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre"])

    assert get_groups(graph, "*****@*****.**") == all_groups
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["tech-ops"])

    assert get_groups(graph, "*****@*****.**") == all_groups
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-infra"])
Beispiel #29
0
def expired_graph(session, graph, groups, users):
    now = datetime.utcnow()

    # expired user membership
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"], expiration=now)

    # expired group membership
    add_member(groups["serving-team"], users["*****@*****.**"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"], expiration=now)

    # expired user membership in disabled group
    add_member(groups["sad-team"], users["*****@*****.**"], expiration=now)
    groups["sad-team"].disable()
    session.commit()

    return graph
Beispiel #30
0
def test_merge(session, initial_items, items_to_merge):
    items = {
        1: {
            'id': 1,
            'change': '1',
            'a': 'a',
            'b': 'b'
        },
    }
    session.execute(insert(Foo, initial_items.values()))
    session.execute(Merge(Foo, items.values()))
    session.commit()
    foos = {
        foo.id: foo._asdict()
        for foo in session.query(Foo.id, Foo.change, Foo.a, Foo.b).all()
    }
    assert dict(initial_items, **items) == foos
Beispiel #31
0
def test_cant_revoke_last_npowner(get_plugin_proxy, session, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    group = groups["team-infra"]
    first_owner = users["*****@*****.**"]
    second_owner = users["*****@*****.**"]

    add_member(group, first_owner, role="np-owner")
    add_member(group, second_owner, role="np-owner")

    # Revoking the first owner does not raise an exception
    revoke_member(group, first_owner)

    session.commit()

    with pytest.raises(PluginRejectedGroupMembershipUpdate):
        revoke_member(group, second_owner)
Beispiel #32
0
def expired_graph(session, graph, groups, users):
    now = datetime.utcnow()

    # expired user membership
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"], expiration=now)

    # expired group membership
    add_member(groups["serving-team"], users["*****@*****.**"], role="owner")
    add_member(groups["serving-team"], groups["team-sre"], expiration=now)

    # expired user membership in disabled group
    add_member(groups["sad-team"], users["*****@*****.**"], expiration=now)
    groups["sad-team"].disable()
    session.commit()

    return graph
Beispiel #33
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
Beispiel #34
0
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]
    )
Beispiel #35
0
def test_graph_add_member_existing(session, graph, users, groups):  # noqa
    """ Test adding members to an existing relationship."""

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

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

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

    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"])

    session.commit()
    graph.update_from_db(session)

    assert get_users(graph, "team-sre") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "tech-ops") == set(["*****@*****.**", "*****@*****.**"])

    assert get_users(graph, "team-infra") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "team-infra", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "all-teams") == set(
        ["*****@*****.**", "*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "all-teams", cutoff=1) == set(["*****@*****.**"])

    assert get_groups(graph, "*****@*****.**") == set(
        ["team-sre", "all-teams", "tech-ops", "team-infra"])
    assert get_groups(graph, "*****@*****.**",
                      cutoff=1) == set(["team-sre", "tech-ops", "team-infra"])

    assert get_groups(graph, "*****@*****.**") == set(
        ["team-sre", "all-teams", "tech-ops", "team-infra"])
    assert get_groups(graph, "*****@*****.**",
                      cutoff=1) == set(["team-sre", "tech-ops"])

    assert get_groups(graph, "*****@*****.**") == set(["all-teams"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["all-teams"])
Beispiel #36
0
def test_basic_request(graph, groups, permissions, session, standard_graph, users):
    group_sre = groups["team-sre"]
    group_not_sre = [g for name,g in groups.items() if name != "team-sre"]

    assert not any([group.my_requests(status="pending").all() for group in groups.values()]), \
            "no group should start with pending requests"

    group_sre.add_member(users["*****@*****.**"], users["*****@*****.**"], reason="for the lulz")
    session.commit()

    request_not_sre = [group.my_requests(status="pending").all() for group in group_not_sre]
    assert not any(request_not_sre), "only affected group should show pending requests"
    request_sre = group_sre.my_requests(status="pending").all()
    assert len(request_sre) == 1, "affected group should have request"

    request = session.query(Request).filter_by(id=request_sre[0].id).scalar()
    request.update_status(users["*****@*****.**"], "actioned", "for being a good person")
    session.commit()

    assert not any([group.my_requests(status="pending").all() for group in groups.values()]), \
            "no group should have requests after being actioned"
Beispiel #37
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
Beispiel #38
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"
Beispiel #39
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"
Beispiel #40
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"
Beispiel #41
0
def test_graph_cycle_direct(session, graph, users, groups):  # noqa
    """ Test adding members where all descendants already exist."""

    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"])

    add_member(groups["team-sre"], groups["tech-ops"])
    add_member(groups["tech-ops"], groups["team-sre"])

    session.commit()
    graph.update_from_db(session)
    assert get_users(graph, "team-sre") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "team-sre", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "tech-ops") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "tech-ops", cutoff=1) == set(["*****@*****.**"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "tech-ops"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "tech-ops"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["tech-ops"])
Beispiel #42
0
def test_graph_cycle_direct(session, graph, users, groups):  # noqa
    """ Test adding members where all descendants already exist."""

    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"])

    add_member(groups["team-sre"], groups["tech-ops"])
    add_member(groups["tech-ops"], groups["team-sre"])

    session.commit()
    graph.update_from_db(session)
    assert get_users(graph, "team-sre") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "team-sre", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "tech-ops") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "tech-ops", cutoff=1) == set(["*****@*****.**"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "tech-ops"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "tech-ops"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["tech-ops"])
def test_cant_revoke_last_owner(get_plugins, session, groups, users):
    get_plugins.return_value = [GroupOwnershipPolicyPlugin()]

    group = groups["team-infra"]
    first_owner = users["*****@*****.**"]
    second_owner = users["*****@*****.**"]

    add_member(group, first_owner, role="owner")
    add_member(group, second_owner, role="owner")

    assert len(group.my_owners()) == 2

    # Revoking the first owner does not raise an exception
    revoke_member(group, first_owner)

    session.commit()
    assert len(group.my_owners()) == 1

    with pytest.raises(PluginRejectedGroupMembershipUpdate):
        revoke_member(group, second_owner)

    assert len(group.my_owners()) == 1
Beispiel #44
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")) == []
Beispiel #45
0
def test_graph_add_member_existing(session, graph, users, groups):  # noqa
    """ Test adding members to an existing relationship."""

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

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

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

    add_member(groups["team-sre"], users["*****@*****.**"])
    add_member(groups["tech-ops"], users["*****@*****.**"])

    session.commit()
    graph.update_from_db(session)

    assert get_users(graph, "team-sre") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "tech-ops") == set(["*****@*****.**", "*****@*****.**"])

    assert get_users(graph, "team-infra") == set(["*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "team-infra", cutoff=1) == set(["*****@*****.**"])

    assert get_users(graph, "all-teams") == set(["*****@*****.**", "*****@*****.**", "*****@*****.**"])
    assert get_users(graph, "all-teams", cutoff=1) == set(["*****@*****.**"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "all-teams", "tech-ops",
            "team-infra"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre", "tech-ops", "team-infra"])

    assert get_groups(graph, "*****@*****.**") == set(["team-sre", "all-teams", "tech-ops", "team-infra"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["team-sre", "tech-ops"])

    assert get_groups(graph, "*****@*****.**") == set(["all-teams"])
    assert get_groups(graph, "*****@*****.**", cutoff=1) == set(["all-teams"])
Beispiel #46
0
 def run(self, session, **kwargs):
     if kwargs.get('group'):
         Group.get_or_create(session, groupname=groupname)
         session.commit()
     elif kwargs.get('key') == 'valuewith=':
         User.get_or_create(session, username=other_username)
         session.commit()
     else:
         User.get_or_create(session, username=username)
         session.commit()
Beispiel #47
0
 def run(self, session, **kwargs):
     if kwargs.get('group'):
         Group.get_or_create(session, groupname=groupname)
         session.commit()
     elif kwargs.get('key') == 'valuewith=':
         User.get_or_create(session, username=other_username)
         session.commit()
     else:
         User.get_or_create(session, username=username)
         session.commit()
Beispiel #48
0
def test_aggregate_request(graph, groups, permissions, session, standard_graph, users):
    gary = users["gary"]
    testuser = users["testuser"]
    not_involved = [user for name,user in users.items() if name not in ("gary","testuser")]

    print "users! {}".format(users.values())
    assert not any([u.my_requests_aggregate().all() for u in users.values()]), \
            "should have no pending requests to begin with"

    # one request to one team
    groups["team-sre"].add_member(users["testuser"], users["testuser"], reason="for the lulz")
    session.commit()

    assert len(gary.my_requests_aggregate().all()) == 1, "one pending request for owner"
    assert not any([u.my_requests_aggregate().all() for u in not_involved]), \
            "no pending requests if you're not the owner"

    # two request to two teams, same owner
    groups["team-infra"].add_member(users["testuser"], users["testuser"], reason="for the lulz")
    session.commit()

    request_gary = gary.my_requests_aggregate().all()
    assert len(request_gary) == 2, "two pending request for owner"
    assert not any([u.my_requests_aggregate().all() for u in not_involved]), \
            "no pending requests if you're not the owner"

    # resolving one request should reflect
    request = session.query(Request).filter_by(id=request_gary[0].id).scalar()
    request.update_status(users["gary"], "actioned", "for being a good person")
    session.commit()

    assert len(gary.my_requests_aggregate().all()) == 1, "one pending request for owner"
    assert not any([u.my_requests_aggregate().all() for u in not_involved]), \
            "no pending requests if you're not the owner"

    # requests to dependent teams should reflect apprpriately
    groups["security-team"].add_member(users["testuser"], users["testuser"], reason="for the lulz")
    session.commit()

    assert len(gary.my_requests_aggregate().all()) == 1, "super owner should not get request"
    assert len(users["oliver"].my_requests_aggregate().all()) == 1, "owner should get request"
    user_not_gary_oliver = [u for n,u in users.items() if n not in ("gary","oliver")]
    assert not any([u.my_requests_aggregate().all() for u in user_not_gary_oliver])
Beispiel #49
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"
Beispiel #50
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"
Beispiel #51
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_request_autoexpiration(graph, groups, permissions, session,
                                standard_graph, users, base_url, http_client):
    tech = groups["tech-ops"]
    sre = groups["team-sre"]
    security = groups["security-team"]
    sad = groups["sad-team"]
    infra = groups["team-infra"]

    tech.canjoin = "canask"
    tech.auto_expire = timedelta(days=5)
    tech.add(session)
    session.commit()

    sre.canjoin = "canjoin"
    sre.auto_expire = timedelta(days=500)
    sre.add(session)
    session.commit()

    security.canjoin = "canjoin"
    security.add(session)
    session.commit()

    sad.canjoin = "canjoin"
    sad.add(session)
    session.commit()

    infra.canjoin = "canjoin"
    infra.add(session)
    session.commit()

    # REQUEST 1

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    tech = session.query(Group).filter_by(groupname="tech-ops").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

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request = session.query(Request).filter_by(requesting_id=tech.id,
                                               requester_id=user.id).scalar()
    assert datetime.strptime(request.changes['expiration'], "%m/%d/%Y").date(
    ) == (
        datetime.utcnow().date() + tech.auto_expire
    ), "Request expirations should be the current date + group.auto_expire for canask groups"

    # REQUEST 2

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    sre = session.query(Group).filter_by(groupname="team-sre").scalar()
    fe_url = url(base_url, '/groups/{}/join'.format(sre.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

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request = session.query(Request).filter_by(requesting_id=sre.id,
                                               requester_id=user.id).scalar()
    assert datetime.strptime(request.changes['expiration'], "%m/%d/%Y").date(
    ) == (
        datetime.utcnow().date() + sre.auto_expire
    ), "Request expirations should be the current date + group.auto_expire for canjoin groups"

    # REQUEST 3

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    security = session.query(Group).filter_by(
        groupname="security-team").scalar()
    fe_url = url(base_url, '/groups/{}/join'.format(security.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

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request = session.query(Request).filter_by(requesting_id=security.id,
                                               requester_id=user.id).scalar()
    assert "expiration" not in request.changes, "The request should not have an expiration if none is provided and there is no auto_expiration"

    # REQUEST 4

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    sad = session.query(Group).filter_by(groupname="sad-team").scalar()
    fe_url = url(base_url, '/groups/{}/join'.format(sad.groupname))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "reason":
                                       "Test Request Please Ignore",
                                       "member":
                                       "User: {}".format(user.name),
                                       "expiration":
                                       "01/19/2038"
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request = session.query(Request).filter_by(requesting_id=sad.id,
                                               requester_id=user.id).scalar()
    assert datetime.strptime(request.changes['expiration'], "%m/%d/%Y").date(
    ) == date(
        year=2038, month=1, day=19
    ), "User provided expiration times should not be overwritten by the auto_expiration"

    # REQUEST 5

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    infra = session.query(Group).filter_by(groupname="team-infra").scalar()
    fe_url = url(base_url, '/groups/{}/add'.format(infra.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': "******"})
    assert resp.code == 200

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request = session.query(Request).filter_by(requesting_id=infra.id,
                                               requester_id=user.id).scalar()
    assert "expiration" not in request.changes, "The request should not have an expiration if none is provided and the request was created by adding a member"

    # REQUEST 6

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    sre = session.query(Group).filter_by(groupname="team-sre").scalar()
    fe_url = url(base_url,
                 '/groups/{}/edit/user/{}'.format(sre.groupname, user.name))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "reason":
                                       "Test Request Please Ignore",
                                       "member":
                                       "User: {}".format(user.name),
                                       "role":
                                       "member",
                                       "expiration":
                                       ""
                                   }),
                                   headers={'X-Grouper-User': "******"})
    assert resp.code == 200

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    group_edge = session.query(GroupEdge).filter_by(
        group_id=sre.id, member_pk=user.id).scalar()
    assert group_edge.expiration is None, "The request should not have an expiration if none is provided and the user was edited by an approver"
def test_request_emails(graph, groups, permissions, session, standard_graph,
                        users, base_url, http_client):
    tech = groups["tech-ops"]

    tech.canjoin = "canask"
    tech.add(session)
    session.commit()

    # REQUEST 1

    before_reqs = session.query(Request).count()

    # 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

    zaya_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(session, "*****@*****.**"))
    fh_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(
            session, "*****@*****.**"))

    assert zaya_emails + fh_emails == 2, "Only approvers for the requested group should receive an email"
    assert zaya_emails == 1, "Owners should receive exactly one email per canask request"
    assert fh_emails == 1, "NP-Owners should receive exactly one email per canask request"

    assert session.query(Request).count(
    ) == before_reqs + 1, "There should only be one added request"

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request_id = session.query(Request).filter_by(
        requesting_id=tech.id, requester_id=user.id).scalar().id
    fe_url = url(base_url,
                 '/groups/{}/requests/{}'.format(tech.groupname, request_id))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       "reason": "Test Response Please Ignore",
                                       "status": "actioned"
                                   }),
                                   headers={'X-Grouper-User': "******"})
    assert resp.code == 200

    fh_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(
            session, "*****@*****.**"))
    testuser_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(
            session, "*****@*****.**"))

    assert fh_emails + testuser_emails == 2, "Only the approver that didn't action the request and the reqester should get an email"
    assert fh_emails == 1, "NP-owners that did not action the request should receive an email"
    assert testuser_emails == 1, "The requester should receive an email when the request is handled"

    # REQUEST 2

    before_reqs = session.query(Request).count()

    # 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 2",
                                       "member":
                                       "User: {}".format(user.name)
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    zaya_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(session, "*****@*****.**"))
    fh_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(
            session, "*****@*****.**"))

    assert zaya_emails + fh_emails == 2, "Only approvers for the requested group should receive an email"
    assert zaya_emails == 1, "Owners should receive exactly one email per canask request"
    assert fh_emails == 1, "NP-Owners should receive exactly one email per canask request"

    assert session.query(Request).count(
    ) == before_reqs + 1, "There should only be one added request"

    # Explicitly requery because pulling from the users dict causes DetachedSessionErrors
    user = session.query(User).filter_by(username="******").scalar()
    request_id = session.query(Request).filter_by(
        requesting_id=tech.id, requester_id=user.id).scalar().id
    fe_url = url(base_url,
                 '/groups/{}/requests/{}'.format(tech.groupname, request_id))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({
            "reason": "Test Response Please Ignore 2",
            "status": "actioned"
        }),
        headers={'X-Grouper-User': "******"})
    assert resp.code == 200

    zaya_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(session, "*****@*****.**"))
    oliver_emails = len(
        _get_unsent_and_mark_as_sent_emails_with_username(
            session, "*****@*****.**"))

    assert zaya_emails + oliver_emails == 2, "Only the approver that didn't action the request and the reqester should get an email"
    assert zaya_emails == 1, "NP-owners that did not action the request should receive an email"
    assert oliver_emails == 1, "The requester should receive an email when the request is handled"
Beispiel #54
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"
Beispiel #55
0
def test_usertokens(users, session, http_client, base_url):
    user = users["*****@*****.**"]
    tok, secret = add_new_user_token(session, UserToken(user=user, name="Foo"))
    session.commit()

    api_url = url(base_url, '/token/validate')

    # Completely bogus input
    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': 'invalid'}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "error"
    assert len(body["errors"]) == 1
    assert body["errors"][0]["code"] == 1

    valid_token = str(tok) + ":" + secret

    # Valid token
    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': valid_token}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "ok"
    assert body["data"]["identity"] == str(tok)
    assert body["data"]["owner"] == user.username
    assert body["data"]["act_as_owner"]
    assert body["data"]["valid"]

    # Token with the last character changed to something invalid
    bad_char = "1" if secret[-1].isalpha() else "a"
    token_with_bad_secret = str(tok) + ":" + secret[:-1] + bad_char

    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': token_with_bad_secret}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "error"
    assert len(body["errors"]) == 1
    assert body["errors"][0]["code"] == 4

    # Token with the token name frobbed to be something invalid
    token_with_bad_name = str(tok) + "z:" + secret

    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': token_with_bad_name}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "error"
    assert len(body["errors"]) == 1
    assert body["errors"][0]["code"] == 2

    # Token with the user frobbed to be something invalid
    token_with_bad_user = "******" + str(tok) + ":" + secret

    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': token_with_bad_user}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "error"
    assert len(body["errors"]) == 1
    assert body["errors"][0]["code"] == 2

    # Token with the user changed to another valid, but wrong user
    token_with_wrong_user = "******" + tok.name + ":" + secret

    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': token_with_wrong_user}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "error"
    assert len(body["errors"]) == 1
    assert body["errors"][0]["code"] == 2

    # Disabled, but otherwise valid token
    disable_user_token(session, tok)
    session.commit()

    resp = yield http_client.fetch(api_url, method="POST", body=urlencode({'token': valid_token}))
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "error"
    assert len(body["errors"]) == 1
    assert body["errors"][0]["code"] == 3
Beispiel #56
0
def test_expire_nonauditors(standard_graph, users, groups, session, permissions):
    """ Test expiration auditing and notification. """

    graph = standard_graph  # noqa

    # Test audit autoexpiration for all approvers

    approver_roles = ["owner", "np-owner", "manager"]

    for role in approver_roles:

        # Add non-auditor as an owner to an audited group
        add_member(groups["audited-team"], users["*****@*****.**"], role=role)
        session.commit()
        graph.update_from_db(session)

        group_md = graph.get_group_details("audited-team")

        assert group_md.get('audited', False)

        # Expire the edges.
        background = BackgroundThread(settings, None)
        background.expire_nonauditors(session)

        # Check that the edges are now marked as inactive.
        edge = session.query(GroupEdge).filter_by(group_id=groups["audited-team"].id, member_pk=users["*****@*****.**"].id).scalar()
        assert edge.expiration is not None
        assert edge.expiration < datetime.utcnow() + timedelta(days=settings.nonauditor_expiration_days)
        assert edge.expiration > datetime.utcnow() + timedelta(days=settings.nonauditor_expiration_days - 1)

        assert any(["Subject: Membership in audited-team set to expire" in email.body and "To: [email protected]" in email.body for email in _get_unsent_emails_and_send(session)])

        audits = AuditLog.get_entries(session, action="nonauditor_flagged")
        assert len(audits) == 3 + 1 * (approver_roles.index(role) + 1)

        revoke_member(groups["audited-team"], users["*****@*****.**"])

    # Ensure nonauditor, nonapprovers in audited groups do not get set to expired

    member_roles = ["member"]

    for role in member_roles:

        # Add non-auditor as an owner to an audited group
        add_member(groups["audited-team"], users["*****@*****.**"], role=role)
        session.commit()
        graph.update_from_db(session)

        group_md = graph.get_group_details("audited-team")

        assert group_md.get('audited', False)

        # Expire the edges.
        background = BackgroundThread(settings, None)
        background.expire_nonauditors(session)

        # Check that the edges are now marked as inactive.
        edge = session.query(GroupEdge).filter_by(group_id=groups["audited-team"].id, member_pk=users["*****@*****.**"].id).scalar()
        assert edge.expiration is None

        assert not any(["Subject: Membership in audited-team set to expire" in email.body and "To: [email protected]" in email.body for email in _get_unsent_emails_and_send(session)])

        audits = AuditLog.get_entries(session, action="nonauditor_flagged")
        assert len(audits) == 3 + 1 * len(approver_roles)

        revoke_member(groups["audited-team"], users["*****@*****.**"])