Skip to content
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

feat: github app refresh tokens #27

Merged
merged 2 commits into from
Aug 25, 2023
Merged

Conversation

giovanni-guidini
Copy link
Contributor

Adding support for github app refresh tokens.
This is currently an opt-in feature for github apps (what we use to auth users).

closes codecov/engineering-team#163

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. In 2022 this entity acquired Codecov and as result Sentry is going to need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@codecov
Copy link

codecov bot commented Aug 16, 2023

Codecov Report

Merging #27 (dd65a8e) into main (5fc16f4) will increase coverage by 0.05%.
Report is 2 commits behind head on main.
The diff coverage is 96.66%.

@@            Coverage Diff             @@
##             main      #27      +/-   ##
==========================================
+ Coverage   91.69%   91.75%   +0.05%     
==========================================
  Files          93       93              
  Lines        8107     8135      +28     
  Branches     1228     1234       +6     
==========================================
+ Hits         7434     7464      +30     
+ Misses        671      669       -2     
  Partials        2        2              
Flag Coverage Δ
python3.10.5 88.69% <93.33%> (+0.07%) ⬆️
python3.7.13 88.53% <90.00%> (+0.05%) ⬆️
python3.8.13 88.76% <90.00%> (+0.05%) ⬆️
python3.9.12 89.11% <90.00%> (+0.05%) ⬆️
rust 89.75% <ø> (ø)
smart-labels 92.27% <96.66%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Changed Coverage Δ
shared/encryption/token.py 100.00% <ø> (ø)
shared/torngit/github.py 95.89% <96.66%> (+0.61%) ⬆️

@giovanni-guidini giovanni-guidini force-pushed the gio/gh-refresh-tokens branch 2 times, most recently from 317057b to a79b65b Compare August 16, 2023 20:21
@giovanni-guidini giovanni-guidini marked this pull request as ready for review August 16, 2023 20:28
@giovanni-guidini
Copy link
Contributor Author

The one "issue" we have is that I don't know a good way to check if the token is expired or not. Gitlab had a specific way of telling us "this request failed because the token expired", but Github just say "Bad credentials". (I couldn't find in the docs reference to this, I just tested it with a revoked token)

So we try to refresh on all 401 errors :E

giovanni-guidini added a commit to codecov/codecov-api that referenced this pull request Aug 17, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
Adding support for github app refresh tokens.
This is currently an opt-in feature for github apps (what we use to auth users).

We only try to refresh the token if the reqeust that failed is to the GIthub API

closes codecov/engineering-team#163
giovanni-guidini added a commit to codecov/codecov-api that referenced this pull request Aug 17, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
giovanni-guidini added a commit to codecov/worker that referenced this pull request Aug 17, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
giovanni-guidini added a commit to codecov/worker that referenced this pull request Aug 17, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
Copy link
Contributor

@scott-codecov scott-codecov left a comment

Choose a reason for hiding this comment

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

This looks good to me. Like we chatted about earlier I'm just a little curious about the sequence of releasing this. Current tokens never expire and don't have a refresh token. What's the smoothest way to roll this out?

If the currently issued tokens still never expire (and only new logins have expiring tokens + refresh tokens) then it might make sense to not raise TorngitCantRefreshTokenError when missing a refresh_token. Might be worth testing out the transition from non-expiring token GitHub app -> expiring token GitHub app and see what happens w/ old tokens.

@giovanni-guidini
Copy link
Contributor Author

giovanni-guidini commented Aug 18, 2023

I agree that we need to test the transition.

About

If the currently issued tokens still never expire (and only new logins have expiring tokens + refresh tokens) then it might make sense to not raise TorngitCantRefreshTokenError when missing a refresh_token.

Well we only raise that if we try to refresh the token. If it never expires it shouldn't 401 and therefore we won't ever try to refresh it :E

EDIT
As I was testing this a new situation appeared. If you go in the UI and try to see your code we make a request to get content. That fails with 404 instead of 401 😅 so I'll have to add that detail in (retry on 404 if content is in the URL). In light of 404 being more common than 401 I will not raise exception and just return the current token. It's an extra retry on a fail request, but maybe we can tolerate that?

Make sure we continue to support the current case, where github
doesn't send a refresh_token when getting the access_token

If we try to refresh wihtout the refresh_token info we return `None` and do nothing.

Also there are many endpoints from Github (under `/repos/<repo_slug>/...` that return 404
rather than 401. This is on purpose for security, but makes it harder for us.
SO we are now also retrying in 404 if the url path starts like that.

It is possible that we will try to refresh when we shouldn't.
I tried to improve the exception messages for that case, and we can revisit the retry logic
if we notice we are trying to refresh more tokens than expected and getting too many errors.
Copy link
Contributor

@matt-codecov matt-codecov left a comment

Choose a reason for hiding this comment

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

seconding scott's Q about rolling this out. do we want to phase out the non-expiring tokens? did we do anything like that for GitLab? looks like you addressed scott's feedback about raising TorngitCantRefreshTokenError, but there remain a couple dead references to it in the PR

if multiple api requests/worker tasks (particularly the latter) are spinning up at once, i'm worried they'll get stuck in a cycle of invalidating each others' tokens which will spawn a bunch of unnecessary API requests and hurt performance. i think that's worth solving, but maybe in a separate PR as it would involve changing the GitLab implementation as well. this PR is equivalent to the GitLab implementation and the tests are thorough so i'll approve

incidentally, i noticed that _on_token_refresh()/get_token_refresh_callback() is only populated in worker/services/repository.py and worker/services/repo_providers.py and is missing from worker/services/owner.py (and maybe other places). didn't check API, but that's a bug in worker at least

@giovanni-guidini giovanni-guidini merged commit 5e3ba08 into main Aug 25, 2023
14 checks passed
@giovanni-guidini giovanni-guidini deleted the gio/gh-refresh-tokens branch August 25, 2023 14:40
giovanni-guidini added a commit to codecov/codecov-api that referenced this pull request Aug 30, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
giovanni-guidini added a commit to codecov/worker that referenced this pull request Aug 30, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
giovanni-guidini added a commit to codecov/worker that referenced this pull request Sep 5, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
giovanni-guidini added a commit to codecov/worker that referenced this pull request Sep 5, 2023
Depends on codecov/shared#27

Adds support for github app refresh tokens

context: codecov/engineering-team#162
giovanni-guidini added a commit to codecov/codecov-api that referenced this pull request Sep 6, 2023
Depends on codecov/shared#27
TODO: after that is merged update the sha reference in requirements.in

Adds support for github app refresh tokens

codecov/engineering-team#162
giovanni-guidini added a commit to codecov/codecov-api that referenced this pull request Sep 6, 2023
Depends on codecov/shared#27


Adds support for github app refresh tokens

only include token refresh callback if token is from owner
trent-codecov added a commit to codecov/codecov-api that referenced this pull request Sep 7, 2023
* ImportError: cannot import name should_write_data_to_storage_config_c… (#104)

* ImportError: cannot import name should_write_data_to_storage_config_check

* Update VERSION

* feat: Django command to enqueue commit backfill tasks (#102)

* feat: Django command to enqueue commit backfill tasks

* Fetch only commit id and commitid

* chore: Update Sentry config keys to be more consistent with other services (#103)

* Fix/config error enterprise (#107)

* Fix config error

* Fix config error

* Add RiskyAlterField to utils/migrations (#93)

* Add RiskyAlterField to utils/migrations

* Remove duplicate RiskyAddField class

Signed-off-by: joseph-sentry <[email protected]>

* feat: support gh refresh tokens (#85)

Depends on codecov/shared#27


Adds support for github app refresh tokens

only include token refresh callback if token is from owner

* Make uses_invoice field on Owner(#92)

* Add uses_invoice field to Owner using RiskyAddField
* Set default to False for uses_invoice field on Owner
* Make uses_invoice field in Owner non-nullable
* Fix uses_invoice column migrations

Signed-off-by: joseph-sentry <[email protected]>

* fix: Include impacted files with no coverage diff and no indirect changes in direct changes list (#114)

* Add 23.9.5 migration

* update to handle to redirects (#113)

* Adjust donwload_url link (#115)

* Add changes for monthly uploads to account for trialing customer (#101)

* Add changes for monthly uploads to account for trialing customer

* Adjust filtering logic when trialing

* Add 23.9.5 migration

---------

Signed-off-by: joseph-sentry <[email protected]>
Co-authored-by: scott-codecov <[email protected]>
Co-authored-by: joseph-sentry <[email protected]>
Co-authored-by: Giovanni M Guidini <[email protected]>
Co-authored-by: Rula Abuhasna <[email protected]>
Co-authored-by: Adrian <[email protected]>
trent-codecov added a commit to codecov/codecov-api that referenced this pull request Sep 7, 2023
* ImportError: cannot import name should_write_data_to_storage_config_c… (#104)

* ImportError: cannot import name should_write_data_to_storage_config_check

* Update VERSION

* feat: Django command to enqueue commit backfill tasks (#102)

* feat: Django command to enqueue commit backfill tasks

* Fetch only commit id and commitid

* chore: Update Sentry config keys to be more consistent with other services (#103)

* Fix/config error enterprise (#107)

* Fix config error

* Fix config error

* Add RiskyAlterField to utils/migrations (#93)

* Add RiskyAlterField to utils/migrations

* Remove duplicate RiskyAddField class

Signed-off-by: joseph-sentry <[email protected]>

* feat: support gh refresh tokens (#85)

Depends on codecov/shared#27


Adds support for github app refresh tokens

only include token refresh callback if token is from owner

* Make uses_invoice field on Owner(#92)

* Add uses_invoice field to Owner using RiskyAddField
* Set default to False for uses_invoice field on Owner
* Make uses_invoice field in Owner non-nullable
* Fix uses_invoice column migrations

Signed-off-by: joseph-sentry <[email protected]>

* fix: Include impacted files with no coverage diff and no indirect changes in direct changes list (#114)

* Add 23.9.5 migration

* update to handle to redirects (#113)

* Adjust donwload_url link (#115)

* Add changes for monthly uploads to account for trialing customer (#101)

* Add changes for monthly uploads to account for trialing customer

* Adjust filtering logic when trialing

* Add 23.9.5 migration

---------

Signed-off-by: joseph-sentry <[email protected]>
Co-authored-by: scott-codecov <[email protected]>
Co-authored-by: joseph-sentry <[email protected]>
Co-authored-by: Giovanni M Guidini <[email protected]>
Co-authored-by: Rula Abuhasna <[email protected]>
Co-authored-by: Adrian <[email protected]>
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.

Implement refresh token handling for Github
3 participants