| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | # -*- coding: utf-8; -*- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-08 00:11:30 -06:00
										 |  |  | import uuid as _uuid | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | from unittest import TestCase | 
					
						
							|  |  |  | from unittest.mock import MagicMock | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from pyramid import testing | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from wuttjamaican.conf import WuttaConfig | 
					
						
							|  |  |  | from wuttaweb import auth as mod | 
					
						
							| 
									
										
										
										
											2025-01-06 16:47:48 -06:00
										 |  |  | from wuttaweb.testing import WebTestCase | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestLoginUser(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  |         config = WuttaConfig() | 
					
						
							|  |  |  |         app = config.get_app() | 
					
						
							|  |  |  |         model = app.model | 
					
						
							|  |  |  |         request = testing.DummyRequest(wutta_config=config) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         headers = mod.login_user(request, user) | 
					
						
							|  |  |  |         self.assertEqual(headers, []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | class TestLogoutUser(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							|  |  |  |         config = WuttaConfig() | 
					
						
							|  |  |  |         request = testing.DummyRequest(wutta_config=config) | 
					
						
							|  |  |  |         request.session.delete = MagicMock() | 
					
						
							|  |  |  |         headers = mod.logout_user(request) | 
					
						
							|  |  |  |         request.session.delete.assert_called_once_with() | 
					
						
							|  |  |  |         self.assertEqual(headers, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestWuttaSecurityPolicy(TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def setUp(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.config = WuttaConfig( | 
					
						
							|  |  |  |             defaults={ | 
					
						
							|  |  |  |                 "wutta.db.default.url": "sqlite://", | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.request = testing.DummyRequest() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.pyramid_config = testing.setUp( | 
					
						
							|  |  |  |             request=self.request, | 
					
						
							|  |  |  |             settings={ | 
					
						
							|  |  |  |                 "wutta_config": self.config, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         self.app = self.config.get_app() | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  |         model.Base.metadata.create_all(bind=self.config.appdb_engine) | 
					
						
							|  |  |  |         self.session = self.app.make_session() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.user = model.User(username="barney") | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         self.session.add(self.user) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.policy = self.make_policy() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self): | 
					
						
							|  |  |  |         testing.tearDown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def make_policy(self): | 
					
						
							|  |  |  |         return mod.WuttaSecurityPolicy(db_session=self.session) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_remember(self): | 
					
						
							|  |  |  |         uuid = self.user.uuid | 
					
						
							|  |  |  |         self.assertIsNotNone(uuid) | 
					
						
							|  |  |  |         self.assertIsNone(self.policy.session_helper.authenticated_userid(self.request)) | 
					
						
							|  |  |  |         self.policy.remember(self.request, uuid) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.policy.session_helper.authenticated_userid(self.request), uuid | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_forget(self): | 
					
						
							|  |  |  |         uuid = self.user.uuid | 
					
						
							|  |  |  |         self.policy.remember(self.request, uuid) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertEqual( | 
					
						
							|  |  |  |             self.policy.session_helper.authenticated_userid(self.request), uuid | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         self.policy.forget(self.request) | 
					
						
							|  |  |  |         self.assertIsNone(self.policy.session_helper.authenticated_userid(self.request)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_identity(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no identity | 
					
						
							|  |  |  |         user = self.policy.identity(self.request) | 
					
						
							|  |  |  |         self.assertIsNone(user) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # identity is remembered (must use new policy to bust cache) | 
					
						
							|  |  |  |         self.policy = self.make_policy() | 
					
						
							|  |  |  |         uuid = self.user.uuid | 
					
						
							|  |  |  |         self.assertIsNotNone(uuid) | 
					
						
							|  |  |  |         self.policy.remember(self.request, uuid) | 
					
						
							|  |  |  |         user = self.policy.identity(self.request) | 
					
						
							|  |  |  |         self.assertIs(user, self.user) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # invalid identity yields no user | 
					
						
							|  |  |  |         self.policy = self.make_policy() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.policy.remember(self.request, _uuid.uuid4())  # random uuid | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         user = self.policy.identity(self.request) | 
					
						
							|  |  |  |         self.assertIsNone(user) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_authenticated_userid(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # no identity | 
					
						
							|  |  |  |         uuid = self.policy.authenticated_userid(self.request) | 
					
						
							|  |  |  |         self.assertIsNone(uuid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # identity is remembered (must use new policy to bust cache) | 
					
						
							|  |  |  |         self.policy = self.make_policy() | 
					
						
							|  |  |  |         self.policy.remember(self.request, self.user.uuid) | 
					
						
							|  |  |  |         uuid = self.policy.authenticated_userid(self.request) | 
					
						
							|  |  |  |         self.assertEqual(uuid, self.user.uuid) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_permits(self): | 
					
						
							|  |  |  |         auth = self.app.get_auth_handler() | 
					
						
							|  |  |  |         model = self.app.model | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # anon has no perms | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(self.policy.permits(self.request, None, "foo.bar")) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but we can grant it | 
					
						
							|  |  |  |         anons = auth.get_role_anonymous(self.session) | 
					
						
							|  |  |  |         self.user.roles.append(anons) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         auth.grant_permission(anons, "foo.bar") | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # and then perm check is satisfied | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(self.policy.permits(self.request, None, "foo.bar")) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # now, create a separate role and grant another perm | 
					
						
							|  |  |  |         # (but user does not yet belong to this role) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         role = model.Role(name="whatever") | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         self.session.add(role) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         auth.grant_permission(role, "baz.edit") | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  |         self.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # so far then, user does not have the permission | 
					
						
							|  |  |  |         self.policy = self.make_policy() | 
					
						
							|  |  |  |         self.policy.remember(self.request, self.user.uuid) | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(self.policy.permits(self.request, None, "baz.edit")) | 
					
						
							| 
									
										
										
										
											2024-08-04 21:54:46 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # but if we assign user to role, perm check should pass | 
					
						
							|  |  |  |         self.user.roles.append(role) | 
					
						
							|  |  |  |         self.session.commit() | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(self.policy.permits(self.request, None, "baz.edit")) | 
					
						
							| 
									
										
										
										
											2024-08-05 14:21:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # now let's try another perm - we won't grant it, but will | 
					
						
							|  |  |  |         # confirm user is denied access unless they become root | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertFalse(self.policy.permits(self.request, None, "some-root-perm")) | 
					
						
							| 
									
										
										
										
											2024-08-05 14:21:54 -05:00
										 |  |  |         self.request.is_root = True | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         self.assertTrue(self.policy.permits(self.request, None, "some-root-perm")) | 
					
						
							| 
									
										
										
										
											2024-08-14 15:10:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestAddPermissionGroup(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         permissions = self.pyramid_config.get_settings().get("wutta_permissions", {}) | 
					
						
							|  |  |  |         self.assertNotIn("widgets", permissions) | 
					
						
							|  |  |  |         self.pyramid_config.add_wutta_permission_group("widgets") | 
					
						
							|  |  |  |         permissions = self.pyramid_config.get_settings().get("wutta_permissions", {}) | 
					
						
							|  |  |  |         self.assertIn("widgets", permissions) | 
					
						
							|  |  |  |         self.assertEqual(permissions["widgets"]["label"], "Widgets") | 
					
						
							| 
									
										
										
										
											2024-08-14 15:10:54 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestAddPermission(WebTestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_basic(self): | 
					
						
							| 
									
										
										
										
											2025-08-31 12:26:43 -05:00
										 |  |  |         permissions = self.pyramid_config.get_settings().get("wutta_permissions", {}) | 
					
						
							|  |  |  |         self.assertNotIn("widgets", permissions) | 
					
						
							|  |  |  |         self.pyramid_config.add_wutta_permission("widgets", "widgets.polish") | 
					
						
							|  |  |  |         permissions = self.pyramid_config.get_settings().get("wutta_permissions", {}) | 
					
						
							|  |  |  |         self.assertIn("widgets", permissions) | 
					
						
							|  |  |  |         self.assertEqual(permissions["widgets"]["label"], "Widgets") | 
					
						
							|  |  |  |         self.assertIn("widgets.polish", permissions["widgets"]["perms"]) |