Skip to content

add script to update users country in keycloak - #172

Open
bilalesi wants to merge 2 commits into
mainfrom
feat/script-update-country
Open

add script to update users country in keycloak#172
bilalesi wants to merge 2 commits into
mainfrom
feat/script-update-country

Conversation

@bilalesi

@bilalesi bilalesi commented May 7, 2026

Copy link
Copy Markdown
Collaborator
Screenshot 2026-05-07 at 10 50 08

@bilalesi
bilalesi force-pushed the feat/script-update-country branch from 39773af to fbd07ee Compare May 7, 2026 08:52
@bilalesi bilalesi self-assigned this May 7, 2026
@bilalesi
bilalesi requested review from danifr, g-bar and pgetta May 7, 2026 08:53
@bilalesi
bilalesi force-pushed the feat/script-update-country branch 2 times, most recently from 01558f7 to cf549d8 Compare May 7, 2026 12:46
@bilalesi
bilalesi force-pushed the feat/script-update-country branch from cf549d8 to 9d32f37 Compare May 26, 2026 07:41
@github-actions

Copy link
Copy Markdown

poetry audit report

Loading...
Scanning 105 packages...

No vulnerabilities found ✨✨

@bilalesi
bilalesi requested review from pgetta and removed request for danifr, g-bar and pgetta June 3, 2026 09:17

@pgetta pgetta left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving — the two scripts are well-structured (dry-run/live with double confirmation, attribute merge follows the existing billing.py pattern, and the psycopg2 ANY(CAST(... AS uuid[])) list binding is correct). Left 4 non-blocking inline comments worth addressing before relying on these in a live run, two of which are silent data-correctness issues in write tools.

for row in result.mappings():
row_dict = dict(row)
oid = str(row_dict["owner_id"])
if oid in result_map:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixed/upper-case CSV UUIDs silently skip labs. result_map is keyed by the raw CSV id (line 193), but matched against oid = str(row_dict["owner_id"]) where owner_id::text is always rendered in lowercase canonical form by Postgres. The query's = ANY(CAST(... AS uuid[])) is case-insensitive and validate_user_ids uses re.IGNORECASE, so an uppercase UUID is accepted and its lab is fetched — then dropped here because the lowercase oid doesn't match the uppercase key.

Failure: CSV row id = 5F9D…A1 (a common uppercase export format) → lab exists and is returned, but reports as NO_VLAB and is never updated — a silent skip in a data-write tool.

Fix: lowercase both the result_map keys and oid (or normalize CSV ids on load).

return []

# Strategy 1: Use regex to find all UUID-shaped strings in the input
uuid_pattern = re.compile(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unanchored UUID regex truncates malformed IDs and silently drops junk tokens. Strategy 1 uses an unanchored findall and returns immediately on any match. A token with an extra trailing hex char is matched only up to 36 chars, then passes the anchored validate_user_ids.

Failure: pasting 12345678-1234-1234-1234-1234567890123 (13-digit final group, a typo) → captured as …123456789012 and accepted as valid; if that truncated UUID belongs to a different real user, the wrong user's country is overwritten in live mode.

The same early return found also discards non-UUID tokens (e.g. bad-id-typo, <valid-uuid>) before validate_user_ids runs, so the ⚠️ N invalid UUID(s) will be skipped warning never fires and the operator never learns a token was dropped. Consider anchoring the match per-token (split first, then validate each) instead of scanning the whole blob.

ORDER BY created_at
""")

result_map: Dict[str, List[Dict[str, Any]]] = {uid: [] for uid in owner_ids}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate CSV rows cause repeated updates and inflated counts. load_csv doesn't dedupe and analyze_users iterates per row, so a repeated owner id emits the same vlab_id multiple times; apply_updates then runs one UPDATE per result.

Failure: CSV has the same id twice with a@x.com then b@x.com → the lab is updated to a@x.com then b@x.com (non-deterministic last-write-wins), and the UPDATE N confirmation prompt plus the "X updated" summary double-count the single lab. Consider deduping by id (or by resolved vlab_id) before analysis.

padding=(1, 2),
)
)
scope = UpdateScope.BOTH

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dry-run preview doesn't match the default live run. Dry run hardcodes scope = UpdateScope.BOTH, while live mode prompts and defaults to missing_only.

Failure: operator dry-runs and sees "12 virtual labs would be updated" (missing + mismatches), then runs live and accepts the default missing_only, which changes only the 3 missing ones — the preview overstates the default action, undermining dry-run as a verification step. Consider running the analysis with the same scope the live run will use (or letting the user pick scope in dry-run too).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants