-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Integrations Identity pipeline refactoring #6708
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
Integrations Identity pipeline refactoring #6708
Conversation
Security concerns found
Migration Checklist
Generated by 🚫 danger |
1917af7 to
a46346d
Compare
|
Assigning @dcramer since I know he knows this part of the code, but I know he's busy, so also assigning @alex-hofsteede for that knowledge share. |
| from sentry.utils.pipeline import PipelineProvider | ||
|
|
||
|
|
||
| class MigratingIdentityId(namedtuple('MigratingIdentityId', ['id', 'legacy_id'])): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, haven't seen this trick before. I'm guessing it's just to avoid a bunch of self.foo = foo boilerplate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I actually introduced this over here #6577, but am moving it into the identity module, and it will be removed from the auth provider later once the auth providers make use of the identity provider.
|
|
||
| class IdentityManager(object): | ||
| def __init__(self): | ||
| self.__values = {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the values are assumed to be providers, then can we call this __providers ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This manager was just copied over from other provider managers. The auth module and integration module both have one of these. At some point we'll likely want to just provide some general lookup manager that can be used to this fashion. It doesn't have anything specific to identity providers.
src/sentry/identity/__init__.py
Outdated
| register = default_manager.register | ||
| unregister = default_manager.unregister | ||
|
|
||
| # TODO(epurkhiser): needs to be initialized some other way |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this need to be addressed before merge?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the comment for this, but basically the idea is that this registering of the provider should happen with the slack plugin most likely.
| oauth_access_token_url = 'https://slack.com/api/oauth.access' | ||
| oauth_authorize_url = 'https://slack.com/oauth/authorize' | ||
| oauth_scopes = tuple(sorted(( | ||
| # TODO: Remove id and use key everywhere for integrations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was done right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, updated. good catch.
| assert resp.status_code == 200 | ||
| self.assertDialogSuccess(resp) | ||
|
|
||
| integration = Integration.objects.get(provider=self.provider.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need any more tests aside from the ones refactored here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some identity linking acceptance tests that I need to finish up, I'll try and get those in here, but I'd like to get this merged in sooner than later, I'll try and get those in, but otherwise they'll come in as a separate PR I think.
Other than that more tests will show up as we solidify more of what integration setup looks like from a configuration standpoint
582be30 to
8abad79
Compare
alex-hofsteede
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
mattrobenolt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This migration is a blocker. Let's chat IRL to come up with the plan.
| from sentry import options | ||
| from sentry.identity.oauth2 import OAuth2Provider | ||
|
|
||
| options.register('slack.client-id') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set flags=FLAG_PRIORITIZE_DISK at least on these since I assume we'll be hardcoding these for us in config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah these will be hardcoded in the configs. Updated here.
src/sentry/integrations/pipeline.py
Outdated
|
|
||
| __all__ = ['IntegrationPipeline'] | ||
|
|
||
| import json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use sentry.utils.json instead unless there was a reason not to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| unique_together = (('idp', 'external_id'),) | ||
|
|
||
|
|
||
| class UserIdentity(Model): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not actually drop this yet until a later migration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| __core__ = False | ||
|
|
||
| idp = FlexibleForeignKey('sentry.IdentityProvider') | ||
| user = FlexibleForeignKey(settings.AUTH_USER_MODEL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be nullable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| type = models.CharField(max_length=64) | ||
| instance = models.CharField(max_length=64) | ||
| organization = FlexibleForeignKey('sentry.Organization') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this migration is going to be problematic.
We need to come up with a transition plan. We can't drop and add these new columns at the same time, nor can we simply edit this unique_together, or add not nullable columns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
Talked IRL with @mattrobenolt. I've updated the description of the PR to note that the Identity models where not yet used anywhere outside of the V3 integration work, so the changes that were made to these tables can be safely be applied by dropping and recreating these tables as is done n the migrations here. I will still however need to update the IDs of the migrations. |
c4f666c to
448cc71
Compare
|
@mattrobenolt: bumped my migrations. |
e762f87 to
bad62a0
Compare
Refactors integrations to compose the identity provider found in the sentry.identity module.
bad62a0 to
2fd8285
Compare
|
Had to bump the migrations one more time because of #6147. Just need your sign off @mattrobenolt. |
mattrobenolt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Punch it.
Probably easiest to review the 4 commits individually.
This is a large refactoring of the v3 Integration setup pipeline to use a new style of user identity lookup, based on a new
identitymodule, which provides a pipeline + identity providers.This is the foundation for unifying the SSO Authentication identity, integrations identity, and (at some point probably in the far future) plugin identity (likely when they're moved to new-style integrations).
This implements the following:
The
identitymodule, which provides an Identity pipeline, with a generic identity associationfinish_pipelineimplementation. This may be used both directly as part of an identity association endpoint, as well as made part of a pipeline through thepipleline.NestedProviderView. A generic baseOAuth2provider is also implemented, which is mostly a copy and paste from both theauthmodule andintegrationmodules implementations (which this will replace).The OAuth identity provider supports scope customization through the pipeline config object.
The
models.identitymodule has been updated with models that more accurately reflect how Identity is stored.One identity per user
IdentityProvideris associated to an organization, allowing lookup of identity providers configured for an organization. Originally the idea was to have one identity provider per 'instance' of the identity provider, for example there'd be one Slack IDP since there's only one Sentry app on slack. However, with this implementation we'd stil need some way to know it's configured for an organization, and that linking table would likely take just as much space. Further, having a direct association to an identity provider makes generic identity association possible.Also Important to note is that these tables were not yet in use outside of the feature-flagged v3 integrations, so there are two migrations here, the first simply removes the tables, the second re-creates the tables using the updated model fields.
The Integrations base object has it's
idclass attribute renamed tokey. This is a little more clear as it differentiates it from the provider models database id.Integrations now compose the slack identity provider pipeline to do setup and store the setup users identity.