Esempio n. 1
0
def test_expire_edges(expired_graph, session):  # noqa: F811
    """ Test expiration auditing and notification. """
    email = session.query(AsyncNotification).all()
    assert email == []
    for edge in session.query(GroupEdge).all():
        assert edge.active == True

    # Expire the edges.
    background = BackgroundProcessor(settings, None)
    background.expire_edges(session)

    # Check that the edges are now marked as inactive.
    edges = (session.query(GroupEdge).filter(
        GroupEdge.group_id == Group.id, Group.enabled == True,
        GroupEdge.expiration != None).all())
    for edge in edges:
        assert edge.active == False

    # Check that we have two queued email messages.
    #
    # TODO(rra): It would be nice to check the contents as well.
    email = session.query(AsyncNotification).all()
    assert len(email) == 2

    # Check that we have three audit log entries: one for the expired user and
    # two for both "sides" of the expired group membership.
    audits = AuditLog.get_entries(session, action="expired_from_group")
    assert len(audits) == 3
Esempio n. 2
0
def start_processor(args, settings):
    # type: (Namespace, BackgroundSettings) -> None
    log_level = logging.getLevelName(logging.getLogger().level)
    logging.info("begin. log_level={}".format(log_level))

    try:
        plugins = PluginProxy.load_plugins(settings, "grouper-background")
        set_global_plugin_proxy(plugins)
    except PluginsDirectoryDoesNotExist as e:
        logging.fatal("Plugin directory does not exist: {}".format(e))
        sys.exit(1)

    # setup database
    logging.debug("configure database session")
    Session.configure(bind=get_db_engine(settings.database))

    background = BackgroundProcessor(settings, plugins)
    background.run()
Esempio n. 3
0
def start_processor(args, settings, sentry_client):
    # type: (Namespace, BackgroundSettings, SentryProxy) -> None
    log_level = logging.getLevelName(logging.getLogger().level)
    logging.info("begin. log_level={}".format(log_level))

    try:
        plugins = PluginProxy.load_plugins(settings, "grouper-background")
        set_global_plugin_proxy(plugins)
    except PluginsDirectoryDoesNotExist as e:
        logging.fatal("Plugin directory does not exist: {}".format(e))
        sys.exit(1)

    # setup database
    logging.debug("configure database session")
    Session.configure(bind=get_db_engine(settings.database))

    background = BackgroundProcessor(settings, sentry_client)
    background.run()
Esempio n. 4
0
def start_processor(args, sentry_client):
    # type: (argparse.Namespace, SentryProxy) -> None

    log_level = logging.getLevelName(logging.getLogger().level)
    logging.info("begin. log_level={}".format(log_level))

    try:
        initialize_plugins(settings.plugin_dirs, settings.plugin_module_paths, "grouper-background")
    except PluginsDirectoryDoesNotExist as e:
        logging.fatal("Plugin directory does not exist: {}".format(e))
        sys.exit(1)

    # setup database
    logging.debug("configure database session")
    Session.configure(bind=get_db_engine(get_database_url(settings)))

    settings.start_config_thread(args.config, "background")

    background = BackgroundProcessor(settings, sentry_client)
    background.run()
Esempio n. 5
0
def test_promote_nonauditors(
        mock_gagn,
        standard_graph,
        graph,
        users,
        groups,
        session,
        permissions  # noqa: F811
):
    """ Test expiration auditing and notification. """

    assert graph.get_group_details("audited-team")["audited"]

    #
    # Ensure auditors promotion for all approvers
    #
    approver_roles = ["owner", "np-owner", "manager"]

    affected_users = set(
        ["*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**"])
    for idx, role in enumerate(approver_roles):

        # Add non-auditor as an approver to an audited group
        add_member(groups["audited-team"], users["*****@*****.**"], role=role)
        graph.update_from_db(session)
        assert not affected_users.intersection(get_users(graph, "auditors"))

        # do the promotion logic
        background = BackgroundProcessor(settings, None)
        background.promote_nonauditors(session)

        # Check that the users now added to auditors group
        graph.update_from_db(session)
        assert affected_users.intersection(get_users(
            graph, "auditors")) == affected_users
        unsent_emails = _get_unsent_emails_and_send(session)
        assert any([
            'Subject: Added as member to group "auditors"' in email.body
            and "To: [email protected]" in email.body for email in unsent_emails
        ])
        assert any([
            'Subject: Added as member to group "auditors"' in email.body
            and "To: [email protected]" in email.body for email in unsent_emails
        ])
        assert any([
            'Subject: Added as member to group "auditors"' in email.body
            and "To: [email protected]" in email.body for email in unsent_emails
        ])

        audits = AuditLog.get_entries(session, action="nonauditor_promoted")
        assert len(audits) == len(affected_users) * (idx + 1)

        # reset for next iteration
        revoke_member(groups["audited-team"], users["*****@*****.**"])
        for username in affected_users:
            revoke_member(groups["auditors"], users[username])

    #
    # Ensure nonauditor, nonapprovers in audited groups do not get promoted
    #

    # first, run a promotion to get any other promotion that we don't
    # care about out of the way
    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)

    prev_audit_log_count = len(
        AuditLog.get_entries(session, action="nonauditor_promoted"))

    member_roles = ["member"]
    for idx, role in enumerate(member_roles):

        # Add non-auditor as a non-approver to an audited group
        add_member(groups["audited-team"], users["*****@*****.**"], role=role)

        # do the promotion logic
        background = BackgroundProcessor(settings, None)
        background.promote_nonauditors(session)

        # Check that the user is not added to auditors group
        graph.update_from_db(session)
        assert "*****@*****.**" not in get_users(graph, "auditors")

        assert not any([
            'Subject: Added as member to group "auditors"' 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_promoted")
        assert len(audits) == prev_audit_log_count

        revoke_member(groups["audited-team"], users["*****@*****.**"])
Esempio n. 6
0
def test_auditor_promotion(mock_nnp, mock_gagn, session, graph, permissions, users):  # noqa: F811
    """Test automatic promotion of non-auditor approvers

    We set up our own group/user/permission for testing instead of
    using the `standard_graph` fixture---retrofitting it to work for
    us and also not break existing tests is too cumbersome.

    So here are our groups:

    very-special-auditors:
      * user14

    group-1:
      * user11 (o)
      * user12
      * user13 (np-o)
      * user14 (o, a)

    group-2:
      * user13 (np-o)
      * user21 (o)
      * user22

    group-3:
      * user22 (o)
      * user12 (o)

    group-4:
      * user21 (np-o)
      * user41
      * user42 (o)
      * user43 (np-o)

    o: owner, np-o: no-permission owner, a: auditor

    group-1 and group-2 have the permission that we will enable
    auditing. group-4 will be a subgroup of group-1 and thus will
    inherit the audited permission from group-1.

    The expected outcome is: user11, user13, user21, user42, and
    user43 will be added to the auditors group.

    """
    settings = BackgroundSettings()
    set_global_settings(settings)

    #
    # set up our test part of the graph
    #

    # create groups
    AUDITED_GROUP = "audited"
    AUDITORS_GROUP = mock_gagn.return_value = "very-special-auditors"
    PERMISSION_NAME = "test-permission"
    all_groups = {
        groupname: Group.get_or_create(session, groupname=groupname)[0]
        for groupname in ("group-1", "group-2", "group-3", "group-4", AUDITORS_GROUP)
    }
    # create users
    users.update(
        {
            username + "@a.co": User.get_or_create(session, username=username + "@a.co")[0]
            for username in (
                "user11",
                "user12",
                "user13",
                "user14",
                "user21",
                "user22",
                "user23",
                "user41",
                "user42",
                "user43",
            )
        }
    )
    # create permissions
    permissions.update(
        {
            permission: get_or_create_permission(
                session, permission, description="{} permission".format(permission)
            )[0]
            for permission in [PERMISSION_NAME]
        }
    )
    # add users to groups
    for (groupname, username, role) in (
        ("group-1", "user11", "owner"),
        ("group-1", "user12", "member"),
        ("group-1", "user13", "np-owner"),
        ("group-1", "user14", "owner"),
        ("group-2", "user13", "np-owner"),
        ("group-2", "user21", "owner"),
        ("group-2", "user22", "member"),
        ("group-3", "user12", "owner"),
        ("group-3", "user22", "owner"),
        ("group-4", "user21", "np-owner"),
        ("group-4", "user41", "member"),
        ("group-4", "user42", "owner"),
        ("group-4", "user43", "np-owner"),
    ):
        add_member(all_groups[groupname], users[username + "@a.co"], role=role)
    # add group-4 as member of group-1
    add_member(all_groups["group-1"], all_groups["group-4"])
    # add user14 to auditors group
    add_member(all_groups[AUDITORS_GROUP], users["*****@*****.**"])
    # grant permissions to groups
    #
    # give the test permission to groups 1 and 2, and group 4 should
    # also inherit from group 1
    grant_permission(all_groups["group-1"], permissions[PERMISSION_NAME])
    grant_permission(all_groups["group-2"], permissions[PERMISSION_NAME])
    grant_permission(all_groups[AUDITORS_GROUP], permissions[PERMISSION_AUDITOR])

    graph.update_from_db(session)
    # done setting up

    # now a few pre-op checks
    assert not graph.get_group_details("group-1").get(AUDITED_GROUP)
    assert not graph.get_group_details("group-4").get(AUDITED_GROUP)
    assert get_users(graph, AUDITORS_GROUP) == set(["*****@*****.**"])
    assert get_users(graph, "group-3") == set(["*****@*****.**", "*****@*****.**"])

    #
    # run the promotion logic -> nothing should happen because the
    # test-permission is not yet audited
    #
    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)
    graph.update_from_db(session)

    # nothing should have happened
    assert not graph.get_group_details("group-1").get(AUDITED_GROUP)
    assert not graph.get_group_details("group-4").get(AUDITED_GROUP)
    assert get_users(graph, AUDITORS_GROUP) == set(["*****@*****.**"])
    assert mock_nnp.call_count == 0

    #
    # now enable auditing for the permission and run the promotion
    # logic again
    #
    enable_permission_auditing(session, PERMISSION_NAME, users["*****@*****.**"].id)
    graph.update_from_db(session)
    assert graph.get_group_details("group-1").get(AUDITED_GROUP)
    assert graph.get_group_details("group-4").get(AUDITED_GROUP)

    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)
    graph.update_from_db(session)

    # check that stuff happened
    assert get_users(graph, AUDITORS_GROUP) == set(
        ["*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**"]
    )
    expected_calls = [
        call(
            settings, session, users["*****@*****.**"], all_groups[AUDITORS_GROUP], set(["group-1"])
        ),
        call(
            settings,
            session,
            users["*****@*****.**"],
            all_groups[AUDITORS_GROUP],
            set(["group-1", "group-2"]),
        ),
        call(
            settings,
            session,
            users["*****@*****.**"],
            all_groups[AUDITORS_GROUP],
            set(["group-2", "group-4"]),
        ),
        call(
            settings, session, users["*****@*****.**"], all_groups[AUDITORS_GROUP], set(["group-4"])
        ),
        call(
            settings, session, users["*****@*****.**"], all_groups[AUDITORS_GROUP], set(["group-4"])
        ),
    ]
    assert mock_nnp.call_count == len(expected_calls)
    mock_nnp.assert_has_calls(expected_calls, any_order=True)

    #
    # run the background promotion logic again, and nothing should
    # happen
    #
    mock_nnp.reset_mock()
    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)
    assert mock_nnp.call_count == 0
Esempio n. 7
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["*****@*****.**"])
Esempio n. 8
0
def test_auditor_promotion(mock_nnp, mock_gagn, session, graph, permissions,
                           users):  # noqa: F811
    """Test automatic promotion of non-auditor approvers

    We set up our own group/user/permission for testing instead of
    using the `standard_graph` fixture---retrofitting it to work for
    us and also not break existing tests is too cumbersome.

    So here are our groups:

    very-special-auditors:
      * user14

    group-1:
      * user11 (o)
      * user12
      * user13 (np-o)
      * user14 (o, a)

    group-2:
      * user13 (np-o)
      * user21 (o)
      * user22

    group-3:
      * user22 (o)
      * user12 (o)

    group-4:
      * user21 (np-o)
      * user41
      * user42 (o)
      * user43 (np-o)

    o: owner, np-o: no-permission owner, a: auditor

    group-1 and group-2 have the permission that we will enable
    auditing. group-4 will be a subgroup of group-1 and thus will
    inherit the audited permission from group-1.

    The expected outcome is: user11, user13, user21, user42, and
    user43 will be added to the auditors group.

    """
    settings = BackgroundSettings()
    set_global_settings(settings)

    #
    # set up our test part of the graph
    #

    # create groups
    AUDITED_GROUP = "audited"
    AUDITORS_GROUP = mock_gagn.return_value = "very-special-auditors"
    PERMISSION_NAME = "test-permission"
    all_groups = {
        groupname: Group.get_or_create(session, groupname=groupname)[0]
        for groupname in ("group-1", "group-2", "group-3", "group-4",
                          AUDITORS_GROUP)
    }
    # create users
    users.update({
        username + "@a.co": User.get_or_create(session,
                                               username=username + "@a.co")[0]
        for username in (
            "user11",
            "user12",
            "user13",
            "user14",
            "user21",
            "user22",
            "user23",
            "user41",
            "user42",
            "user43",
        )
    })
    # create permissions
    permissions.update({
        permission: get_or_create_permission(
            session,
            permission,
            description="{} permission".format(permission))[0]
        for permission in [PERMISSION_NAME]
    })
    # add users to groups
    for (groupname, username, role) in (
        ("group-1", "user11", "owner"),
        ("group-1", "user12", "member"),
        ("group-1", "user13", "np-owner"),
        ("group-1", "user14", "owner"),
        ("group-2", "user13", "np-owner"),
        ("group-2", "user21", "owner"),
        ("group-2", "user22", "member"),
        ("group-3", "user12", "owner"),
        ("group-3", "user22", "owner"),
        ("group-4", "user21", "np-owner"),
        ("group-4", "user41", "member"),
        ("group-4", "user42", "owner"),
        ("group-4", "user43", "np-owner"),
    ):
        add_member(all_groups[groupname], users[username + "@a.co"], role=role)
    # add group-4 as member of group-1
    add_member(all_groups["group-1"], all_groups["group-4"])
    # add user14 to auditors group
    add_member(all_groups[AUDITORS_GROUP], users["*****@*****.**"])
    # grant permissions to groups
    #
    # give the test permission to groups 1 and 2, and group 4 should
    # also inherit from group 1
    grant_permission(all_groups["group-1"], permissions[PERMISSION_NAME])
    grant_permission(all_groups["group-2"], permissions[PERMISSION_NAME])
    grant_permission(all_groups[AUDITORS_GROUP],
                     permissions[PERMISSION_AUDITOR])

    graph.update_from_db(session)
    # done setting up

    # now a few pre-op checks
    assert not graph.get_group_details("group-1").get(AUDITED_GROUP)
    assert not graph.get_group_details("group-4").get(AUDITED_GROUP)
    assert get_users(graph, AUDITORS_GROUP) == set(["*****@*****.**"])
    assert get_users(graph, "group-3") == set(["*****@*****.**", "*****@*****.**"])

    #
    # run the promotion logic -> nothing should happen because the
    # test-permission is not yet audited
    #
    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)
    graph.update_from_db(session)

    # nothing should have happened
    assert not graph.get_group_details("group-1").get(AUDITED_GROUP)
    assert not graph.get_group_details("group-4").get(AUDITED_GROUP)
    assert get_users(graph, AUDITORS_GROUP) == set(["*****@*****.**"])
    assert mock_nnp.call_count == 0

    #
    # now enable auditing for the permission and run the promotion
    # logic again
    #
    enable_permission_auditing(session, PERMISSION_NAME,
                               users["*****@*****.**"].id)
    graph.update_from_db(session)
    assert graph.get_group_details("group-1").get(AUDITED_GROUP)
    assert graph.get_group_details("group-4").get(AUDITED_GROUP)

    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)
    graph.update_from_db(session)

    # check that stuff happened
    assert get_users(graph, AUDITORS_GROUP) == set([
        "*****@*****.**", "*****@*****.**", "*****@*****.**", "*****@*****.**",
        "*****@*****.**", "*****@*****.**"
    ])
    expected_calls = [
        call(settings, session, users["*****@*****.**"],
             all_groups[AUDITORS_GROUP], set(["group-1"])),
        call(
            settings,
            session,
            users["*****@*****.**"],
            all_groups[AUDITORS_GROUP],
            set(["group-1", "group-2"]),
        ),
        call(
            settings,
            session,
            users["*****@*****.**"],
            all_groups[AUDITORS_GROUP],
            set(["group-2", "group-4"]),
        ),
        call(settings, session, users["*****@*****.**"],
             all_groups[AUDITORS_GROUP], set(["group-4"])),
        call(settings, session, users["*****@*****.**"],
             all_groups[AUDITORS_GROUP], set(["group-4"])),
    ]
    assert mock_nnp.call_count == len(expected_calls)
    mock_nnp.assert_has_calls(expected_calls, any_order=True)

    #
    # run the background promotion logic again, and nothing should
    # happen
    #
    mock_nnp.reset_mock()
    background = BackgroundProcessor(settings, None)
    background.promote_nonauditors(session)
    assert mock_nnp.call_count == 0