Skip to content

feat: Implement API to GDPR delete users#3224

Open
Janis4411 wants to merge 1 commit intomainfrom
jv/SODEV-2997-Implement-API-to-GDPR-delete-users
Open

feat: Implement API to GDPR delete users#3224
Janis4411 wants to merge 1 commit intomainfrom
jv/SODEV-2997-Implement-API-to-GDPR-delete-users

Conversation

@Janis4411
Copy link
Copy Markdown
Contributor

This PR introduces a possible way to GDPR delete users via a API.

If we delete a user on openHPI we also have to delete the user on codeocean. Previously this was handled via a rake task that has to be triggered manually.

Part of SODEV-2997

@Janis4411 Janis4411 requested a review from arkirchner April 16, 2026 13:25
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 85f5e83 to 4c3c10a Compare April 16, 2026 13:26
Comment thread app/controllers/api/internal/users/deletions_controller.rb Fixed
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread app/jobs/user_cleanup_job.rb Outdated
@Janis4411 Janis4411 marked this pull request as draft April 16, 2026 13:34
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 16, 2026

Codecov Report

❌ Patch coverage is 73.68421% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.35%. Comparing base (7876111) to head (29ef0d1).

Files with missing lines Patch % Lines
app/controllers/api/internal/users_controller.rb 75.00% 2 Missing ⚠️
lib/tasks/gdpr_delete.rake 0.00% 2 Missing ⚠️
app/controllers/api/api_controller.rb 85.71% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3224      +/-   ##
==========================================
+ Coverage   70.33%   70.35%   +0.01%     
==========================================
  Files         214      216       +2     
  Lines        6839     6857      +18     
==========================================
+ Hits         4810     4824      +14     
- Misses       2029     2033       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch 3 times, most recently from 3238780 to 9988915 Compare April 20, 2026 07:57
Comment thread app/controllers/api/api_controller.rb Fixed
Comment thread app/controllers/api/api_controller.rb Fixed
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 9988915 to cb82a61 Compare April 20, 2026 08:23
@Janis4411 Janis4411 self-assigned this Apr 20, 2026
@Janis4411 Janis4411 marked this pull request as ready for review April 20, 2026 09:53
Comment thread app/jobs/user_cleanup_job.rb Outdated
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread app/controllers/api/api_controller.rb Outdated
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread app/jobs/user_cleanup_job.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from cb82a61 to b7bfbd7 Compare April 20, 2026 11:57
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch 2 times, most recently from 62fa41c to 014d4d7 Compare April 21, 2026 07:14
Comment thread app/models/external_user.rb Outdated
Comment on lines +11 to +12
def soft_delete!
update(name: 'Deleted User', email: nil)
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.

I think it is better to blow up if the update did not work. soft_delete does not need a !. The ! indicates a volatile version of a method. Since we do not implement two versions of this method, we should not use !.

Suggested change
def soft_delete!
update(name: 'Deleted User', email: nil)
def soft_delete
update!(name: 'Deleted User', email: nil)

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.

Maybe we can add a new column deleted_at and add a timestamp when the user was deleted. This is good for debugging.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is the updated_at not serving the pretty much same purpose? Once a ExternalUser is updated with (name: 'Deleted User', email: nil) it won't be updated again, right?

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.

It might be. The username Deleted User could be used by a user. No email could be a side effect from some bug. The deleted_at just makes it clearer and is a common practice for soft deletions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added the deleted_at column and update it now in the soft_delete method.

Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
Comment thread spec/request/api/internal/users/deletions_spec.rb Outdated
Comment thread spec/request/api/internal/users/destroy_spec.rb
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 014d4d7 to 667a61b Compare April 21, 2026 09:27
Comment thread lib/tasks/gdpr_delete.rake Outdated
Comment thread app/controllers/api/internal/users/deletions_controller.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 667a61b to 37a665c Compare April 21, 2026 12:03
Comment thread config/routes.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch 2 times, most recently from 1b514dc to 71bbf3d Compare April 21, 2026 12:37
Comment thread app/controllers/api/internal/users_controller.rb Outdated
Comment thread app/controllers/api/internal/users_controller.rb Outdated
Comment thread config/routes.rb Outdated
Comment thread app/controllers/api/internal/users_controller.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 71bbf3d to 142fae9 Compare April 21, 2026 13:14
Comment thread app/controllers/api/internal/users_controller.rb Outdated
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 142fae9 to 79b8847 Compare April 21, 2026 13:55
Comment thread app/controllers/api/internal/users_controller.rb
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch 3 times, most recently from 4f7469b to 4379562 Compare April 21, 2026 15:33
Comment thread app/controllers/api/api_controller.rb Outdated
This is a possible way to GDPR delete users via a API. The background
is that if we delete a user on openhpi we also want to delete the user
on codeocean.

Part of SODEV-2997
@Janis4411 Janis4411 force-pushed the jv/SODEV-2997-Implement-API-to-GDPR-delete-users branch from 4379562 to 29ef0d1 Compare April 21, 2026 15:53
Comment on lines +10 to +13
unless ActiveSupport::SecurityUtils.secure_compare(
token.to_s,
ENV.fetch('OPENHPI_API_TOKEN', nil)
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: ActiveSupport::SecurityUtils.secure_compare will raise a NoMethodError if the OPENHPI_API_TOKEN environment variable is not set, as ENV.fetch will return nil.
Severity: HIGH

Suggested Fix

Ensure the value passed to secure_compare is a string. Either convert the result of ENV.fetch to a string using .to_s, like ENV.fetch('OPENHPI_API_TOKEN', nil).to_s, or provide an empty string as the default value to fetch, like ENV.fetch('OPENHPI_API_TOKEN', '').

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: app/controllers/api/api_controller.rb#L10-L13

Potential issue: The `authenticate` method uses
`ActiveSupport::SecurityUtils.secure_compare` to validate an API token. The second
argument to this function is `ENV.fetch('OPENHPI_API_TOKEN', nil)`. If the
`OPENHPI_API_TOKEN` environment variable is not set, for example due to a deployment
misconfiguration, `ENV.fetch` will return `nil`. The `secure_compare` function then
attempts to call `.bytesize` on this `nil` value, which raises a `NoMethodError`. This
causes the request to fail with a 500 Internal Server Error instead of gracefully
returning a 401 Unauthorized status as intended.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants