class TestProjectRegistrationProvider(object): def setUp(self): self.provider = ProjectRegistrationProvider() @patch('allura.lib.security.has_access') def test_validate_project_15char_user(self, has_access): has_access.return_value = TruthyCallable(lambda: True) nbhd = M.Neighborhood() self.provider.validate_project( neighborhood=nbhd, shortname='u/' + ('a' * 15), project_name='15 char username', user=MagicMock(), user_project=True, private_project=False, ) @patch('allura.model.Project') def test_shortname_validator(self, Project): Project.query.get.return_value = None nbhd = Mock() v = self.provider.shortname_validator.to_python v('thisislegit', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'not valid', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'this-is-valid-but-too-long', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'this is invalid and too long', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'end-dash-', neighborhood=nbhd) Project.query.get.return_value = Mock() assert_raises(ProjectConflict, v, 'thisislegit', neighborhood=nbhd)
def test_validate_project_15char_user(self, has_access): has_access.return_value = TruthyCallable(lambda: True) provider = ProjectRegistrationProvider() nbhd = M.Neighborhood() provider.validate_project( neighborhood=nbhd, shortname='u/' + ('a' * 15), project_name='15 char username', user=MagicMock(), user_project=True, private_project=False, )
class TestProjectRegistrationProvider(object): def setUp(self): self.provider = ProjectRegistrationProvider() @patch('allura.lib.security.has_access') def test_validate_project_15char_user(self, has_access): has_access.return_value = TruthyCallable(lambda: True) nbhd = M.Neighborhood() self.provider.validate_project( neighborhood=nbhd, shortname='u/' + ('a' * 15), project_name='15 char username', user=MagicMock(), user_project=True, private_project=False, ) def test_suggest_name(self): f = self.provider.suggest_name assert_equals(f('A More Than Fifteen Character Name', Mock()), 'amorethanfifteencharactername') def test_valid_project_shortname(self): f = self.provider.valid_project_shortname p = Mock() valid = (True, None) invalid = (False, 'Please use only letters, numbers, and dashes ' '3-15 characters long.') assert_equals(f('thisislegit', p), valid) assert_equals(f('not valid', p), invalid) assert_equals(f('this-is-valid-but-too-long', p), invalid) assert_equals(f('this is invalid and too long', p), invalid) def test_allowed_project_shortname(self): allowed = valid = (True, None) invalid = (False, 'invalid') taken = (False, 'This project name is taken.') cases = [ (valid, False, allowed), (invalid, False, invalid), (valid, True, taken), ] p = Mock() vps = self.provider.valid_project_shortname = Mock() nt = self.provider._name_taken = Mock() f = self.provider.allowed_project_shortname for vps_v, nt_v, result in cases: vps.return_value = vps_v nt.return_value = nt_v assert_equals(f('project', p), result)
def execute(cls, options): provider = ProjectRegistrationProvider.get() for proj in options.projects: proj = cls.get_project(proj) if proj: log.info('Purging %s%s. Reason: %s', proj.neighborhood.url_prefix, proj.shortname, options.reason) provider.purge_project(proj, disable_users=options.disable_users, reason=options.reason)
def search_projects(self, q=None, f=None, page=0, limit=None, **kw): fields = [('shortname', 'shortname'), ('name', 'full name')] add_fields = aslist(tg.config.get('search.project.additional_search_fields'), ',') r = self._search(M.Project, fields, add_fields, q, f, page, limit, **kw) r['search_results_template'] = 'allura:templates/site_admin_search_projects_results.html' r['additional_display_fields'] = \ aslist(tg.config.get('search.project.additional_display_fields'), ',') r['provider'] = ProjectRegistrationProvider.get() return r
class TestProjectRegistrationProvider(object): def setUp(self): self.provider = ProjectRegistrationProvider() @patch('allura.lib.security.has_access') def test_validate_project_15char_user(self, has_access): has_access.return_value = TruthyCallable(lambda: True) nbhd = M.Neighborhood() self.provider.validate_project( neighborhood=nbhd, shortname='u/' + ('a' * 15), project_name='15 char username', user=MagicMock(), user_project=True, private_project=False, ) def test_suggest_name(self): f = self.provider.suggest_name assert_equals(f('Foo Bar', Mock()), 'foo-bar') assert_equals(f('A More Than Fifteen Character Name', Mock()), 'a-more-than-fifteen-character-name') assert_equals(f('foo! bar?.. the great!!', Mock()), 'foo-bar-the-great') @patch('allura.model.Project') def test_shortname_validator(self, Project): Project.query.get.return_value = None nbhd = Mock() v = self.provider.shortname_validator.to_python v('thisislegit', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'not valid', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'this-is-valid-but-too-long', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'this is invalid and too long', neighborhood=nbhd) assert_raises(ProjectShortnameInvalid, v, 'end-dash-', neighborhood=nbhd) Project.query.get.return_value = Mock() assert_raises(ProjectConflict, v, 'thisislegit', neighborhood=nbhd)
def parse_projects(self, projects): """Takes projects from user input and returns a list of tuples (input, project, error)""" provider = ProjectRegistrationProvider.get() projects = projects.splitlines() projects = self.remove_comments(projects) parsed_projects = [] for input in projects: if input.strip(): p, error = provider.project_from_url(input.strip()) parsed_projects.append((input, p, error)) return parsed_projects
def search_projects(self, q=None, f=None, page=0, limit=None, **kw): fields = [('shortname', 'shortname'), ('name', 'full name')] add_fields = aslist( tg.config.get('search.project.additional_search_fields'), ',') r = self._search(M.Project, fields, add_fields, q, f, page, limit, **kw) r['search_results_template'] = 'allura:templates/site_admin_search_projects_results.html' r['additional_display_fields'] = \ aslist(tg.config.get('search.project.additional_display_fields'), ',') r['provider'] = ProjectRegistrationProvider.get() return r
def deserialize_project(datum, projectSchema, nbhd): # type: (dict, NewProjectSchema, Neighborhood) -> object p = projectSchema.deserialize(datum) p = Object(p) # convert from dict to something with attr-access # generate a shortname, and try to make it unique if not p.shortname: max_shortname_len = 15 # maybe more depending on NeighborhoodProjectShortNameValidator impl, but this is safe shortname = orig_shortname = make_shortname(p.name, max_shortname_len) for i in range(1, 10): try: ProjectRegistrationProvider.get( ).shortname_validator.to_python(shortname, neighborhood=nbhd) except formencode.api.Invalid: if len(orig_shortname) == max_shortname_len - 1: shortname = orig_shortname + str(i) else: shortname = orig_shortname[:max_shortname_len - 1] + str(i) else: # we're good! break p.shortname = shortname return p
def execute(cls, options): provider = ProjectRegistrationProvider.get() auth_provider = AuthenticationProvider.get(Request.blank('/')) for proj in options.projects: proj = cls.get_project(proj) if proj: if proj.is_user_project: # disable user as well user = proj.user_project_of if user: auth_provider.disable_user(user, audit=False) msg = u'Account disabled because user-project was specified for deletion. Reason: {}'.format( options.reason) log_entry = h.auditlog_user(msg, user=user) session(log_entry).flush(log_entry) else: log.info('Could not find associated user for user-project %s', proj.shortname) log.info('Purging %s Reason: %s', proj.url(), options.reason) provider.purge_project(proj, disable_users=options.disable_users, reason=options.reason)
def execute(cls, options): provider = ProjectRegistrationProvider.get() auth_provider = AuthenticationProvider.get(Request.blank('/')) for proj in options.projects: proj = cls.get_project(proj) if proj: if proj.is_user_project: # disable user as well user = proj.user_project_of if user: auth_provider.disable_user(user, audit=False) msg = u'Account disabled because user-project was specified for deletion. Reason: {}'.format( options.reason) log_entry = h.auditlog_user(msg, user=user) session(log_entry).flush(log_entry) else: log.info( 'Could not find associated user for user-project %s', proj.shortname) log.info('Purging %s Reason: %s', proj.url(), options.reason) provider.purge_project(proj, disable_users=options.disable_users, reason=options.reason)
def __init__(self, source): super(ProjectImportForm, self).__init__() provider = ProjectRegistrationProvider.get() self.add_field('tools', ToolsValidator(source)) self.add_field('project_shortname', provider.shortname_validator) self.allow_extra_fields = True
def setUp(self): setup_basic_test() ThreadLocalORMSession.close_all() setup_global_objects() self.provider = ProjectRegistrationProvider() self.parse = self.provider.project_from_url
def setUp(self): self.provider = ProjectRegistrationProvider()
def deserialize(self, node, cstruct): if cstruct is col.null: return col.null return ProjectRegistrationProvider.get().shortname_validator.to_python(cstruct, check_allowed=not self.update, neighborhood=self.nbhd)
def setUp(self): self.p = ProjectRegistrationProvider() self.user = UserMock() self.nbhd = MagicMock()
class TestProjectRegistrationProviderPhoneVerification(object): def setUp(self): self.p = ProjectRegistrationProvider() self.user = UserMock() self.nbhd = MagicMock() def test_phone_verified_disabled(self): with h.push_config(tg.config, **{'project.verify_phone': 'false'}): assert_true(self.p.phone_verified(self.user, self.nbhd)) @patch.object(plugin.security, 'has_access', autospec=True) def test_phone_verified_admin(self, has_access): has_access.return_value.return_value = True with h.push_config(tg.config, **{'project.verify_phone': 'true'}): assert_true(self.p.phone_verified(self.user, self.nbhd)) @patch.object(plugin.security, 'has_access', autospec=True) def test_phone_verified_project_admin(self, has_access): has_access.return_value.return_value = False with h.push_config(tg.config, **{'project.verify_phone': 'true'}): self.user.set_projects([Mock()]) assert_false(self.p.phone_verified(self.user, self.nbhd)) self.user.set_projects([Mock(neighborhood_id=self.nbhd._id)]) assert_true(self.p.phone_verified(self.user, self.nbhd)) @patch.object(plugin.security, 'has_access', autospec=True) def test_phone_verified(self, has_access): has_access.return_value.return_value = False with h.push_config(tg.config, **{'project.verify_phone': 'true'}): assert_false(self.p.phone_verified(self.user, self.nbhd)) self.user.set_tool_data('phone_verification', number_hash='123') assert_true(self.p.phone_verified(self.user, self.nbhd)) @patch.object(plugin, 'g') def test_verify_phone_disabled(self, g): g.phone_service = Mock(spec=phone.PhoneService) with h.push_config(tg.config, **{'project.verify_phone': 'false'}): result = self.p.verify_phone(self.user, '12345') assert_false(g.phone_service.verify.called) assert_equal(result, {'status': 'ok'}) @patch.object(plugin, 'g') def test_verify_phone(self, g): g.phone_service = Mock(spec=phone.PhoneService) with h.push_config(tg.config, **{'project.verify_phone': 'true'}): result = self.p.verify_phone(self.user, '123 45 45') g.phone_service.verify.assert_called_once_with('1234545') assert_equal(result, g.phone_service.verify.return_value) @patch.object(plugin, 'g') def test_check_phone_verification_disabled(self, g): g.phone_service = Mock(spec=phone.PhoneService) with h.push_config(tg.config, **{'project.verify_phone': 'false'}): result = self.p.check_phone_verification( self.user, 'request-id', '1111', 'hash') assert_false(g.phone_service.check.called) assert_equal(result, {'status': 'ok'}) @patch.object(plugin.h, 'auditlog_user', autospec=True) @patch.object(plugin, 'g') def test_check_phone_verification_fail(self, g, audit): g.phone_service = Mock(spec=phone.PhoneService) with h.push_config(tg.config, **{'project.verify_phone': 'true'}): result = self.p.check_phone_verification( self.user, 'request-id', '1111', 'hash') g.phone_service.check.assert_called_once_with( 'request-id', '1111') assert_equal(result, g.phone_service.check.return_value) assert_equal( self.user.get_tool_data('phone_verification', 'number_hash'), None) audit.assert_called_once_with( 'Phone verification failed. Hash: hash', user=self.user) @patch.object(plugin.h, 'auditlog_user', autospec=True) @patch.object(plugin, 'g') def test_check_phone_verification_success(self, g, audit): g.phone_service = Mock(spec=phone.PhoneService) with h.push_config(tg.config, **{'project.verify_phone': 'true'}): g.phone_service.check.return_value = {'status': 'ok'} result = self.p.check_phone_verification( self.user, 'request-id', '1111', 'hash') g.phone_service.check.assert_called_once_with( 'request-id', '1111') assert_equal( self.user.get_tool_data('phone_verification', 'number_hash'), 'hash') audit.assert_called_once_with( 'Phone verification succeeded. Hash: hash', user=self.user)