class TestBaseBackend(BaseACLTest): """ Tests for the access backend interface """ def setUp(self): super(TestBaseBackend, self).setUp() self.backend = IAccessBackend(self.request) patch.object(self.backend, 'verify_user').start() patch.object(self.backend, 'groups').start() patch.object(self.backend, 'is_admin').start() patch.object(self.backend, 'group_permissions').start() patch.object(self.backend, 'user_permissions').start() self.request.access = self.backend def tearDown(self): super(TestBaseBackend, self).tearDown() patch.stopall() def test_root_acl(self): """ Root ACL sets login, admin, and DENY ALL """ root = Root(self.request) self.assert_allowed(root, 'login', ['admin', Authenticated]) self.assert_allowed(root, 'admin', ['admin']) self.assert_allowed(root, 'arbitrary', ['admin']) def test_user_rw(self): """ Owner always has rw perms on a package """ self.backend.user_permissions.return_value = { 'dsa': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', ['user:dsa']) self.assert_allowed(acl, 'write', ['user:dsa']) def test_group_everyone(self): """ Special 'everyone' group sets perms for everyone """ self.backend.group_permissions.return_value = { 'everyone': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', [Everyone]) self.assert_allowed(acl, 'write', [Everyone]) def test_group_authenticated(self): """ Special 'authenticated' group sets perms for logged-in users """ self.backend.group_permissions.return_value = { 'authenticated': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', [Authenticated]) self.assert_allowed(acl, 'write', [Authenticated]) def test_group(self): """ Groups set perms for a 'group:<>' principal """ self.backend.group_permissions.return_value = { 'brotatos': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', ['group:brotatos']) self.assert_allowed(acl, 'write', ['group:brotatos']) def test_abstract_methods(self): """ Abstract methods raise NotImplementedError """ access = IMutableAccessBackend(None) with self.assertRaises(NotImplementedError): access.verify_user('a', 'b') with self.assertRaises(NotImplementedError): access.groups() with self.assertRaises(NotImplementedError): access.group_members('a') with self.assertRaises(NotImplementedError): access.is_admin('a') with self.assertRaises(NotImplementedError): access.group_permissions('a') with self.assertRaises(NotImplementedError): access.user_permissions('a') with self.assertRaises(NotImplementedError): access.user_package_permissions('a') with self.assertRaises(NotImplementedError): access.group_package_permissions('a') with self.assertRaises(NotImplementedError): access.user_data() with self.assertRaises(NotImplementedError): access.allow_register() with self.assertRaises(NotImplementedError): access.set_allow_register(True) with self.assertRaises(NotImplementedError): access.register('a', 'b') with self.assertRaises(NotImplementedError): access.pending_users() with self.assertRaises(NotImplementedError): access.approve_user('a') with self.assertRaises(NotImplementedError): access.edit_user_password('a', 'b') with self.assertRaises(NotImplementedError): access.delete_user('a') with self.assertRaises(NotImplementedError): access.set_user_admin('a', True) with self.assertRaises(NotImplementedError): access.edit_user_group('a', 'a', 'add') with self.assertRaises(NotImplementedError): access.create_group('a') with self.assertRaises(NotImplementedError): access.delete_group('a') with self.assertRaises(NotImplementedError): access.edit_user_permission('a', 'b', 'c', True) with self.assertRaises(NotImplementedError): access.edit_group_permission('a', 'b', 'c', True) def test_need_admin(self): """ need_admin is True if no admins """ access = IMutableAccessBackend(None) with patch.object(access, 'user_data') as user_data: user_data.return_value = [{'admin': False}] self.assertTrue(access.need_admin()) def test_no_need_admin(self): """ need_admin is False if 1+ admins """ access = IMutableAccessBackend(None) with patch.object(access, 'user_data') as user_data: user_data.return_value = [{'admin': False}, {'admin': True}] self.assertFalse(access.need_admin()) def test_load_remote_backend(self): """ keyword 'remote' loads RemoteBackend """ config = MagicMock() config.get_settings.return_value = { 'pypi.access_backend': 'remote', 'auth.backend_server': 'http://example.com', } includeme(config) config.add_request_method.assert_called_with(RemoteAccessBackend, name='access', reify=True) def test_load_sql_backend(self): """ keyword 'sql' loads SQLBackend """ config = MagicMock() config.get_settings.return_value = { 'auth.db.url': 'sqlite:///:memory:', 'pypi.access_backend': 'sql', } includeme(config) config.add_request_method.assert_called_with(SQLAccessBackend, name='access', reify=True) def test_load_arbitrary_backend(self): """ Can pass dotted path to load arbirary backend """ config = MagicMock() config.get_settings.return_value = { 'auth.db.url': 'sqlite:///:memory:', 'pypi.access_backend': 'pypicloud.access.sql.SQLAccessBackend', } includeme(config) config.add_request_method.assert_called_with(SQLAccessBackend, name='access', reify=True) def test_admin_permissions(self): """ Admins always have read/write permissions """ access = IAccessBackend(None) perms = access.principal_permissions('p1', 'admin') self.assertEqual(perms, ['read', 'write']) def test_everyone_permissions(self): """ Everyone gets converted to 'everyone' """ access = IAccessBackend(None) with patch.object(access, 'group_permissions') as grp: perms = access.principal_permissions('p1', Everyone) grp.assert_called_with('p1', 'everyone') self.assertEqual(perms, grp()) def test_authenticated_permissions(self): """ Authenticated gets converted to 'authenticated' """ access = IAccessBackend(None) with patch.object(access, 'group_permissions') as grp: perms = access.principal_permissions('p1', Authenticated) grp.assert_called_with('p1', 'authenticated') self.assertEqual(perms, grp()) def test_group_permissions(self): """ 'group:name' specifier gets turned into 'group' """ access = IAccessBackend(None) with patch.object(access, 'group_permissions') as grp: perms = access.principal_permissions('p1', 'group:brotatos') grp.assert_called_with('p1', 'brotatos') self.assertEqual(perms, grp()) def test_admin_has_permission(self): """ Admins always have permission """ access = IAccessBackend(None) access.is_admin = lambda x: True with patch.object(pypicloud.access, 'unauthenticated_userid') as userid: userid.return_value = 'abc' self.assertTrue(access.has_permission('p1', 'write')) def test_admin_principal(self): """ Admin user has the 'admin' principal """ access = IAccessBackend(None) access.is_admin = lambda x: True with patch.object(access, 'groups') as groups: groups.return_value = ['brotatos'] principals = access.user_principals('abc') self.assertItemsEqual(principals, [Everyone, Authenticated, 'admin', 'group:brotatos', 'user:abc'])
class TestBaseBackend(BaseACLTest): """ Tests for the access backend interface """ def setUp(self): super(TestBaseBackend, self).setUp() self.backend = IAccessBackend(self.request) patch.object(self.backend, 'verify_user').start() patch.object(self.backend, 'groups').start() patch.object(self.backend, 'is_admin').start() patch.object(self.backend, 'group_permissions').start() patch.object(self.backend, 'user_permissions').start() self.request.access = self.backend def tearDown(self): super(TestBaseBackend, self).tearDown() patch.stopall() def test_root_acl(self): """ Root ACL sets login, admin, and DENY ALL """ root = Root(self.request) self.assert_allowed(root, 'login', ['admin', Authenticated]) self.assert_allowed(root, 'admin', ['admin']) self.assert_allowed(root, 'arbitrary', ['admin']) def test_user_rw(self): """ Owner always has rw perms on a package """ self.backend.user_permissions.return_value = { 'dsa': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', ['user:dsa']) self.assert_allowed(acl, 'write', ['user:dsa']) def test_group_everyone(self): """ Special 'everyone' group sets perms for everyone """ self.backend.group_permissions.return_value = { 'everyone': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', [Everyone]) self.assert_allowed(acl, 'write', [Everyone]) def test_group_authenticated(self): """ Special 'authenticated' group sets perms for logged-in users """ self.backend.group_permissions.return_value = { 'authenticated': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', [Authenticated]) self.assert_allowed(acl, 'write', [Authenticated]) def test_group(self): """ Groups set perms for a 'group:<>' principal """ self.backend.group_permissions.return_value = { 'brotatos': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', ['group:brotatos']) self.assert_allowed(acl, 'write', ['group:brotatos']) def test_abstract_methods(self): """ Abstract methods raise NotImplementedError """ access = IMutableAccessBackend(None, pwd_context=get_pwd_context()) with self.assertRaises(NotImplementedError): access.verify_user('a', 'b') with self.assertRaises(NotImplementedError): access.groups() with self.assertRaises(NotImplementedError): access.group_members('a') with self.assertRaises(NotImplementedError): access.is_admin('a') with self.assertRaises(NotImplementedError): access.group_permissions('a') with self.assertRaises(NotImplementedError): access.user_permissions('a') with self.assertRaises(NotImplementedError): access.user_package_permissions('a') with self.assertRaises(NotImplementedError): access.group_package_permissions('a') with self.assertRaises(NotImplementedError): access.user_data() with self.assertRaises(NotImplementedError): access.allow_register() with self.assertRaises(NotImplementedError): access.set_allow_register(True) with self.assertRaises(NotImplementedError): access.register('a', 'b') with self.assertRaises(NotImplementedError): access.pending_users() with self.assertRaises(NotImplementedError): access.approve_user('a') with self.assertRaises(NotImplementedError): access.edit_user_password('a', 'b') with self.assertRaises(NotImplementedError): access.delete_user('a') with self.assertRaises(NotImplementedError): access.set_user_admin('a', True) with self.assertRaises(NotImplementedError): access.edit_user_group('a', 'a', 'add') with self.assertRaises(NotImplementedError): access.create_group('a') with self.assertRaises(NotImplementedError): access.delete_group('a') with self.assertRaises(NotImplementedError): access.edit_user_permission('a', 'b', 'c', True) with self.assertRaises(NotImplementedError): access.edit_group_permission('a', 'b', 'c', True) def test_need_admin(self): """ need_admin is True if no admins """ access = IMutableAccessBackend(None) with patch.object(access, 'user_data') as user_data: user_data.return_value = [{'admin': False}] self.assertTrue(access.need_admin()) def test_no_need_admin(self): """ need_admin is False if 1+ admins """ access = IMutableAccessBackend(None) with patch.object(access, 'user_data') as user_data: user_data.return_value = [{'admin': False}, {'admin': True}] self.assertFalse(access.need_admin()) def test_load_remote_backend(self): """ keyword 'remote' loads RemoteBackend """ config = MagicMock() config.get_settings.return_value = { 'pypi.auth': 'remote', 'auth.backend_server': 'http://example.com', } includeme(config) config.add_request_method.assert_called_with( PartialEq(RemoteAccessBackend), name='access', reify=True) def test_load_sql_backend(self): """ keyword 'sql' loads SQLBackend """ config = MagicMock() config.get_settings.return_value = { 'auth.db.url': 'sqlite://', 'pypi.auth': 'sql', } includeme(config) config.add_request_method.assert_called_with( PartialEq(SQLAccessBackend), name='access', reify=True) def test_load_arbitrary_backend(self): """ Can pass dotted path to load arbirary backend """ config = MagicMock() config.get_settings.return_value = { 'auth.db.url': 'sqlite://', 'pypi.auth': 'pypicloud.access.sql.SQLAccessBackend', } includeme(config) config.add_request_method.assert_called_with( PartialEq(SQLAccessBackend), name='access', reify=True) def test_admin_has_permission(self): """ Admins always have permission """ self.request.userid = 'abc' access = IAccessBackend(self.request) access.is_admin = lambda x: True self.assertTrue(access.has_permission('p1', 'write')) def test_has_permission_default_read(self): """ If no user/group permissions on a package, use default_read """ self.backend.default_read = ['everyone', 'authenticated'] self.backend.default_write = [] perms = self.backend.allowed_permissions('anypkg') self.assertEqual(perms, { Everyone: ('read', ), Authenticated: ('read', ) }) def test_has_permission_default_write(self): """ If no user/group permissions on a package, use default_write """ self.backend.default_read = ['authenticated'] self.backend.default_write = ['authenticated'] perms = self.backend.allowed_permissions('anypkg') self.assertEqual(perms, {Authenticated: ('read', 'write')}) def test_admin_principal(self): """ Admin user has the 'admin' principal """ access = IAccessBackend(None) access.is_admin = lambda x: True with patch.object(access, 'groups') as groups: groups.return_value = ['brotatos'] principals = access.user_principals('abc') self.assertItemsEqual( principals, [Everyone, Authenticated, 'admin', 'group:brotatos', 'user:abc']) def test_load(self): """ Base backend has no default implementation for load() """ access = IAccessBackend(None) with self.assertRaises(TypeError): access.load({}) def test_hmac_validate(self): """ hmac will validate """ access = IMutableAccessBackend(signing_key='abc') user = '******' token = access.get_signup_token(user) self.assertEqual(user, access.validate_signup_token(token)) def test_hmac_expire(self): """ hmac will expire after a time """ access = IMutableAccessBackend(signing_key='abc', token_expiration=-10) user = '******' token = access.get_signup_token(user) self.assertIsNone(access.validate_signup_token(token)) def test_hmac_invalid(self): """ hmac will be invalid if mutated """ access = IMutableAccessBackend(signing_key='abc') user = '******' token = access.get_signup_token(user) self.assertIsNone(access.validate_signup_token(token + 'a'))
class TestBaseBackend(BaseACLTest): """ Tests for the access backend interface """ def setUp(self): super(TestBaseBackend, self).setUp() self.backend = IAccessBackend(self.request) patch.object(self.backend, 'verify_user').start() patch.object(self.backend, 'groups').start() patch.object(self.backend, 'is_admin').start() patch.object(self.backend, 'group_permissions').start() patch.object(self.backend, 'user_permissions').start() self.request.access = self.backend def tearDown(self): super(TestBaseBackend, self).tearDown() patch.stopall() def test_root_acl(self): """ Root ACL sets login, admin, and DENY ALL """ root = Root(self.request) self.assert_allowed(root, 'login', ['admin', Authenticated]) self.assert_allowed(root, 'admin', ['admin']) self.assert_allowed(root, 'arbitrary', ['admin']) def test_user_rw(self): """ Owner always has rw perms on a package """ self.backend.user_permissions.return_value = { 'dsa': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', ['user:dsa']) self.assert_allowed(acl, 'write', ['user:dsa']) def test_group_everyone(self): """ Special 'everyone' group sets perms for everyone """ self.backend.group_permissions.return_value = { 'everyone': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', [Everyone]) self.assert_allowed(acl, 'write', [Everyone]) def test_group_authenticated(self): """ Special 'authenticated' group sets perms for logged-in users """ self.backend.group_permissions.return_value = { 'authenticated': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', [Authenticated]) self.assert_allowed(acl, 'write', [Authenticated]) def test_group(self): """ Groups set perms for a 'group:<>' principal """ self.backend.group_permissions.return_value = { 'brotatos': ['read', 'write'], } acl = self.backend.get_acl('mypkg') self.assert_allowed(acl, 'read', ['group:brotatos']) self.assert_allowed(acl, 'write', ['group:brotatos']) def test_abstract_methods(self): """ Abstract methods raise NotImplementedError """ access = IMutableAccessBackend(None) with self.assertRaises(NotImplementedError): access.verify_user('a', 'b') with self.assertRaises(NotImplementedError): access.groups() with self.assertRaises(NotImplementedError): access.group_members('a') with self.assertRaises(NotImplementedError): access.is_admin('a') with self.assertRaises(NotImplementedError): access.group_permissions('a') with self.assertRaises(NotImplementedError): access.user_permissions('a') with self.assertRaises(NotImplementedError): access.user_package_permissions('a') with self.assertRaises(NotImplementedError): access.group_package_permissions('a') with self.assertRaises(NotImplementedError): access.user_data() with self.assertRaises(NotImplementedError): access.allow_register() with self.assertRaises(NotImplementedError): access.set_allow_register(True) with self.assertRaises(NotImplementedError): access.register('a', 'b') with self.assertRaises(NotImplementedError): access.pending_users() with self.assertRaises(NotImplementedError): access.approve_user('a') with self.assertRaises(NotImplementedError): access.edit_user_password('a', 'b') with self.assertRaises(NotImplementedError): access.delete_user('a') with self.assertRaises(NotImplementedError): access.set_user_admin('a', True) with self.assertRaises(NotImplementedError): access.edit_user_group('a', 'a', 'add') with self.assertRaises(NotImplementedError): access.create_group('a') with self.assertRaises(NotImplementedError): access.delete_group('a') with self.assertRaises(NotImplementedError): access.edit_user_permission('a', 'b', 'c', True) with self.assertRaises(NotImplementedError): access.edit_group_permission('a', 'b', 'c', True) def test_need_admin(self): """ need_admin is True if no admins """ access = IMutableAccessBackend(None) with patch.object(access, 'user_data') as user_data: user_data.return_value = [{'admin': False}] self.assertTrue(access.need_admin()) def test_no_need_admin(self): """ need_admin is False if 1+ admins """ access = IMutableAccessBackend(None) with patch.object(access, 'user_data') as user_data: user_data.return_value = [{'admin': False}, {'admin': True}] self.assertFalse(access.need_admin()) def test_load_remote_backend(self): """ keyword 'remote' loads RemoteBackend """ config = MagicMock() config.get_settings.return_value = { 'pypi.access_backend': 'remote', 'auth.backend_server': 'http://example.com', } includeme(config) config.add_request_method.assert_called_with( PartialEq(RemoteAccessBackend), name='access', reify=True) def test_load_sql_backend(self): """ keyword 'sql' loads SQLBackend """ config = MagicMock() config.get_settings.return_value = { 'auth.db.url': 'sqlite:///:memory:', 'pypi.access_backend': 'sql', } includeme(config) config.add_request_method.assert_called_with( PartialEq(SQLAccessBackend), name='access', reify=True) def test_load_arbitrary_backend(self): """ Can pass dotted path to load arbirary backend """ config = MagicMock() config.get_settings.return_value = { 'auth.db.url': 'sqlite:///:memory:', 'pypi.access_backend': 'pypicloud.access.sql.SQLAccessBackend', } includeme(config) config.add_request_method.assert_called_with( PartialEq(SQLAccessBackend), name='access', reify=True) def test_admin_has_permission(self): """ Admins always have permission """ self.request.userid = 'abc' access = IAccessBackend(self.request) access.is_admin = lambda x: True self.assertTrue(access.has_permission('p1', 'write')) def test_has_permission_default_read(self): """ If no user/group permissions on a package, use default_read """ self.backend.default_read = ['everyone', 'authenticated'] self.backend.default_write = [] perms = self.backend.allowed_permissions('anypkg') self.assertEqual(perms, {Everyone: ('read',), Authenticated: ('read',)}) def test_has_permission_default_write(self): """ If no user/group permissions on a package, use default_write """ self.backend.default_read = ['authenticated'] self.backend.default_write = ['authenticated'] perms = self.backend.allowed_permissions('anypkg') self.assertEqual(perms, {Authenticated: ('read', 'write')}) def test_admin_principal(self): """ Admin user has the 'admin' principal """ access = IAccessBackend(None) access.is_admin = lambda x: True with patch.object(access, 'groups') as groups: groups.return_value = ['brotatos'] principals = access.user_principals('abc') self.assertItemsEqual(principals, [Everyone, Authenticated, 'admin', 'group:brotatos', 'user:abc']) def test_load(self): """ Base backend has no default implementation for load() """ access = IAccessBackend(None) with self.assertRaises(TypeError): access.load({})