spring: Add Flask password-sync utility (1/4 split of #168) - #169
spring: Add Flask password-sync utility (1/4 split of #168)#169RudraBJoshi wants to merge 2 commits into
Conversation
FlaskPasswordSync calls Flask's internal sync endpoint (POST /api/internal/sync-password) with a shared secret (INTERNAL_SYNC_KEY), so a password reset completed on Spring also lands on the Flask account for the same uid. Not wired up to any caller yet -- that's the OAuth-verified reset flow, next PR in the stack. Best-effort: a sync failure is logged, not fatal to whatever already-successful operation triggered it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Ensures any Claude Code session working in this repo automatically sees that .clauderc (one directory up, at the prodsys root) has the project structure, ongoing work, deploy requirements, and known gaps -- CLAUDE.md is auto-loaded into context at session start, .clauderc on its own is not.
|
This should be tied to Profile Password reset |
|
The process from the logged-in Reset Password should use this utility. IF Login -> Profile/Reset Password button -> Delete all Cookies -> Reset Flask -> Reset Spring (if the Spring account does not exist, create it) -> Force Logout -> Return to the login page. IF Logout -> we need to put them through an identification process, probably by sending them an email. On the email confirmation link, you can reset their Flask password to a temporary password. The next login should force them to reset their password. I don't believe we want to do more than reset Flask as we may have several needs for recovery and we should have that sequence in one place. |
Addresses jm1021's review feedback on PR Open-Coding-Society#169/flask Open-Coding-Society#74 ("tied to Profile Password reset") reinterpreted for the current architecture: the profile page's direct password field was removed in a later PR in the same stack in favor of routing everyone through this OAuth wizard, so "tied to profile reset" now means "tied to the wizard's completion". Track MVC logins in a SessionRegistry (tracking only, no session cap) and force-expire a uid's sessions after /reset/oauth/complete succeeds, closing the previously-documented gap where the JWT path invalidated on password change but the MVC HttpSession path didn't. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Addressed in split/spring/s2-oauth-verified-reset (spring #170): reinterpreted for the current architecture since the profile page's own direct password-change field was removed in a later PR (pages #1371) in favor of routing everyone -- logged in or not -- through the same OAuth-verified reset wizard. |
|
This has a hard-coded localhost address that will not work in production. String flaskUri = resolve("FLASK_URI", "http://localhost:8587"); Traditionally, we change passwords from Frontend user input. In that case, we obtain the URI from the frontend. import { pythonURI, javaURI, fetchOptions } from '{{ site.baseurl }}/assets/js/api/config.js';Is this a case where we change the password in the Spring Admin UI and want it updated in Flask? This would be a very low-volume use case. In my view, Flask is in charge, so I do not want the Spring --> Flask path. Synchronization and Recovery PracticesThe primary principle for this system is:
For that reason, synchronization should be coordinated through the existing frontend API paths: Frontend → Flask — obtain the authoritative state Flask remains the System of Record; the frontend is the mechanism through which the user performs synchronization. This avoids creating a new privileged Flask → Spring or Spring → Flask communication path. 1. User Changes Password in the FrontendWhen a user changes their password through the frontend:
The frontend should not retrieve password hashes, encrypted passwords, or authentication tokens from Flask for the purpose of sending them to Spring. The browser should not be responsible for synchronizing sensitive credentials between backends. 2. User Account Synchronization or RecoveryThere may be situations where a Spring account is missing or out of synchronization. In these cases:
Synchronization may include fields such as:
The synchronization process should be designed so that it is safe to run repeatedly. If the Spring record already exists, it should be updated rather than duplicated.
3. Forgot Password or UIDThe password recovery process should remain centralized. A user requests account recovery through the frontend. The system should:
The password reset process should never depend upon manually retrieving or transferring password hashes through the frontend. 4. Administrative Reset and CleanupAdministrative tools in Jinja2 or Thymeleaf may need to support account recovery, cleanup, or removal. Worst case scenario. Examples may include:
The goal should be to develop safe administrative recovery operations rather than allowing Flask and Spring administrators to directly overwrite each other's data. Administrative Rule
This provides a clear recovery path when synchronization fails and prevents the system from developing two competing sources of truth. |
|
After verbal confirmation, my inclination is that we will close this PR. |
|
This is banned from design shared above. |
Splitting #168 into smaller, independently-reviewable PRs across spring/flask/pages. This one covers password database syncing.
Adds
FlaskPasswordSync, a standalone utility that calls Flask'sPOST /api/internal/sync-passwordwith a shared secret, so a Spring-side reset can keep Flask's password in sync. Not wired up to any caller yet — that happens in the next PR in this stack, which depends on this class existing.Stack: this PR → "Add OAuth + student ID verified password reset flow" and "Refuse to sync a plaintext password to Flask..." both branch from here.
Original PR: #168