Update user names in crawls and workflows after username update (#1299)
Fixes #1275
This commit is contained in:
		
							parent
							
								
									fc6dc287c0
								
							
						
					
					
						commit
						733809b5a8
					
				| @ -206,6 +206,12 @@ class BaseCrawlOps: | ||||
|             {"$set": data}, | ||||
|         ) | ||||
| 
 | ||||
|     async def update_usernames(self, userid: uuid.UUID, updated_name: str) -> None: | ||||
|         """Update username references matching userid""" | ||||
|         await self.crawls.update_many( | ||||
|             {"userid": userid}, {"$set": {"userName": updated_name}} | ||||
|         ) | ||||
| 
 | ||||
|     async def shutdown_crawl(self, crawl_id: str, org: Organization, graceful: bool): | ||||
|         """stop or cancel specified crawl""" | ||||
|         crawl = await self.get_crawl_raw(crawl_id, org) | ||||
| @ -764,3 +770,5 @@ def init_base_crawls_api( | ||||
|         org: Organization = Depends(org_crawl_dep), | ||||
|     ): | ||||
|         return await ops.delete_crawls_all_types(delete_list, org, user) | ||||
| 
 | ||||
|     return ops | ||||
|  | ||||
| @ -340,6 +340,14 @@ class CrawlConfigOps: | ||||
|             ret["started"] = crawl_id | ||||
|         return ret | ||||
| 
 | ||||
|     async def update_usernames(self, userid: uuid.UUID, updated_name: str) -> None: | ||||
|         """Update username references matching userid""" | ||||
|         for workflow_field in ["createdBy", "modifiedBy", "lastStartedBy"]: | ||||
|             await self.crawl_configs.update_many( | ||||
|                 {workflow_field: userid}, | ||||
|                 {"$set": {f"{workflow_field}Name": updated_name}}, | ||||
|             ) | ||||
| 
 | ||||
|     async def get_crawl_configs( | ||||
|         self, | ||||
|         org: Organization, | ||||
|  | ||||
| @ -76,8 +76,6 @@ def main(): | ||||
| 
 | ||||
|     event_webhook_ops = init_event_webhooks_api(mdb, org_ops, app_root) | ||||
| 
 | ||||
|     user_manager.set_org_ops(org_ops) | ||||
| 
 | ||||
|     # pylint: disable=import-outside-toplevel | ||||
|     if not os.environ.get("KUBERNETES_SERVICE_HOST"): | ||||
|         print( | ||||
| @ -106,7 +104,7 @@ def main(): | ||||
| 
 | ||||
|     coll_ops = init_collections_api(app, mdb, org_ops, storage_ops, event_webhook_ops) | ||||
| 
 | ||||
|     init_base_crawls_api( | ||||
|     base_crawl_ops = init_base_crawls_api( | ||||
|         app, | ||||
|         mdb, | ||||
|         user_manager, | ||||
| @ -118,6 +116,8 @@ def main(): | ||||
|         current_active_user, | ||||
|     ) | ||||
| 
 | ||||
|     user_manager.set_ops(org_ops, crawl_config_ops, base_crawl_ops) | ||||
| 
 | ||||
|     crawls = init_crawls_api( | ||||
|         app, | ||||
|         mdb, | ||||
|  | ||||
| @ -41,8 +41,6 @@ def main(): | ||||
| 
 | ||||
|     event_webhook_ops = EventWebhookOps(mdb, org_ops) | ||||
| 
 | ||||
|     user_manager.set_org_ops(org_ops) | ||||
| 
 | ||||
|     # pylint: disable=import-outside-toplevel | ||||
|     if not os.environ.get("KUBERNETES_SERVICE_HOST"): | ||||
|         print( | ||||
| @ -66,6 +64,8 @@ def main(): | ||||
|         profile_ops, | ||||
|     ) | ||||
| 
 | ||||
|     user_manager.set_ops(org_ops, crawl_config_ops, None) | ||||
| 
 | ||||
|     coll_ops = CollectionOps(mdb, crawl_manager, org_ops, event_webhook_ops) | ||||
| 
 | ||||
|     crawl_ops = CrawlOps( | ||||
|  | ||||
| @ -51,21 +51,26 @@ from .auth import ( | ||||
| 
 | ||||
| 
 | ||||
| # ============================================================================ | ||||
| # pylint: disable=raise-missing-from, too-many-public-methods | ||||
| # pylint: disable=raise-missing-from, too-many-public-methods, too-many-instance-attributes | ||||
| class UserManager: | ||||
|     """Browsertrix UserManager""" | ||||
| 
 | ||||
|     def __init__(self, mdb, email, invites): | ||||
|         self.users = mdb.get_collection("users") | ||||
|         self.crawl_config_ops = None | ||||
|         self.base_crawl_ops = None | ||||
|         self.email = email | ||||
|         self.invites = invites | ||||
|         self.org_ops = None | ||||
| 
 | ||||
|         self.registration_enabled = is_bool(os.environ.get("REGISTRATION_ENABLED")) | ||||
| 
 | ||||
|     def set_org_ops(self, ops): | ||||
|     # pylint: disable=attribute-defined-outside-init | ||||
|     def set_ops(self, org_ops, crawl_config_ops, base_crawl_ops): | ||||
|         """set org ops""" | ||||
|         self.org_ops = ops | ||||
|         self.org_ops = org_ops | ||||
|         self.crawl_config_ops = crawl_config_ops | ||||
|         self.base_crawl_ops = base_crawl_ops | ||||
| 
 | ||||
|     async def init_index(self): | ||||
|         """init lookup index""" | ||||
| @ -476,6 +481,10 @@ class UserManager: | ||||
| 
 | ||||
|         await self.update_email_name(user, user_update.email, user_update.name) | ||||
| 
 | ||||
|         if user_update.name: | ||||
|             await self.base_crawl_ops.update_usernames(user.id, user_update.name) | ||||
|             await self.crawl_config_ops.update_usernames(user.id, user_update.name) | ||||
| 
 | ||||
|     async def update_verified(self, user: User) -> None: | ||||
|         """Update verified status for user""" | ||||
|         await self.users.find_one_and_update( | ||||
|  | ||||
| @ -1,7 +1,13 @@ | ||||
| import requests | ||||
| import time | ||||
| 
 | ||||
| from .conftest import API_PREFIX, CRAWLER_USERNAME, ADMIN_PW, ADMIN_USERNAME | ||||
| from .conftest import ( | ||||
|     API_PREFIX, | ||||
|     CRAWLER_USERNAME, | ||||
|     ADMIN_PW, | ||||
|     ADMIN_USERNAME, | ||||
|     FINISHED_STATES, | ||||
| ) | ||||
| 
 | ||||
| VALID_USER_EMAIL = "validpassword@example.com" | ||||
| VALID_USER_PW = "validpassw0rd!" | ||||
| @ -230,14 +236,67 @@ def test_reset_valid_password(admin_auth_headers, default_org_id): | ||||
|     assert r.json()["updated"] == True | ||||
| 
 | ||||
| 
 | ||||
| def test_patch_me_endpoint(admin_auth_headers, default_org_id): | ||||
| def test_patch_me_endpoint(admin_auth_headers, default_org_id, admin_userid): | ||||
|     # Start a new crawl | ||||
|     crawl_data = { | ||||
|         "runNow": True, | ||||
|         "name": "name change test crawl", | ||||
|         "config": { | ||||
|             "seeds": [{"url": "https://specs.webrecorder.net/", "depth": 1}], | ||||
|         }, | ||||
|     } | ||||
|     r = requests.post( | ||||
|         f"{API_PREFIX}/orgs/{default_org_id}/crawlconfigs/", | ||||
|         headers=admin_auth_headers, | ||||
|         json=crawl_data, | ||||
|     ) | ||||
|     data = r.json() | ||||
|     crawl_id = data["run_now_job"] | ||||
| 
 | ||||
|     # Wait for it to complete | ||||
|     while True: | ||||
|         r = requests.get( | ||||
|             f"{API_PREFIX}/orgs/{default_org_id}/crawls/{crawl_id}/replay.json", | ||||
|             headers=admin_auth_headers, | ||||
|         ) | ||||
|         data = r.json() | ||||
|         if data["state"] in FINISHED_STATES: | ||||
|             break | ||||
|         time.sleep(5) | ||||
| 
 | ||||
|     # Change user name and email | ||||
|     new_name = "New Admin" | ||||
|     r = requests.patch( | ||||
|         f"{API_PREFIX}/users/me", | ||||
|         headers=admin_auth_headers, | ||||
|         json={"email": "admin2@example.com", "name": "New Admin"}, | ||||
|         json={"email": "admin2@example.com", "name": new_name}, | ||||
|     ) | ||||
|     assert r.status_code == 200 | ||||
| 
 | ||||
|     # Verify that name was updated in workflows and crawls | ||||
|     for workflow_field in ["createdBy", "modifiedBy", "lastStartedBy"]: | ||||
|         r = requests.get( | ||||
|             f"{API_PREFIX}/orgs/{default_org_id}/crawlconfigs?{workflow_field}={admin_userid}", | ||||
|             headers=admin_auth_headers, | ||||
|         ) | ||||
|         assert r.status_code == 200 | ||||
|         data = r.json() | ||||
|         assert data["total"] > 0 | ||||
|         for workflow in data["items"]: | ||||
|             if workflow[workflow_field] == admin_userid: | ||||
|                 assert workflow[f"{workflow_field}Name"] == new_name | ||||
| 
 | ||||
|     r = requests.get( | ||||
|         f"{API_PREFIX}/orgs/{default_org_id}/crawls?userid={admin_userid}", | ||||
|         headers=admin_auth_headers, | ||||
|     ) | ||||
|     assert r.status_code == 200 | ||||
|     data = r.json() | ||||
|     assert data["total"] > 0 | ||||
|     for item in data["items"]: | ||||
|         if item["userid"] == admin_userid: | ||||
|             assert item["userName"] == new_name | ||||
| 
 | ||||
| 
 | ||||
| def test_patch_me_invalid_email_in_use(admin_auth_headers, default_org_id): | ||||
|     r = requests.patch( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user