fix: Redact uid field and delete records for retired users from support_historicalusersocialauth#38658
fix: Redact uid field and delete records for retired users from support_historicalusersocialauth#38658Akanshu-2u wants to merge 19 commits into
Conversation
…rt_historicalusersocialauth
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR strengthens user retirement by ensuring PII stored in django-simple-history snapshots of social auth records is redacted and removed during the retirement workflow.
Changes:
- Call a new retirement utility to redact+delete
HistoricalUserSocialAuthrows during user retirement. - Add
redact_and_delete_historical_social_authutility that updatesuid/extra_datathen deletes historical rows. - Add LMS tests covering UPDATE-before-DELETE behavior and deletion scope.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| openedx/core/djangoapps/user_api/accounts/views.py | Invokes the new historical social auth redaction/deletion step during retirement. |
| openedx/core/djangoapps/user_api/accounts/utils.py | Adds a utility to redact+delete historical social auth snapshots that can retain PII. |
| openedx/core/djangoapps/user_api/accounts/tests/test_utils.py | Adds tests validating query ordering and deletion behavior for historical social auth redaction. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
8150ff0 to
798d6e5
Compare
| super().setUp() | ||
| self.user = UserFactory.create(username='testuser', email='testuser@example.com') | ||
| self.historical_social_auth_model = getattr(getattr(UserSocialAuth, 'history', None), 'model', None) | ||
| if self.historical_social_auth_model is None: |
| [query['sql'] for query in ctx], | ||
| table=table_name, | ||
| ) | ||
| # since rows are filtered by user_id and history_id is used to build the unique redacted uid. |
There was a problem hiding this comment.
- There is a grammatical error in this sentence that makes me unable to understand what you want to get across.
- I'm not clear if the sentence should be fixed or removed. I'm sort of feel like this whole assertion should be removed.
| HistoricalUserSocialAuth rows are django-simple-history snapshots not covered by the | ||
| standard UserSocialAuth retirement step, so they must be explicitly cleaned up. |
There was a problem hiding this comment.
I replaced this comment. I don't think the original is necessary, and I like this one that was used elsewhere to explain why we are redacting before deleting.
| HistoricalUserSocialAuth rows are django-simple-history snapshots not covered by the | |
| standard UserSocialAuth retirement step, so they must be explicitly cleaned up. | |
| Downstream copies of data may use soft-deletes, and redacting before deleting | |
| ensures PII for retired users (or future retirements) is not retained. |
| HistoricalUserSocialAuth rows are django-simple-history snapshots not covered by the | ||
| standard UserSocialAuth retirement step, so they must be explicitly cleaned up. | ||
| """ | ||
| historical_social_auth_model = getattr(getattr(UserSocialAuth, 'history', None), 'model', None) |
There was a problem hiding this comment.
Is this an optional model? Is it behind a feature flag?
| LOGGER.warning( | ||
| 'redact_and_delete_historical_social_auth: UserSocialAuth has no history model, skipping for user_id=%s', | ||
| user_id, | ||
| ) |
There was a problem hiding this comment.
At most this would be .debug for local testing, but it probably isn't needed at all. We shouldn't warn for normal behavior.
| # Redact and delete django-simple-history snapshots of social auth records. | ||
| redact_and_delete_historical_social_auth(user.id) |
There was a problem hiding this comment.
I'm guessing we don't want this here, and only want this when we do the full retirement.
| # Redact and delete django-simple-history snapshots of social auth records. | ||
| redact_and_delete_historical_social_auth(user.id) |
There was a problem hiding this comment.
I don't think we want this here. What do you think? I think this is just adding someone to the queue, where we do minimal retirement to lock them out, but the full retirement happens elsewhere.
| Test that HistoricalUserSocialAuth records are redacted and deleted when retire_user is called. | ||
| Covers both single and multiple historical record scenarios. | ||
|
|
||
| HistoricalUserSocialAuth rows are django-simple-history snapshots that are not touched | ||
| by the live UserSocialAuth retirement step, so they must be explicitly cleaned up. |
There was a problem hiding this comment.
- The first line of a docstring is usually a single line (non-wrapped) summary. Add a blank line if you want to add more comments.
- That said, I'm removing the rest, because I don't think it is needed.
| Test that HistoricalUserSocialAuth records are redacted and deleted when retire_user is called. | |
| Covers both single and multiple historical record scenarios. | |
| HistoricalUserSocialAuth rows are django-simple-history snapshots that are not touched | |
| by the live UserSocialAuth retirement step, so they must be explicitly cleaned up. | |
| Test that HistoricalUserSocialAuth records are redacted and deleted when retire_user is called. |
Description:
This PR strengthens user retirement by ensuring PII stored in django-simple-history snapshots of social auth records is redacted and removed during the retirement workflow.
Changes:
redact_and_delete_historical_social_authutility that bulk-updatesuidto a safe placeholderredacted-before-delete-{history_id}@safe.comand clearsextra_datathen deletes the rows.LMSAccountRetirementView.post()during the retirement workflow.Private JIRA Link:
BOMS-577