browsertrix/backend/btrixcloud/migrations/migration_0018_usernames.py
Ilya Kreymer 9a2787f9c4
User refactor + remove fastapi_users dependency + update fastapi (#1290)
Fixes #1050 

Major refactor of the user/auth system to remove fastapi_users
dependency. Refactors users.py to be standalone
and adds new auth.py module for handling auth. UserManager now works
similar to other ops classes.

The auth should be fully backwards compatible with fastapi_users auth,
including accepting previous JWT tokens w/o having to re-login. The User
data model in mongodb is also unchanged.

Additional fixes:
- allows updating fastapi to latest
- add webhook docs to openapi (follow up to #1041)

API changes:
- Removing the`GET, PATCH, DELETE /users/<id>` endpoints, which were not
in used before, as users are scoped to orgs. For deletion, probably
auto-delete when user is removed from last org (to be implemented).
- Rename `/users/me-with-orgs` is renamed to just `/users/me/`
- New `PUT /users/me/change-password` endpoint with password required to update password, fixes  #1269, supersedes #1272 

Frontend changes:
- Fixes from #1272 to support new change password endpoint.

---------
Co-authored-by: Tessa Walsh <tessa@bitarchivist.net>
Co-authored-by: sua yoo <sua@suayoo.com>
2023-10-18 10:49:23 -07:00

89 lines
3.0 KiB
Python

"""
Migration 0018 - Store crawl and workflow userName directly in db
"""
from btrixcloud.migrations import BaseMigration
from btrixcloud.emailsender import EmailSender
from btrixcloud.invites import init_invites
from btrixcloud.users import init_user_manager
MIGRATION_VERSION = "0018"
# pylint: disable=too-many-locals, invalid-name
class Migration(BaseMigration):
"""Migration class."""
def __init__(self, mdb, migration_version=MIGRATION_VERSION):
super().__init__(mdb, migration_version)
async def migrate_up(self):
"""Perform migration up.
Store userName in db for crawls and workflows
"""
mdb_configs = self.mdb["crawl_configs"]
mdb_crawls = self.mdb["crawls"]
email = EmailSender()
invites = init_invites(self.mdb, email)
user_manager = init_user_manager(self.mdb, email, invites)
async for crawl in mdb_crawls.find({}):
crawl_id = crawl["_id"]
if crawl.get("userName"):
continue
try:
user = await user_manager.get_by_id(crawl["userid"])
await mdb_crawls.find_one_and_update(
{"_id": crawl_id},
{"$set": {"userName": user.name}},
)
# pylint: disable=broad-exception-caught
except Exception as err:
print(
f"Unable to update userName for crawl {crawl_id}: {err}", flush=True
)
async for config in mdb_configs.find({}):
cid = config["_id"]
if config.get("createdByName") and config.get("modifiedByName"):
continue
try:
created_by_name = ""
modified_by_name = ""
last_started_by_name = ""
created_user = await user_manager.get_by_id(config["createdBy"])
if created_user:
created_by_name = created_user.name
modified_user = await user_manager.get_by_id(config["modifiedBy"])
if modified_user:
modified_by_name = modified_user.name
last_started_by = config.get("lastStartedBy")
if last_started_by:
last_started_user = await user_manager.get_by_id(last_started_by)
if last_started_user:
last_started_by_name = last_started_user.name
await mdb_configs.find_one_and_update(
{"_id": cid},
{
"$set": {
"createdByName": created_by_name,
"modifiedByName": modified_by_name,
"lastStartedByName": last_started_by_name,
}
},
)
# pylint: disable=broad-exception-caught
except Exception as err:
print(
f"Unable to update usernames for crawlconfig {cid}: {err}",
flush=True,
)