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: Add Sentry OAuth and current user endpoint #19

Merged
merged 5 commits into from
Jul 25, 2023

Conversation

scott-codecov
Copy link
Contributor

@scott-codecov scott-codecov commented Jul 19, 2023

Purpose/Motivation

Login with Sentry

Links to relevant tickets

codecov/engineering-team#87
codecov/engineering-team#88

What does this PR do?

  • adds a Sentry OAuth flow available at /login/sentry
  • adds a new table codecov_auth_sentryuser which stores Senty user info + access token and belongs to a single User
  • adds a new /internal/user endpoint for returning the current user info
    • 401 if not authenticated
    • includes a list of owners to which the current user is linked
    • this will be used by Gazebo to determine if there's an authenticated user (even outside the presence of a Git service) - and perhaps later for displaying a list of linked owners that the user can switch between

TODO

Sentry folks are still working on the OIDC implementation. At the very least we should try decoding the id_token (a JWT) using a shared secret that we were given. This way we can ensure the OAuth callback redirect is indeed being made by Sentry.

@codecov
Copy link

codecov bot commented Jul 19, 2023

Codecov Report

Merging #19 (d7a5e64) into main (afd582c) will increase coverage by 0.03%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##            main     #19     +/-   ##
=======================================
+ Coverage   95.22   95.25   +0.03     
=======================================
  Files        564     568      +4     
  Lines      14178   14287    +109     
=======================================
+ Hits       13500   13609    +109     
  Misses       678     678             
Flag Coverage Δ
unit 95.25% <100.00%> (+0.03%) ⬆️
unit-latest-uploader 95.25% <100.00%> (+0.03%) ⬆️

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

Files Changed Coverage Δ
api/internal/urls.py 97.36% <100.00%> (+0.07%) ⬆️
api/internal/user/serializers.py 100.00% <100.00%> (ø)
api/internal/user/views.py 100.00% <100.00%> (ø)
codecov/settings_base.py 84.11% <100.00%> (+0.18%) ⬆️
codecov_auth/migrations/0033_sentryuser.py 100.00% <100.00%> (ø)
codecov_auth/models.py 98.83% <100.00%> (+0.02%) ⬆️
codecov_auth/tests/factories.py 100.00% <100.00%> (ø)
codecov_auth/urls.py 100.00% <100.00%> (ø)
codecov_auth/views/sentry.py 100.00% <100.00%> (ø)

* main:
  Add api_health endpoint
  Move `Commit.report` to GCS (#10)
  fix: Set SameSite=None; Secure for sessionid cookie
  delete unnecessary redacted secrets from config
  Get rid of reduntant validation error
  Update shared. (#20)
  fix: Handle no current owner in GraphQL resolvers
  Return and catch validation error
  Addressed feedback
  Add mutation to start trial
Copy link
Contributor

@adrian-codecov adrian-codecov left a comment

Choose a reason for hiding this comment

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

Left some comments but looks good overall. Is there a way to test this by setting sentry local + pairing it with the gazebo client code?

@@ -455,6 +455,8 @@
"setup", "sentry", "jwt_shared_secret", default=None
)
SENTRY_USER_WEBHOOK_URL = get_config("setup", "sentry", "webhook_url", default=None)
SENTRY_OAUTH_CLIENT_ID = get_config("setup", "sentry", "oauth_client_id")
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these secrets stored already in k8s? And are there secret values to play with local too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not yet - just got these last Friday - I'll open a k8s-v2 PR to add the values and link it here.

To test things locally you can create an OAuth app in Sentry under your personal account: https://codecov.sentry.io/settings/account/api/applications/

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds good, yeah as long as you can test that locally yourself that sounds good to me 👌

class Migration(migrations.Migration):

dependencies = [
("codecov_auth", "0031_user_owner_user"),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you'll have to rerun this migration cause the latest trial one is a 0032 and will have migration name violation


# TEMPORARY: we're assuming a single owner for the time being since there's
# no supporting UI to select which owner you'd like to view
owner = current_user.owners.first()
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you know if we eventually want to redirect to the default owner if there's one? If so might be worth leaving a comment here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not really sure. I dunno if there will be a concept of a default owner - we might just redirect to a list of possible owners and you pick one? I dunno.

Copy link
Contributor

Choose a reason for hiding this comment

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

gotcha gotcha, the other login routes have a way to pick this up, but I don't expect that to be part of the 1st pass, maybe more of a mental note for the future

# user has not connected any owners yet
return redirect(f"{settings.CODECOV_DASHBOARD_URL}/sync")

def _login_user(self, request: HttpRequest, user_data: dict):
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there generally a way to automatically map a dictionary to a dataclass or a typedDict? Like a utility to do so? Not necessarily for this PR but I think can come in handy in the future

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's possible to declare the types for everything in a dict using TypedDict: https://peps.python.org/pep-0589/

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeaah, what I'm thinking is in situations like this, or when we use Stripe for instance, we expect a dictionary from a webhook or from another server's response and we don't type those. Im wondering if there's a way to automatically pass dictionaries into some utility/middleware to transform any dictionary into its dataclass/typeddict equivalent so we always have the shape of an object you know? Not for this, but that would be something neat

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, like auto generate the TypedDict definition based on some data we pass? That could be convenient but we'd still need to review the third-party docs and make sure each type is potentially nullable, etc. Our example data might not be representative of every case.

* main:
  conflicts merge + pr review feedback
  More PR feedback review
  Adjust code based on PR feedback
  Added command to add initital value for trial status
  Minor test+logic adjustment
  Modified plan + billing file
  adjusted tests and got rid of prints
  Use plan service thorughout the codebase
@scott-codecov scott-codecov merged commit 41f01a0 into main Jul 25, 2023
7 of 8 checks passed
@scott-codecov scott-codecov deleted the scott/sentry-oauth branch July 25, 2023 14:34
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.

None yet

2 participants