Skip to content

Commit 830d120

Browse files
committed
docs(user-sync): add user sync guide and finalize example
1 parent f2d011d commit 830d120

3 files changed

Lines changed: 66 additions & 0 deletions

File tree

‎docs/tools/user-sync.md‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# User Item Sync
2+
3+
Create or update OSW `User` items from the MediaWiki accounts of an OSL
4+
instance, enriching ORCID users from the public ORCID API. The run is
5+
idempotent and previews every change before writing.
6+
7+
## When to use it
8+
9+
OSL instances gain accounts from manual creation and from whitelisted ORCID
10+
single sign-on (whose username is the ORCID iD). Those accounts have no
11+
semantic `User` item until this tool reconciles them.
12+
13+
## Run it
14+
15+
```bash
16+
uv run python examples/user_sync.py --domain your-instance.example.org --dry-run
17+
```
18+
19+
Credentials are read from `accounts.pwd.yaml` (or `--cred-filepath`), the same
20+
mechanism as `OswExpress`. Start with `--dry-run` to preview, then run without
21+
it to write after confirming at the prompt.
22+
23+
### Options
24+
25+
| Flag | Effect |
26+
| --- | --- |
27+
| `--domain` | Target OSL domain. |
28+
| `--cred-filepath` | Path to `accounts.pwd.yaml`. |
29+
| `--dry-run` | Preview only; never writes. |
30+
| `--yes` | Non-interactive: create and gap-fill, keep existing on conflicts. |
31+
| `--limit N` | Process at most N accounts (testing). |
32+
| `--orcid-only` | Only accounts whose username is an ORCID iD. |
33+
| `--include-system` | Do not skip MediaWiki reserved system accounts. |
34+
| `--no-redirects` | Do not create `User:` redirect pages. |
35+
| `--no-organizations` | Do not link ORCID affiliations to Organization items. |
36+
37+
## What it does
38+
39+
1. Enumerate MediaWiki accounts, skipping bots and privileged groups
40+
(`bot`, `sysop`, `bureaucrat`, `interface-admin`) and MediaWiki reserved
41+
system usernames.
42+
2. Enrich ORCID users from `https://pub.orcid.org/v3.0/<id>` (names, public
43+
email, websites, employment or affiliation).
44+
3. Map each account to a proposed `User` item with a deterministic id
45+
(uuid5 on the ORCID iD, else the username), so re-runs are idempotent.
46+
4. Reconcile against existing items by `username` into NEW, GAP_FILL, CONFLICT
47+
or UNCHANGED, then preview and resolve conflicts interactively.
48+
5. Store items, create `User:<username>` redirects to each item, ensure linked
49+
Organization items, and verify by reloading.
50+
51+
## Notes
52+
53+
- MediaWiki does not expose other users' email or real name, so ORCID is the
54+
only source of rich data. Non-ORCID accounts get username-based placeholder
55+
names, flagged in the preview.
56+
- On a first accepted run the library autofetches schemas and may regenerate
57+
`src/osw/model/entity.py`; restore it if you do not want that change.

‎examples/user_sync.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ def main() -> None:
1616
osw = OswExpress(domain=config.domain, cred_filepath=config.cred_filepath)
1717
report = run_user_sync(config, osw=osw)
1818
print(report.summary())
19+
for title in report.created:
20+
print(f" created: {title}")
21+
for title in report.updated:
22+
print(f" updated: {title}")
23+
for key, error in report.failed.items():
24+
print(f" FAILED {key}: {error}")
1925

2026

2127
if __name__ == "__main__":

‎zensical.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ nav = [
2222
{ "Controllers" = "api/controller.md" },
2323
{ "Model" = "api/model.md" },
2424
]},
25+
{ "Tools" = [
26+
{ "User Sync" = "tools/user-sync.md" },
27+
]},
2528
{ "Development" = "dev.md" },
2629
]
2730

0 commit comments

Comments
 (0)