Skip to content

Commit

Permalink
Add script for migrating OAuth2 sub
Browse files Browse the repository at this point in the history
  • Loading branch information
jirik committed Jan 10, 2024
1 parent edea390 commit a6a6d87
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
```
OAUTH2_INTROSPECTION_SUB_KEY=userId
```
- After running `make upgrade-demo` or `make-upgrade-demo-full`, run also script `v1_23_change_oauth2_sub_username_to_user_id.py`:
```bash
docker compose -f docker-compose.deps.demo.yml -f docker-compose.demo.yml run --rm --no-deps -u root -e LAYMAN_WAGTAIL_DB_URI=<URI_of_Wagtail_db> layman bash -c "cd src && python3 -B v1_23_change_oauth2_sub_username_to_user_id.py"
```
- `URI_of_Wagtail_db` is PostgreSQL connection URI to Wagtail database, e.g. `postgresql://user:[email protected]:5432/wagtail_db_name`
- The script changes OAuth2 "sub" values in Layman prime DB schema from Wagtail usernames to Wagtail user IDs. See [940](https://github.com/LayerManager/layman/issues/940).
### Migrations and checks
#### Schema migrations
- [#165](https://github.com/LayerManager/layman/issues/165) Add column `role_name` to table `rights` in prime DB schema. Add constraint that exactly one of columns `role_name` and `id_user` is not null.
Expand Down
54 changes: 54 additions & 0 deletions src/v1_23_change_oauth2_sub_username_to_user_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import os
import layman_settings as settings
from db import util as db_util


def main():
assert settings.OAUTH2_INTROSPECTION_SUB_KEY == 'userId', f"OAUTH2_INTROSPECTION_SUB_KEY is expected to be `userId`"
assert settings.OAUTH2_INTROSPECTION_USE_SUB_KEY_FROM_USER_PROFILE is True, f"OAUTH2_INTROSPECTION_USE_SUB_KEY_FROM_USER_PROFILE is expected to be `true`"

wagtail_db_uri = os.getenv('LAYMAN_WAGTAIL_DB_URI', None)
assert wagtail_db_uri is not None, f"LAYMAN_WAGTAIL_DB_URI must be set"

wagtail_user_rows = db_util.run_query(f"select id, username from auth_user;", uri_str=wagtail_db_uri)
assert len(set(r[0] for r in wagtail_user_rows)) == len(wagtail_user_rows), f"Wagtail userIds are expected to be unique"
assert len(set(r[1] for r in wagtail_user_rows)) == len(wagtail_user_rows), f"Wagtail usernames are expected to be unique"
wagtail_username_to_id = {
username: f"{user_id}"
for user_id, username in wagtail_user_rows
}

layman_user_rows = db_util.run_query(f"""
select u.id, u.issuer_id, u.sub, w.name as username
from {settings.LAYMAN_PRIME_SCHEMA}.users u
inner join {settings.LAYMAN_PRIME_SCHEMA}.workspaces w on u.id_workspace = w.id
""", uri_str=settings.PG_URI_STR)

print(f"Found {len(wagtail_user_rows)} Wagtail users:")
for user_id, username in wagtail_user_rows:
print(f" {username}, id={user_id}")

print(f"Found {len(layman_user_rows)} Layman users with username registered.")
print(f'Processing Layman users ...')

changed_subs = 0
for layman_user_id, issuer_id, sub, username in layman_user_rows:
print(f" {username} (id={layman_user_id}, sub={sub}, issuer_id={issuer_id})")
if issuer_id != 'layman.authn.oauth2':
print(f" WARNING: User has unexpected issuer_id, skipping.")
continue
new_sub = wagtail_username_to_id.get(sub)
if new_sub is None:
print(f" WARNING: Sub of the user was not found among Wagtail usernames, skipping.")
continue
print(f' Changing sub from `{sub}` to `{new_sub}`')
db_util.run_statement(
f"UPDATE {settings.LAYMAN_PRIME_SCHEMA}.users set sub = %s where id = %s",
data=(new_sub, layman_user_id), uri_str=settings.PG_URI_STR)
changed_subs += 1
print(f' Changed!')
print(f'Processing finished, changed {changed_subs} OAuth2 subs of {len(layman_user_rows)} Layman users.')


if __name__ == '__main__':
main()

0 comments on commit a6a6d87

Please sign in to comment.