def test_user_generation_manages_non_staff_properly(_): input_ = _generate_user_rows() # user 'aalison' is good candidate because her manager does not # exist aalison_row_index = 0 manager_only_user = input_[aalison_row_index] manager_only_user["is_staff"] = False messages = [] ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) generated, messages = population.generate_required_users( ldapsource, input_, messages ) assert 1 == len(messages) assert population.DEFAULT_MANAGER_ONLY_TMPL.format( uid=manager_only_user["employee_id"], display_name=manager_only_user["manager_username"], ) expected = _generate_user_list() expected[aalison_row_index].is_staff = False expected[aalison_row_index].manager_username = None # TODO: super fickle, fix this manager_indices = [2, 5, 6, 7] for i, eg in enumerate(zip(expected, generated)): if i in manager_indices: assert eg[1].has_direct_reports else: assert not eg[1].has_direct_reports assert eg[0].username == eg[1].username
def _generate_user_list(): ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) users = [] for rlu in TEST_LDAP_FULL_DETAILS.values(): u = User.create_from_ldap_details(ldapsource, rlu) users.append(u) return sorted(users, key=lambda u: (u.last_name, u.first_name))
def test_population_validation_catches_duplicate_users(): def _get_ldap_user_by_employee_id_mck(k, id_): if k != TEST_UID_KEY: pytest.fail('Incorrect key "{}" provided'.format(k)) details_by_id = {v[TEST_UID_KEY]: v for _, v in TEST_LDAP_FULL_DETAILS.items()} return details_by_id.get(id_) with mock.patch( "adaero.security.ldapauth.LDAPAuth." "get_ldap_user_by_kv", side_effect=_get_ldap_user_by_employee_id_mck, ): ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) input_ = _generate_user_list() duplicate_user = User.create_from_ldap_details( ldapsource, TEST_LDAP_FULL_DETAILS[NOMINATED_USERNAME] ) duplicate_user.first_name = "Duplicate" input_.append(duplicate_user) messages = [] generated, messages = population.remove_duplicate_users(input_, messages) assert 1 == len(messages) # take into account the header row duplicate_row_num = len(TEST_LDAP_FULL_DETAILS.keys()) + 2 assert ( population.DEFAULT_DUPLICATE_USER_TMPL.format( row_num=duplicate_row_num, first_row_num=USER_TO_REMOVE_ROW_NUM ) == messages[0] ) expected = _generate_user_list() for e, g in zip(expected, generated): assert e.first_name == e.first_name
def test_population_conversion_catches_users_without_ldap(): def _get_ldap_user_by_employee_id_mck(k, id_): if k != TEST_UID_KEY: pytest.fail('Incorrect key "{}" provided'.format(k)) details_by_id = {v[TEST_UID_KEY]: v for _, v in TEST_LDAP_FULL_DETAILS.items()} details_by_id.pop(USER_TO_REMOVE_EMPLOYEE_ID) return details_by_id.get(id_) with mock.patch( "adaero.security.ldapauth.LDAPAuth." "get_ldap_user_by_kv", side_effect=_get_ldap_user_by_employee_id_mck, ): expected = _generate_user_list() ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) for i, u in enumerate(expected): if u.employee_id == USER_TO_REMOVE_EMPLOYEE_ID: expected.pop(i) input_ = open(HIERARCHY_CSV_FILEPATH).read() messages = [] generated, messages = population.convert_population_csv_to_user_rows( ldapsource, input_, messages ) assert 1 == len(messages) assert ( population.MISSING_USER_TMPL.format(row_num=USER_TO_REMOVE_ROW_NUM) == messages[0] ) for e, g in zip(expected, generated): assert e.first_name == e.first_name
def _generate_user_rows(): ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) user_rows = [] for rlu in TEST_LDAP_FULL_DETAILS.values(): u = User.create_from_ldap_details(ldapsource, rlu) u.is_staff = True user_rows.append(u.to_dict()) return sorted(user_rows, key=lambda u: (u["last_name"], u["first_name"]))
def stats_session(dbsession): ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) with transaction.manager: for user_details in TEST_LDAP_FULL_DETAILS.values(): dbsession.add( User.create_from_ldap_details(ldapsource, user_details)) add_test_data_for_stats(dbsession) yield dbsession drop_everything(dbsession)
def email_job(settings): log.info("Starting email job...") start_time_s = time.time() engine = get_engine(settings) session_factory = get_session_factory(engine) dbsession = get_tm_session(session_factory, transaction.manager) ldapsource = build_ldapauth_from_settings(settings) check_and_send_email(dbsession, ldapsource, settings) total_time_s = time.time() - start_time_s log.info("Finished email job, took {0:.2f} seconds".format(total_time_s))
def test_population_validation_catches_invalid_headers(): field_names = copy(population.FIELDNAMES) missing = field_names.pop(0) extra = "foobar" field_names.append(extra) headings_str = ",".join(field_names) ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) users, messages = population.get_valid_users_from_csv(ldapsource, headings_str) assert not users assert 1 == len(messages) assert ( population.DEFAULT_INVALID_HEADERS_TMPL.format(missing=[missing], extra=[extra]) ) == messages[0]
def includeme(config): """ Initialize the model for a Pyramid app. Activate this setup using ``config.include('adaero.models')``. """ settings = config.get_settings() talent_manager_usernames_string = get_config_value( settings, constants.TALENT_MANAGER_USERNAMES_KEY) if not talent_manager_usernames_string: raise ValueError( MISCONFIGURATION_MESSAGE.format( error="Talent manager usernames are not set")) talent_managers = json.loads(talent_manager_usernames_string) settings[constants.TALENT_MANAGER_USERNAMES_KEY] = talent_managers location = get_config_value(settings, constants.HOMEBASE_LOCATION_KEY) if not location: raise ValueError( MISCONFIGURATION_MESSAGE.format( error="Homebase location is not set")) # should_load_users = get_config_value(settings, # constants # .RELOAD_USERS_ON_APP_START_KEY, # False) should_load_tms = get_config_value( settings, constants.LOAD_TALENT_MANAGERS_ON_APP_START_KEY, True) engine = get_engine(settings) for seq in SEQUENCES: seq.create(engine) Base.metadata.create_all(engine) session_factory = get_session_factory(engine) config.registry["dbsession_factory"] = session_factory dbsession = get_tm_session(session_factory, transaction.manager) ldapsource = ldapauth.build_ldapauth_from_settings(settings) if should_load_tms: load_talent_managers_only(dbsession, ldapsource, settings) # make request.dbsession available for use in Pyramid config.add_request_method( lambda request: get_tm_session(session_factory, transaction.manager), "dbsession", reify=True, )
def new_ldap_mocked_app_with_users(dbsession, request): settings = DEFAULT_TEST_SETTINGS ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) if request.config.getoption("--use-sqlite3"): settings["adaero.use_local_sqlite3"] = True # need yield_fixture as we need the patch applied over the lifetime of # the testapp instance with patch( "adaero.security.ldapauth.LDAPAuth.auth_user", side_effect=auth_user_mock_fn, autospec=True, ), patch( "adaero.security.ldapauth.LDAPAuth." "get_ldap_user_by_username", side_effect=get_ldap_user_by_username_mock_fn, autospec=True, ), patch( "adaero.security.ldapauth.LDAPAuth." "get_ldap_user_by_email", side_effect=get_ldap_by_email_mock_fn, autospec=True, ): app = webtest.TestApp(adaero.main({}, **settings)) dbsession = get_dbsession(app) with transaction.manager: for user_details in TEST_LDAP_FULL_DETAILS.values(): if (user_details[tests.integration.constants.TEST_USERNAME_KEY] not in TEST_EMPLOYEES): continue user = User.create_from_ldap_details(ldapsource, user_details) set_as_staff(user, user_details) dbsession.add(user) # Add non-staff member e.g. upper management non_staff_user = User.create_from_ldap_details( ldapsource, TEST_NON_STAFF_USER) dbsession.add(non_staff_user) freezer = freeze_time(TEST_UTCNOW) freezer.start() yield app freezer.stop()
def test_correct_list_of_users_are_parsed(_): expected = _generate_user_rows() ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) input_ = open(HIERARCHY_CSV_FILEPATH).read() messages = [] generated, new_messages = population.convert_population_csv_to_user_rows( ldapsource, input_, messages ) # user 'aalison' has no manager id because the manager itself does # not exist in the test ldap data expected[0]["manager_username"] = None for e, g in zip(expected, generated): assert e["username"] == g["username"] assert e["manager_username"] == g["manager_username"] assert e["is_staff"] == g["is_staff"] assert g.get("manager_id") is None assert not messages
def test_user_generation_generates_missing_managers(_): input_ = _generate_user_rows() # user 'llovelace' is good candidate because she is direct manager of # user 'cdalton' missing_manager_row = input_.pop(5) messages = [] # we need to remove user 'aalison' because her manager does not exist aalison_row_index = 0 input_.pop(aalison_row_index) ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) generated, messages = population.generate_required_users( ldapsource, input_, messages ) generated = sorted(generated, key=lambda u: (u.last_name, u.first_name)) assert 1 == len(messages) assert population.DEFAULT_MISSING_MANAGER_TMPL.format( uid=missing_manager_row["employee_id"], display_name=missing_manager_row["manager_username"], ) expected = _generate_user_list() expected.pop(aalison_row_index) for e, g in zip(expected, generated): assert e.username == g.username
def ldapsource(): return ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS)
def test_get_employee_users(app_with_nominees_inside_entry_subperiod): app = app_with_nominees_inside_entry_subperiod dbsession = get_dbsession(app) users = mail.get_employee_users(dbsession) ldapsource = ldapauth.build_ldapauth_from_settings(DEFAULT_TEST_SETTINGS) assert {u.username for u in users} == {k for k in TEST_EMPLOYEES}
def test_employee_able_to_send_feedback_request_within_entry_subperiod( ldap_mocked_app_with_users, email, expected): # noqa: E501 expected_status_code, expected_msg = expected app = ldap_mocked_app_with_users ldapsource = ldapauth.build_ldapauth_from_settings( app.app.registry.settings) dbsession = get_dbsession(app) template_id = add_test_template(dbsession) add_test_period_with_template(dbsession, Period.ENTRY_SUBPERIOD, template_id) successfully_login(app, TEST_EMPLOYEE_USERNAME) csrf_token = app.cookies[ANGULAR_2_XSRF_TOKEN_COOKIE_NAME] app.app.registry.settings[app_constants.ENABLE_SEND_EMAIL_KEY] = True with patch("smtplib.SMTP") as smtp_mock, patch( "socket.gethostname") as gethostname_mock, patch( "getpass.getuser") as getuser_mock: sendmail_mock = smtp_mock().sendmail gethostname_mock.return_value = TEST_PRODUCTION_HOSTNAME getuser_mock.return_value = TEST_PRODUCTION_USER resp = app.post_json( "/api/v1/external-invite", {"email": email}, headers={ANGULAR_2_XSRF_TOKEN_HEADER_NAME: csrf_token}, expect_errors=expected_status_code != 200, ) if resp.status_code != 200: assert expected_msg == resp.json_body["message"] return # check invite email that is sent parser = Parser() assert len(sendmail_mock.call_args_list) == 1 raw_message = sendmail_mock.call_args_list[0][0][2] message_root = parser.parsestr(raw_message) inviter = User.create_from_ldap_details( ldapsource, TEST_LDAP_FULL_DETAILS[TEST_EMPLOYEE_USERNAME]) subject_str, encoding = decode_header(message_root["Subject"])[0] subject_unicode = subject_str.decode(encoding) assert subject_unicode.count(inviter.display_name) == 1 invite_messages = message_root.get_payload() assert invite_messages[0]["Reply-To"] == inviter.email invite_plain = b64decode(invite_messages[0].get_payload()).decode("utf-8") invite_html = b64decode(invite_messages[1].get_payload()).decode("utf-8") app_url = "https://%s/feedback/%s" % ( TEST_PRODUCTION_HOSTNAME, TEST_LDAP_FULL_DETAILS[inviter.username][ tests.integration.constants.TEST_USERNAME_KEY], ) assert invite_plain.count(app_url) > 0 assert invite_plain.count(inviter.first_name) > 0 assert invite_html.count(app_url) > 1 assert invite_html.count(app_url) % 2 == 0 after_invite_resp = app.post_json( "/api/v1/login", { "username": TEST_COMPANY_COLLEAGUE_USERNAME, "password": TEST_PASSWORD }, ) assert after_invite_resp.status_code == 200