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
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["*****@*****.**"])
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