-
Notifications
You must be signed in to change notification settings - Fork 119
feat: make regular api tokens revocable #1027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
matmanna
wants to merge
41
commits into
hackclub:main
Choose a base branch
from
matmanna:revokable_api_tokens
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 18 commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
02868bf
add new icon from bounty
matmanna 36a158d
Merge branch 'hackclub:main' into main
matmanna 5ff4402
Merge pull request #2 from hackclub/main
matmanna bfe6360
feat: add hackatime normal token revocation
matmanna 1ad3835
chore: make linter not hate me (its always whitespace) <3
matmanna e0fdb0a
fix: combine both revocation apis into one (as requested by mahad)
matmanna c12f771
chore: add HKA_REVOCATION_KEY to .env.example
matmanna a7ba13f
chore: merge remote-tracking branch 'upstream/main'
matmanna 707af3c
feat: add hackatime normal token revocation
matmanna 331062f
chore: make linter not hate me (its always whitespace) <3
matmanna 340009b
fix: combine both revocation apis into one (as requested by mahad)
matmanna 30e5091
chore: add HKA_REVOCATION_KEY to .env.example
matmanna 075f9c9
chore: merge branch 'revokable_api_tokens' of https://github.com/quac…
matmanna b8a4154
feat: add hackatime normal token revocation
matmanna 353aa8d
chore: make linter not hate me (its always whitespace) <3
matmanna aaea827
fix: combine both revocation apis into one (as requested by mahad)
matmanna 2e96e80
chore: add HKA_REVOCATION_KEY to .env.example
matmanna 86c3bc9
feat: add hackatime normal token revocation
matmanna 0d74f3f
chore: make linter not hate me (its always whitespace) <3
matmanna f588a2e
fix: combine both revocation apis into one (as requested by mahad)
matmanna f8d4f57
fix: stuff greptile suggested
matmanna bb5cfb3
chore: keep uptodate
matmanna 2fb2aff
style: add final newline
matmanna 766833d
Merge branch 'main' into revokable_api_tokens
matmanna 082e7b8
docs: apply .env.example suggestion from @skyfallwastaken
matmanna 8a842e5
refactor: move apikey rotation to user model
matmanna 163301e
merge branch 'revokable_api_tokens' of https://github.com/quackclub/h…
matmanna d5d0cc2
style: remove unnecessary comment
matmanna 64cfe45
fix: tests passing and inappropriate response codes
matmanna 595c283
refactor: fix response codes
matmanna c21f28f
refactor: move key info request back into separate function
matmanna 446cadf
Merge branch 'revokable_api_tokens' of github.com:quackclub/hackatime…
matmanna a8f4d4f
Merge branch 'main' into revokable_api_tokens
matmanna 86eae94
fix: broken ci because of merge mistake :/
matmanna 07e85a1
Merge branch 'main' into revokable_api_tokens
matmanna ea1f735
Merge branch 'main' into revokable_api_tokens
skyfallwastaken c1873d6
Merge branch 'revokable_api_tokens' of github.com:quackclub/hackatime…
matmanna 8a005db
refactor: remove unnecessary test line and switch to report_error
matmanna 34646e5
fix: returned name for admin & regular keys
matmanna 54012e5
Merge branch 'main' into revokable_api_tokens
matmanna b624b9b
Merge branch 'main' into revokable_api_tokens
matmanna File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
test/controllers/api/internal/revocations_controller_test.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| require "test_helper" | ||
|
|
||
| class Api::Internal::RevocationsControllerTest < ActionDispatch::IntegrationTest | ||
| setup do | ||
| @previous_revocation_key = ENV["HKA_REVOCATION_KEY"] | ||
| ENV["HKA_REVOCATION_KEY"] = "test-revocation-key" | ||
| end | ||
|
|
||
| teardown do | ||
| ENV["HKA_REVOCATION_KEY"] = @previous_revocation_key | ||
| end | ||
|
|
||
| test "revokes regular ApiKey by rolling token" do | ||
| user = User.create!(timezone: "UTC") | ||
| original_token = SecureRandom.uuid_v4 | ||
| key = user.api_keys.create!(name: "Desktop", token: original_token) | ||
|
|
||
| post "/api/internal/revoke", params: { token: original_token }, headers: auth_headers, as: :json | ||
|
|
||
| assert_response :success | ||
| assert_equal true, response.parsed_body["success"] | ||
|
|
||
| key.reload | ||
| assert_not_equal original_token, key.token | ||
| assert_nil ApiKey.find_by(token: original_token) | ||
matmanna marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| post "/api/internal/revoke", params: { token: original_token }, headers: auth_headers, as: :json | ||
|
|
||
| assert_response :success | ||
matmanna marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| assert_equal({ "success" => false }, response.parsed_body) | ||
| end | ||
|
|
||
| test "returns success false for valid regular UUID token that does not exist" do | ||
| token = SecureRandom.uuid_v4 | ||
|
|
||
| post "/api/internal/revoke", params: { token: token }, headers: auth_headers, as: :json | ||
|
|
||
| assert_response :success | ||
| assert_equal({ "success" => false }, response.parsed_body) | ||
| end | ||
|
|
||
| test "returns success false for token that matches neither regex" do | ||
| post "/api/internal/revoke", params: { token: "not-a-valid-token" }, headers: auth_headers, as: :json | ||
|
|
||
| assert_response :success | ||
| assert_equal({ "success" => false }, response.parsed_body) | ||
| end | ||
|
|
||
| test "returns success false when regular key revoke update fails" do | ||
| user = User.create!(timezone: "UTC") | ||
| colliding_token = SecureRandom.uuid_v4 | ||
| user.api_keys.create!(name: "Existing", token: colliding_token) | ||
|
|
||
| key = user.api_keys.create!(name: "Desktop") | ||
| original_token = key.token | ||
|
|
||
| with_stubbed_uuid_v4(colliding_token) do | ||
| post "/api/internal/revoke", params: { token: original_token }, headers: auth_headers, as: :json | ||
| end | ||
|
|
||
| assert_response :success | ||
matmanna marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| assert_equal({ "success" => false }, response.parsed_body) | ||
|
|
||
| key.reload | ||
| assert_equal original_token, key.token | ||
| end | ||
|
|
||
| test "revokes admin key" do | ||
| user = User.create!(timezone: "UTC") | ||
| admin_key = user.admin_api_keys.create!(name: "Infra", token: "hka_#{SecureRandom.hex(32)}") | ||
|
|
||
| post "/api/internal/revoke", params: { token: admin_key.token }, headers: auth_headers, as: :json | ||
|
|
||
| assert_response :success | ||
| assert_equal true, response.parsed_body["success"] | ||
|
|
||
| admin_key.reload | ||
| assert_not_nil admin_key.revoked_at | ||
| assert_includes admin_key.name, "_revoked_" | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def with_stubbed_uuid_v4(value) | ||
| original_uuid_v4 = SecureRandom.method(:uuid_v4) | ||
| SecureRandom.define_singleton_method(:uuid_v4) { value } | ||
| yield | ||
| ensure | ||
| SecureRandom.define_singleton_method(:uuid_v4, original_uuid_v4) | ||
| end | ||
matmanna marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def auth_headers | ||
| { | ||
| "Authorization" => ActionController::HttpAuthentication::Token.encode_credentials(ENV.fetch("HKA_REVOCATION_KEY")) | ||
| } | ||
| end | ||
| end | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.