def test_notify_whitelist_change(self): old_sig = Signature() new_sig = Signature() new_sig.set_signature_reference_name('Company') new_sig.set_signature_project_id('projectID') cla_manager = CLAUser({'name': 'CLA Manager'}) old_sig.set_domain_whitelist(['a.com', 'b.com']) new_sig.set_domain_whitelist(['b.com', 'd.com']) old_sig.set_github_whitelist([]) new_sig.set_github_whitelist(['githubuser']) old_sig.set_email_whitelist(['*****@*****.**']) new_sig.set_email_whitelist([]) old_sig.set_github_org_whitelist(['githuborg']) new_sig.set_github_org_whitelist(['githuborg']) snsClient = MockSNS() cla.controllers.signature.get_email_service = Mock() cla.controllers.signature.get_email_service.return_value = snsClient new_sig.get_managers = Mock(side_effect=mock_get_managers) cla.models.dynamo_models.Project.load = Mock(side_effect=mock_project) cla.models.dynamo_models.Project.get_project_name = Mock() cla.models.dynamo_models.Project.get_project_name.return_value = 'Project' cla.models.dynamo_models.User.get_user_by_github_username = Mock( side_effect=mock_get_user_by_github_username) notify_whitelist_change(cla_manager, old_sig, new_sig) self.assertEqual(len(snsClient.emails_sent), 3) # check email to cla manager msg = snsClient.emails_sent[0] msg = json.loads(msg) self.assertEqual(msg['data']['subject'], 'EasyCLA: Allow List Update for Project') self.assertEqual(msg['data']['recipients'], ['*****@*****.**', '*****@*****.**']) body = msg['data']['body'] self.assertIn('a.com', body) self.assertNotIn('b.com', body) self.assertIn('d.com', body) self.assertIn('githubuser', body) self.assertIn('*****@*****.**', body) self.assertNotIn('githuborg', body) # check email sent to contributor - removed email msg = snsClient.emails_sent[1] msg = json.loads(msg) self.assertEqual(msg['data']['subject'], 'EasyCLA: Allow List Update for Project') self.assertEqual(msg['data']['recipients'], ['*****@*****.**']) body = msg['data']['body'] self.assertIn('deleted', body) self.assertIn('Company', body) self.assertIn('Project', body) self.assertIn('CLA Manager', body) # check email sent to contributor - added github user msg = snsClient.emails_sent[2] msg = json.loads(msg) self.assertEqual(msg['data']['subject'], 'EasyCLA: Allow List Update for Project') self.assertEqual(msg['data']['recipients'], ['*****@*****.**']) body = msg['data']['body'] self.assertIn('added', body) self.assertIn('Company', body) self.assertIn('Project', body) self.assertIn('CLA Manager', body)
def update_signature( signature_id, # pylint: disable=too-many-arguments,too-many-return-statements,too-many-branches auth_user, signature_project_id=None, signature_reference_id=None, signature_reference_type=None, signature_type=None, signature_approved=None, signature_signed=None, signature_return_url=None, signature_sign_url=None, domain_whitelist=None, email_whitelist=None, github_whitelist=None, github_org_whitelist=None): """ Updates an signature and returns the newly updated signature in dict format. A value of None means the field should not be updated. :param signature_id: ID of the signature. :type signature_id: ID | None :param auth_user: the authenticated user :type auth_user: string :param signature_project_id: Project ID for this signature. :type signature_project_id: string | None :param signature_reference_id: Reference ID for this signature. :type signature_reference_id: string | None :param signature_reference_type: Reference type for this signature. :type signature_reference_type: ['user' | 'company'] | None :param signature_type: New signature type ('cla' or 'dco'). :type signature_type: string | None :param signature_signed: Whether this signature is signed or not. :type signature_signed: boolean | None :param signature_approved: Whether this signature is approved or not. :type signature_approved: boolean | None :param signature_return_url: The URL the user will be sent to after signing. :type signature_return_url: string | None :param signature_sign_url: The URL the user must visit to sign the signature. :type signature_sign_url: string | None :param domain_whitelist: the domain whitelist :param email_whitelist: the email whitelist :param github_whitelist: the github username whitelist :param github_org_whitelist: the github org whitelist :return: dict representation of the signature object. :rtype: dict """ fn = 'controllers.signature.update_signature' cla.log.debug(f'{fn} - loading signature by id: {str(signature_id)}') signature = Signature() try: # Try to load the signature to update. signature.load(str(signature_id)) old_signature = copy.deepcopy(signature) except DoesNotExist as err: return {'errors': {'signature_id': str(err)}} update_str = f'signature {signature_id} updates: \n ' if signature_project_id is not None: # make a note if the project id is set and doesn't match if signature.get_signature_project_id() != str(signature_project_id): cla.log.warning( f'{fn} - project IDs do not match => ' f'record project id: {signature.get_signature_project_id()} != ' f'parameter project id: {str(signature_project_id)}') try: signature.set_signature_project_id(str(signature_project_id)) update_str += f'signature_project_id updated to {signature_project_id} \n' except DoesNotExist as err: return {'errors': {'signature_project_id': str(err)}} # TODO: Ensure signature_reference_id exists. if signature_reference_id is not None: if signature.get_signature_reference_id() != str( signature_reference_id): cla.log.warning( f'{fn} - signature reference IDs do not match => ' f'record signature ref id: {signature.get_signature_reference_id()} != ' f'parameter signature ref id: {str(signature_reference_id)}') signature.set_signature_reference_id(signature_reference_id) if signature_reference_type is not None: signature.set_signature_reference_type(signature_reference_type) update_str += f'signature_reference_type updated to {signature_reference_type} \n' if signature_type is not None: if signature_type in ['cla', 'dco']: signature.set_signature_type(signature_type) update_str += f'signature_type updated to {signature_type} \n' else: return { 'errors': { 'signature_type': 'Invalid value passed. The accepted values are: (cla|dco)' } } if signature_signed is not None: try: val = hug.types.smart_boolean(signature_signed) signature.set_signature_signed(val) update_str += f'signature_signed updated to {signature_signed} \n' except KeyError: return { 'errors': { 'signature_signed': 'Invalid value passed in for true/false field' } } if signature_approved is not None: try: val = hug.types.smart_boolean(signature_approved) update_signature_approved(signature, val) update_str += f'signature_approved updated to {val} \n' except KeyError: return { 'errors': { 'signature_approved': 'Invalid value passed in for true/false field' } } if signature_return_url is not None: try: val = cla.hug_types.url(signature_return_url) signature.set_signature_return_url(val) update_str += f'signature_return_url updated to {val} \n' except KeyError: return { 'errors': { 'signature_return_url': 'Invalid value passed in for URL field' } } if signature_sign_url is not None: try: val = cla.hug_types.url(signature_sign_url) signature.set_signature_sign_url(val) update_str += f'signature_sign_url updated to {val} \n' except KeyError: return { 'errors': { 'signature_sign_url': 'Invalid value passed in for URL field' } } if domain_whitelist is not None: try: domain_whitelist = hug.types.multiple(domain_whitelist) signature.set_domain_whitelist(domain_whitelist) update_str += f'domain_whitelist updated to {domain_whitelist} \n' except KeyError: return { 'errors': { 'domain_whitelist': 'Invalid value passed in for the domain whitelist' } } if email_whitelist is not None: try: email_whitelist = hug.types.multiple(email_whitelist) signature.set_email_whitelist(email_whitelist) update_str += f'email_whitelist updated to {email_whitelist} \n' except KeyError: return { 'errors': { 'email_whitelist': 'Invalid value passed in for the email whitelist' } } if github_whitelist is not None: try: github_whitelist = hug.types.multiple(github_whitelist) signature.set_github_whitelist(github_whitelist) # A little bit of special logic to for GitHub whitelists that have bots bot_list = [ github_user for github_user in github_whitelist if is_github_bot(github_user) ] if bot_list is not None: handle_bots(bot_list, signature) update_str += f'github_whitelist updated to {github_whitelist} \n' except KeyError: return { 'errors': { 'github_whitelist': 'Invalid value passed in for the github whitelist' } } if github_org_whitelist is not None: try: github_org_whitelist = hug.types.multiple(github_org_whitelist) signature.set_github_org_whitelist(github_org_whitelist) update_str += f'github_org_whitelist updated to {github_org_whitelist} \n' except KeyError: return { 'errors': { 'github_org_whitelist': 'Invalid value passed in for the github org whitelist' } } event_data = update_str Event.create_event( event_data=event_data, event_summary=event_data, event_type=EventType.UpdateSignature, contains_pii=True, ) signature.save() notify_whitelist_change(auth_user=auth_user, old_signature=old_signature, new_signature=signature) return signature.to_dict()
def update_signature( signature_id, # pylint: disable=too-many-arguments,too-many-return-statements,too-many-branches signature_project_id=None, signature_reference_id=None, signature_reference_type=None, signature_type=None, signature_approved=None, signature_signed=None, signature_return_url=None, signature_sign_url=None, domain_whitelist=None, email_whitelist=None, github_whitelist=None, github_org_whitelist=None): """ Updates an signature and returns the newly updated signature in dict format. A value of None means the field should not be updated. :param signature_id: ID of the signature. :type signature_id: ID | None :param signature_project_id: Project ID for this signature. :type signature_project_id: string | None :param signature_reference_id: Reference ID for this signature. :type signature_reference_id: string | None :param signature_reference_type: Reference type for this signature. :type signature_reference_type: ['user' | 'company'] | None :param signature_type: New signature type ('cla' or 'dco'). :type signature_type: string | None :param signature_signed: Whether this signature is signed or not. :type signature_signed: boolean | None :param signature_approved: Whether this signature is approved or not. :type signature_approved: boolean | None :param signature_return_url: The URL the user will be sent to after signing. :type signature_return_url: string | None :param signature_sign_url: The URL the user must visit to sign the signature. :type signature_sign_url: string | None :param domain_whitelist: the domain whitelist :param email_whitelist: the email whitelist :param github_whitelist: the github username whitelist :param github_org_whitelist: the github org whitelist :return: dict representation of the signature object. :rtype: dict """ signature = Signature() try: # Try to load the signature to update. signature.load(str(signature_id)) except DoesNotExist as err: return {'errors': {'signature_id': str(err)}} if signature_project_id is not None: # make a note if the project id is set and doesn't match if signature.get_signature_project_id() != str(signature_project_id): cla.log.warning( 'update_signature() - project IDs do not match => ' f'record project id: {signature.get_signature_project_id()} != ' f'parameter project id: {str(signature_project_id)}') try: signature.set_signature_project_id(str(signature_project_id)) except DoesNotExist as err: return {'errors': {'signature_project_id': str(err)}} # TODO: Ensure signature_reference_id exists. if signature_reference_id is not None: if signature.get_signature_reference_id() != str( signature_reference_id): cla.log.warning( 'update_signature() - signature reference IDs do not match => ' f'record signature ref id: {signature.get_signature_reference_id()} != ' f'parameter signature ref id: {str(signature_reference_id)}') signature.set_signature_reference_id(signature_reference_id) if signature_reference_type is not None: signature.set_signature_reference_type(signature_reference_type) if signature_type is not None: if signature_type in ['cla', 'dco']: signature.set_signature_type(signature_type) else: return { 'errors': { 'signature_type': 'Invalid value passed. The accepted values are: (cla|dco)' } } if signature_signed is not None: try: val = hug.types.smart_boolean(signature_signed) signature.set_signature_signed(val) except KeyError as err: return { 'errors': { 'signature_signed': 'Invalid value passed in for true/false field' } } if signature_approved is not None: try: val = hug.types.smart_boolean(signature_approved) update_signature_approved(signature, val) except KeyError as err: return { 'errors': { 'signature_approved': 'Invalid value passed in for true/false field' } } if signature_return_url is not None: try: val = cla.hug_types.url(signature_return_url) signature.set_signature_return_url(val) except KeyError as err: return { 'errors': { 'signature_return_url': 'Invalid value passed in for URL field' } } if signature_sign_url is not None: try: val = cla.hug_types.url(signature_sign_url) signature.set_signature_sign_url(val) except KeyError as err: return { 'errors': { 'signature_sign_url': 'Invalid value passed in for URL field' } } if domain_whitelist is not None: try: domain_whitelist = hug.types.multiple(domain_whitelist) signature.set_domain_whitelist(domain_whitelist) except KeyError as err: return { 'errors': { 'domain_whitelist': 'Invalid value passed in for the domain whitelist' } } if email_whitelist is not None: try: email_whitelist = hug.types.multiple(email_whitelist) signature.set_email_whitelist(email_whitelist) except KeyError as err: return { 'errors': { 'email_whitelist': 'Invalid value passed in for the email whitelist' } } if github_whitelist is not None: try: github_whitelist = hug.types.multiple(github_whitelist) signature.set_github_whitelist(github_whitelist) # A little bit of special logic to for GitHub whitelists that have bots bot_list = [ github_user for github_user in github_whitelist if is_github_bot(github_user) ] if bot_list is not None: handle_bots(bot_list, signature) except KeyError as err: return { 'errors': { 'github_whitelist': 'Invalid value passed in for the github whitelist' } } if github_org_whitelist is not None: try: github_org_whitelist = hug.types.multiple(github_org_whitelist) signature.set_github_org_whitelist(github_org_whitelist) except KeyError as err: return { 'errors': { 'github_org_whitelist': 'Invalid value passed in for the github org whitelist' } } signature.save() return signature.to_dict()