def test_load_user_add_delete_camel_case(self, s3_stubber): """Tests for syncing users with those present in S3 in which S3 data contains camelCase emails""" # create initial users initial_users = [ { 'email': '*****@*****.**', 'attribute': 'value' }, { 'email': '*****@*****.**', 'otherAttribute': 'value' }, ] initial_users_downcase = [ { 'email': '*****@*****.**', 'attribute': 'value' }, { 'email': '*****@*****.**', 'otherAttribute': 'value' }, ] s3_stubber.add_response('get_object', {'Body': StringIO(json.dumps(initial_users))}, { 'Bucket': os.environ.get('USER_BUCKET'), 'Key': os.environ.get('USER_FILE_PATH') }) load_user_response = load.load_user() # confirm users we expect to be added exist in db users_in_db = user_table.scan_all() for user in initial_users_downcase: assert user in users_in_db # remove users we know about from db results, for next check users_in_db.remove(user) assert load_user_response == initial_users_downcase non_admins_remaining = [ user for user in users_in_db if user.get('Admin', False) ] assert non_admins_remaining == [] # test removing users from db updated_users = [] s3_stubber.add_response('get_object', {'Body': StringIO(json.dumps(updated_users))}) load.load_user() # confirm users are removed from db users_in_db = user_table.scan_all() for user in initial_users: assert user not in users_in_db s3_stubber.assert_no_pending_responses()
def load_user(): """Syncs users in user's table with those present in S3 bucket, ensures admin permissions are retained""" user_emails_to_delete = [] users_to_add = [] s3_response = client_s3.get_object(Bucket=user_bucket, Key=os.getenv('USER_FILE_PATH')) user_list_from_s3 = json.loads(s3_response['Body'].read()) users_from_s3 = {} for user in user_list_from_s3: user['email'] = user['email'].lower() users_from_s3[user['email']] = user ddb_data = user_table.scan_all() users_from_ddb = {user['email']: user for user in ddb_data} for user_email, existing_user in users_from_ddb.items(): if user_email in users_from_s3: if existing_user != users_from_s3[user_email]: if existing_user.get('isAdmin', False): # update incoming user users_to_add.append(dict( users_from_s3[user_email], **{ 'isAdmin': existing_user.get('isAdmin'), })) else: users_to_add.append(users_from_s3[user_email]) else: if existing_user.get('isAdmin', False): users_to_add.append({ 'email': existing_user.get('email'), 'isAdmin': existing_user.get('isAdmin'), }) else: user_emails_to_delete.append(user_email) for user_email in users_from_s3: if user_email not in users_from_ddb: users_to_add.append(users_from_s3[user_email]) with user_table.batch_writer() as batch: for user_email in user_emails_to_delete: batch.delete_item(Key={'email': user_email}) for user in users_to_add: batch.put_item(Item=user) return user_list_from_s3
def list_all_users(all_accounts): """ :return: list composed of all users' email, first name, last name, and a list of accountIds associated with that user """ users = user_table.scan_all( ProjectionExpression='email, firstName, lastName, accounts') for user in users: user['accountList'] = [{ 'accountId': account, 'accountName': all_accounts.get(account, {}).get('account_name', '') } for account in user.get('accounts', {}).keys()] user.pop('accounts', None) return users
def test_load_user_admin_updated(self, s3_stubber): """Tests for syncing admin users with those present in S3""" # create initial admin users. initial_users = [ { 'email': '*****@*****.**', 'isAdmin': True, 'attribute': 'value1' }, { 'email': '*****@*****.**', 'isAdmin': True, 'attribute': 'value1' }, { 'email': '*****@*****.**', 'isAdmin': True, 'attribute': 'value1' }, ] for user in initial_users: user_table.put_item(Item=user) # update admin users updated_users = [ { 'email': '*****@*****.**', 'attribute': 'value2' }, # update attribute { 'email': '*****@*****.**' }, # remove attribute # deleting [email protected] # should remove attributes but leave isAdmin ] s3_stubber.add_response('get_object', {'Body': StringIO(json.dumps(updated_users))}) load.load_user() users_in_db = user_table.scan_all() assert { 'email': '*****@*****.**', 'isAdmin': True, 'attribute': 'value2' } in users_in_db assert {'email': '*****@*****.**', 'isAdmin': True} in users_in_db assert {'email': '*****@*****.**', 'isAdmin': True} in users_in_db
def setup_user_spreadsheets_handler(event, context): """ Adds user emails to event/state so step functions can iterator over them to generate spreadsheets Expected input event format { "scanId": scan_id, } Returns { "scanId": scan_id, "userEmails": list of user's email addresses } """ # add usersEmails to event/state users = user_table.scan_all() event['userEmails'] = [user['email'] for user in users] # remove account numbers to keep payload size down event.pop('load', None) return event