예제 #1
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)
예제 #2
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"
예제 #3
0
def test_can_add_owner_twice(get_plugin_proxy, session, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

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

    add_member(group, owner, role="owner")
    add_member(group, owner, role="owner")
예제 #4
0
def test_can_disable_member(get_plugin_proxy, session, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

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

    add_member(group, member)
    disable_user(session, member)
예제 #5
0
def test_cant_disable_last_owner(get_plugin_proxy, session, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

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

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

    with pytest.raises(PluginRejectedDisablingUser):
        disable_user(session, owner)
예제 #6
0
def test_cant_demote_last_owner(get_plugin_proxy, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

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

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

    with pytest.raises(PluginRejectedGroupMembershipUpdate):
        group.edit_member(owner, owner, "Unit Testing", role="member")
예제 #7
0
def test_cant_expire_last_owner(get_plugin_proxy, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

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

    expiration = datetime.utcnow() + timedelta(1)

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

    with pytest.raises(PluginRejectedGroupMembershipUpdate):
        group.edit_member(owner, owner, "Unit Testing", expiration=expiration)
예제 #8
0
def test_can_always_revoke_members(get_plugin_proxy, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    group = groups["team-infra"]
    owner = users["*****@*****.**"]
    member = users["*****@*****.**"]

    expiration = datetime.utcnow() + timedelta(1)

    add_member(group, owner, role="owner", expiration=expiration)
    add_member(group, member)

    revoke_member(group, member)
예제 #9
0
def test_cant_revoke_last_permanent_owner(get_plugin_proxy, groups, users):
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

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

    expiration = datetime.utcnow() + timedelta(1)

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

    with pytest.raises(PluginRejectedGroupMembershipUpdate):
        revoke_member(group, second_owner)
예제 #10
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
예제 #11
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
예제 #12
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)
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
예제 #14
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"])
예제 #15
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"])
예제 #16
0
def test_expiration_notifications(expiring_graph, session, users, groups, permissions):  # noqa
    now = datetime.utcnow()
    note_exp_now = now + timedelta(settings.expiration_notice_days)
    day = timedelta(1)
    week = timedelta(7)

    # What expirations are coming up in the next day?  Next week?
    upcoming_expirations = _get_unsent_expirations(session, now+day)
    assert upcoming_expirations == []

    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Make someone expire a week from now.
    edit_member(groups["team-sre"], users["*****@*****.**"], expiration=note_exp_now+week)
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Now cancel that expiration.
    edit_member(groups["team-sre"], users["*****@*****.**"], expiration=None)
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Make an ordinary member an owner.
    edit_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Make an owner an ordinary member.
    edit_member(groups["team-sre"], users["*****@*****.**"], role="member")
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Send notices about expirations coming up in the next day, next week.
    notices_sent = process_async_emails(settings, session, now+day, dry_run=True)
    assert notices_sent == 0

    notices_sent = process_async_emails(settings, session, now+week, dry_run=True)
    assert notices_sent == 3
    # ("serving-team", "team-sre", "*****@*****.**")
    # ("serving-team", "team-sre", "*****@*****.**")
    # ("team-sre", "*****@*****.**", "*****@*****.**")

    # Notices in the upcoming week have already been sent, but there's another
    # two weeks from now.
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert upcoming_expirations == []

    upcoming_expirations = _get_unsent_expirations(session, now+2*week)
    assert upcoming_expirations == [
        ("tech-ops", "*****@*****.**", "*****@*****.**"),
    ]

    # We already sent these notices.
    notices_sent = process_async_emails(settings, session, now+week, dry_run=True)
    assert notices_sent == 0

    # Extend gary's membership to beyond worth mentioning expiration in two weeks.
    add_member(groups["tech-ops"], users["*****@*****.**"], expiration=note_exp_now+3*week)

    upcoming_expirations = _get_unsent_expirations(session, now+2*week)
    assert upcoming_expirations == []

    notices_sent = process_async_emails(settings, session, now+2*week, dry_run=True)
    assert notices_sent == 0
예제 #17
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
예제 #18
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"])
예제 #19
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"
예제 #20
0
def test_audit_end_to_end(session, users, groups, http_client, base_url,
                          graph):  # noqa
    """ Tests an end-to-end audit cycle. """
    groupname = 'audited-team'

    zay_id = users["*****@*****.**"].id
    gary_id = users["*****@*****.**"].id

    # make everyone an auditor or global audit will have issues
    add_member(groups["auditors"], users["*****@*****.**"])
    add_member(groups["auditors"], users["*****@*****.**"])
    add_member(groups["auditors"], users["*****@*****.**"])
    add_member(groups["auditors"], users["*****@*****.**"])

    # add some users to test removal
    add_member(groups[groupname], users["*****@*****.**"])
    add_member(groups[groupname], users["*****@*****.**"])

    graph.update_from_db(session)

    # start the audit
    end_at_str = (datetime.now() + timedelta(days=10)).strftime('%m/%d/%Y')
    fe_url = url(base_url, '/audits/create')
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({'ends_at': end_at_str}),
                                   headers={'X-Grouper-User': '******'})
    assert resp.code == 200

    open_audits = get_audits(session, only_open=True).all()
    assert len(open_audits) == 4, 'audits created'

    assert groupname in [x.group.name for x in open_audits
                         ], 'group we expect also gets audit'

    # pull all the info we need to resolve audits, avoids detached sqlalchemy sessions
    AuditMember = namedtuple('AuditMember', 'am_id, edge_type, edge_id')
    Audit = namedtuple('Audit',
                       'audit_id, owner_name, group_name, audit_members')
    all_group_ids = [x.group.id for x in open_audits]
    open_audits = [
        Audit(x.id,
              x.group.my_owners().iterkeys().next(), x.group.name, [
                  AuditMember(am.id, am.edge.member_type, am.edge_id)
                  for am in x.my_members()
              ]) for x in open_audits
    ]

    # approve everything but the one we added members to
    for one_audit in open_audits:
        fe_url = url(base_url,
                     '/audits/{}/complete'.format(one_audit.audit_id))

        if one_audit.group_name == groupname:
            continue

        # blanket approval
        body = urlencode({
            "audit_{}".format(am.am_id): "approved"
            for am in one_audit.audit_members
        })

        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            body=body,
            headers={'X-Grouper-User': one_audit.owner_name})
        assert resp.code == 200

    open_audits = get_audits(session, only_open=True).all()
    assert len(open_audits) == 1, 'only our test group remaining'

    one_audit = open_audits[0]
    one_audit.id

    body_dict = {}
    for am in one_audit.my_members():
        if gary_id == am.member.id:
            # deny
            body_dict["audit_{}".format(am.id)] = "remove"
        else:
            # approve
            body_dict["audit_{}".format(am.id)] = "approved"

    owner_name = one_audit.group.my_owners().iterkeys().next()
    fe_url = url(base_url, '/audits/{}/complete'.format(one_audit.id))
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode(body_dict),
                                   headers={'X-Grouper-User': owner_name})
    assert resp.code == 200

    # check all the logs
    assert len(AuditLog.get_entries(
        session, action='start_audit')) == 1, 'global start is logged'
    assert len(AuditLog.get_entries(
        session,
        action='complete_global_audit')) == 1, 'global complete is logged'

    for group_id in all_group_ids:
        assert len(
            AuditLog.get_entries(session,
                                 on_group_id=group_id,
                                 action='complete_audit',
                                 category=AuditLogCategory.audit)
        ) == 1, 'complete entry for each group'

    assert len(
        AuditLog.get_entries(session,
                             on_user_id=gary_id,
                             category=AuditLogCategory.audit)
    ) == 1, 'removal AuditLog entry on user'
예제 #21
0
def test_audit_end_to_end(session, users, groups, http_client, base_url):  # noqa
    """ Tests an end-to-end audit cycle. """
    groupname = 'audited-team'

    zay_id = users["*****@*****.**"].id
    gary_id = users["*****@*****.**"].id

    # make everyone an auditor or global audit will have issues
    add_member(groups["auditors"], users["*****@*****.**"])
    add_member(groups["auditors"], users["*****@*****.**"])
    add_member(groups["auditors"], users["*****@*****.**"])
    add_member(groups["auditors"], users["*****@*****.**"])

    # add some users to test removal
    add_member(groups[groupname], users["*****@*****.**"])
    add_member(groups[groupname], users["*****@*****.**"])

    # start the audit
    end_at_str = (datetime.now() + timedelta(days=10)).strftime('%m/%d/%Y')
    fe_url = url(base_url, '/audits/create')
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'ends_at': end_at_str}), headers={'X-Grouper-User': '******'})
    assert resp.code == 200

    open_audits = get_audits(session, only_open=True).all()
    assert len(open_audits) == 4, 'audits created'

    assert groupname in [x.group.name for x in open_audits], 'group we expect also gets audit'

    # pull all the info we need to resolve audits, avoids detached sqlalchemy sessions
    AuditMember = namedtuple('AuditMember', 'am_id, edge_type, edge_id')
    Audit = namedtuple('Audit', 'audit_id, owner_name, group_name, audit_members')
    all_group_ids = [x.group.id for x in open_audits]
    open_audits = [Audit(x.id, x.group.my_owners().iterkeys().next(), x.group.name,
            [AuditMember(am.id, am.edge.member_type, am.edge_id) for am in x.my_members()]) for
            x in open_audits]

    # approve everything but the one we added members to
    for one_audit in open_audits:
        fe_url = url(base_url, '/audits/{}/complete'.format(one_audit.audit_id))

        if one_audit.group_name == groupname:
            continue

        # blanket approval
        body = urlencode({"audit_{}".format(am.am_id): "approved" for am in
                one_audit.audit_members})

        resp = yield http_client.fetch(fe_url, method="POST", body=body,
                headers={'X-Grouper-User': one_audit.owner_name})
        assert resp.code == 200

    open_audits = get_audits(session, only_open=True).all()
    assert len(open_audits) == 1, 'only our test group remaining'

    one_audit = open_audits[0]
    one_audit.id

    body_dict = {}
    for am in one_audit.my_members():
        if gary_id == am.member.id:
            # deny
            body_dict["audit_{}".format(am.id)] = "remove"
        else:
            # approve
            body_dict["audit_{}".format(am.id)] = "approved"

    owner_name = one_audit.group.my_owners().iterkeys().next()
    fe_url = url(base_url, '/audits/{}/complete'.format(one_audit.id))
    resp = yield http_client.fetch(fe_url, method="POST", body=urlencode(body_dict),
            headers={'X-Grouper-User': owner_name})
    assert resp.code == 200

    # check all the logs
    assert len(AuditLog.get_entries(session, action='start_audit')) == 1, 'global start is logged'
    assert len(AuditLog.get_entries(session,
            action='complete_global_audit')) == 1, 'global complete is logged'

    for group_id in all_group_ids:
        assert len(AuditLog.get_entries(session, on_group_id=group_id, action='complete_audit',
                category=AuditLogCategory.audit)) == 1, 'complete entry for each group'

    assert len(AuditLog.get_entries(session, on_user_id=gary_id,
            category=AuditLogCategory.audit)) == 1, 'removal AuditLog entry on user'
예제 #22
0
def setup_desc_to_ances(session, users, groups):  # noqa
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"])

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

    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"])
예제 #23
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
예제 #24
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"])
예제 #25
0
def test_expiration_notifications(expiring_graph, session, users, groups, permissions):  # noqa
    now = datetime.utcnow()
    note_exp_now = now + timedelta(settings.expiration_notice_days)
    day = timedelta(1)
    week = timedelta(7)

    # What expirations are coming up in the next day?  Next week?
    upcoming_expirations = _get_unsent_expirations(session, now+day)
    assert upcoming_expirations == []

    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Make someone expire a week from now.
    edit_member(groups["team-sre"], users["*****@*****.**"], expiration=note_exp_now+week)
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Now cancel that expiration.
    edit_member(groups["team-sre"], users["*****@*****.**"], expiration=None)
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Make an ordinary member an owner.
    edit_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Make an owner an ordinary member.
    edit_member(groups["team-sre"], users["*****@*****.**"], role="member")
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert sorted(upcoming_expirations) == [
        # Group, subgroup, subgroup owners.
        ("serving-team", "team-sre", "*****@*****.**"),
        ("serving-team", "team-sre", "*****@*****.**"),
        # Group, user, user.
        ("team-sre", "*****@*****.**", "*****@*****.**"),
    ]

    # Send notices about expirations coming up in the next day, next week.
    notices_sent = process_async_emails(settings, session, now+day, dry_run=True)
    assert notices_sent == 0

    notices_sent = process_async_emails(settings, session, now+week, dry_run=True)
    assert notices_sent == 3
    # ("serving-team", "team-sre", "*****@*****.**")
    # ("serving-team", "team-sre", "*****@*****.**")
    # ("team-sre", "*****@*****.**", "*****@*****.**")

    # Notices in the upcoming week have already been sent, but there's another
    # two weeks from now.
    upcoming_expirations = _get_unsent_expirations(session, now+week)
    assert upcoming_expirations == []

    upcoming_expirations = _get_unsent_expirations(session, now+2*week)
    assert upcoming_expirations == [
        ("tech-ops", "*****@*****.**", "*****@*****.**"),
    ]

    # We already sent these notices.
    notices_sent = process_async_emails(settings, session, now+week, dry_run=True)
    assert notices_sent == 0

    # Extend gary's membership to beyond worth mentioning expiration in two weeks.
    add_member(groups["tech-ops"], users["*****@*****.**"], expiration=note_exp_now+3*week)

    upcoming_expirations = _get_unsent_expirations(session, now+2*week)
    assert upcoming_expirations == []

    notices_sent = process_async_emails(settings, session, now+2*week, dry_run=True)
    assert notices_sent == 0
예제 #26
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
예제 #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"])
예제 #28
0
def setup_desc_to_ances(session, users, groups):  # noqa
    add_member(groups["team-sre"], users["*****@*****.**"], role="owner")
    add_member(groups["team-sre"], users["*****@*****.**"])

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

    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"])
예제 #29
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["*****@*****.**"])
예제 #30
0
파일: fixtures.py 프로젝트: zorkian/grouper
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
예제 #31
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
예제 #32
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"])
예제 #33
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
예제 #34
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 = BackgroundProcessor(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 = BackgroundProcessor(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["*****@*****.**"])
예제 #35
0
def standard_graph(session, graph, users, groups):
    add_member(groups["team-sre"], users["gary"], role="owner")
    add_member(groups["team-sre"], users["zay"])
    add_member(groups["team-sre"], users["zorkian"])

    add_member(groups["tech-ops"], users["zay"], role="owner")
    add_member(groups["tech-ops"], users["gary"])

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

    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