Skip to content

feat(integrations): github enterprise support #8348

Merged
MeredithAnya merged 36 commits intomasterfrom
feat/github-enterprise
May 22, 2018
Merged

feat(integrations): github enterprise support #8348
MeredithAnya merged 36 commits intomasterfrom
feat/github-enterprise

Conversation

@MaxBittker
Copy link
Copy Markdown
Contributor

@MaxBittker MaxBittker commented May 8, 2018

@MaxBittker MaxBittker added the WIP label May 8, 2018
@benvinegar
Copy link
Copy Markdown
Contributor

In keeping with our Python filename conventions, should we not rename the githubEnterprise folder to github_enterprise?

@mattrobenolt
Copy link
Copy Markdown
Contributor

In keeping with our Python filename conventions, should we not rename the githubEnterprise folder to github_enterprise?

Yes. And don't use capital letters in filenames.

@MaxBittker MaxBittker force-pushed the feat/github-enterprise branch from 6d18402 to 1f8fc12 Compare May 9, 2018 17:49
@MaxBittker MaxBittker force-pushed the feat/github-enterprise branch from 21f4ff2 to 7c6a34b Compare May 10, 2018 17:38
Comment thread src/sentry/http.py Outdated
allow_redirects=False,
timeout=30,
verify_ssl=True,
verify_ssl=False,
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.

these are in here temporarily because the github enterprise test instance doesn't have a valid cert

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's not forget to turn this off, or at least make it a configuration of the integration or something.

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.

👀

This should absolutely be configurable in the integration. It's likely that more than 0 GH enterprise installs use an non-standard cert. Whether it's an internally trusted cert, self signed, something that we can't validate.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah, it will have to be a toggle on in the configuration form.

Comment thread src/sentry/identity/oauth2.py Outdated
if self.oauth_access_token_url is not '':
return self.oauth_access_token_url

# # check the model for instalation information
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.

these commented out blocks will be used later when the installation flow has completed successfully

Comment thread src/sentry/identity/oauth2.py Outdated
return [
OAuth2LoginView(
authorize_url=self.oauth_authorize_url,
lambda: OAuth2LoginView(
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.

this was needed to be postponed because we can't evaluate the urls until earlier parts of the flow have completed

installation_data = state['installation_data']
# user = get_user_info(installation_data['url'], identity['access_token'])
# this doesn't work yet (404s):
installation = self.get_installation_info(
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.

this is the main issue right now.

Copy link
Copy Markdown
Member

@MeredithAnya MeredithAnya May 15, 2018

Choose a reason for hiding this comment

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

I think you were maybe using the wrong id?

self.provider_model = provider_model

self.config = config
self.provider.set_pipeline(self)
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.

this is definitely why the tests are failing. @MeredithAnya tomorrow maybe you can try removing this change and seeing what breaks for GHE?

and/or @evanpurkhiser do you by chance have any context into why this change would be necessary?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is for sure needed so that the provider is able to lookup the OAuth configuration from the parent pipleine (available on the executing pipeline). I'll take a look at tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should be fixed. The tests overrode the variable this assigned to.

Comment thread src/sentry/http.py Outdated
allow_redirects=False,
timeout=30,
verify_ssl=True,
verify_ssl=False,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's not forget to turn this off, or at least make it a configuration of the integration or something.

self.config = config
self.logger = logging.getLogger('sentry.identity.%s'.format(self.key))

def get_pipeline(self):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you pull this into a separate PR. This is pretty unrelated and just about removing a totally unused abstract method.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

from sentry.identity.oauth2 import OAuth2Provider


def get_user_info(url, access_token):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe we can have this reused in the github integration? Definitely some duplication here. Or maybe this can get sucked into the github client.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@macqueen thoughts here? I could also put it in github/utils with the jwt stuff if that makes sense

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

punting on this.

return resp


class GitHubEnterpriseIdentityProvider(OAuth2Provider):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can this just extend GithubIdentityProvider and override the key and name?

Copy link
Copy Markdown
Member

@MeredithAnya MeredithAnya May 18, 2018

Choose a reason for hiding this comment

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

the GitHubIdentityProvider also has other methods and whatnot that the GHE doesn't need so wouldn't you just end up needing to overriding those too?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah okay, that makes sense. This is fine.

def build_identity(self, data):
data = data['data']

user = get_user_info(data['access_token'])
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This call is wrong, doesn't provide the url.

GitHubEnterpriseInstallationRedirect(),
identity_pipeline_view]

def get_installation_info(self, installation_data, access_token, installation_id):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It would be nice for this to be abstracted between the two github integrations.

logger = logging.getLogger('sentry.integrations.github-enterprise')


class GitHubEnterpriseAppsEndpoint(Endpoint):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are these webhooks going to be so different that we have to use an entirely different endpoint?

'redirect_url': absolute_uri('/extensions/github-enterprise/setup/'),
}

identity_pipeline_view = NestedPipelineView(
Copy link
Copy Markdown
Member

@evanpurkhiser evanpurkhiser May 17, 2018

Choose a reason for hiding this comment

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

Okay so I realized, because we now allow for late binding of pipeline steps, we can actually do a better job providing the oauth parameters to the identity pipeline through it's config object, versus it expecting to find it in a parent pipeline. How about this

If we have a helper method to construct the identity pipeline view

def _make_identity_pipeline_view(self):
    """
    Make the nested identity provider view. It is important that this view is
    not constructed until we reach this step and the
    ``oauth_config_information`` is available in the pipeline state. This
    method should be late bound into the pipeline vies.
    """

    identity_pipeline_config = dict(
        oauth_scopes=(),
        redirect_url=absolute_uri('/extensions/github-enterprise/setup/'),
        *self.pipeline.fetch_state('oauth_config_information'),
    )

    return NestedPipelineView(
        bind_key='identity',
        provider_key='github-enterprise',
        pipeline_cls=IdentityProviderPipeline,
        config=identity_pipeline_config,
    )

Then in the get_pipeline_views

return [
    InstallationConfigView(),
    GitHubEnterpriseInstallationRedirect(),

    # The identity provider pipeline should be constructed at execution
    # time, this allows for the oauth configuration parameters to be made
    # available from the installation config view.
    lambda: self._make_identity_pipeline_view(),
]

Comment thread src/sentry/pipeline/__init__.py Outdated

def set_pipeline(self, pipeline):
"""
todo(maxbittker)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should probably say something along the lines of

Used by the pipeline to give the provider access to the executing pipeline.

self.provider_model = provider_model

self.config = config
self.provider.set_pipeline(self)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should be fixed. The tests overrode the variable this assigned to.

Copy link
Copy Markdown
Member

@evanpurkhiser evanpurkhiser left a comment

Choose a reason for hiding this comment

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

A couple minor nits, but looks awesome. Great work @MaxBittker and @MeredithAnya!

Comment thread src/sentry/identity/oauth2.py Outdated
if model and model.config.get(parameter_name) is not None:
return model.config.get(parameter_name)

raise KeyError
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you give this a message like

KeyError(u'Unable to resolve OAuth parameter "{}"'.format(parameter_name))

Comment thread src/sentry/identity/oauth2.py Outdated
return [
OAuth2LoginView(
authorize_url=self.oauth_authorize_url,
lambda: OAuth2LoginView(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can switch these back to being initialized at class construction time.

@MeredithAnya MeredithAnya merged commit f30320b into master May 22, 2018
@MeredithAnya MeredithAnya deleted the feat/github-enterprise branch May 22, 2018 16:07
defaults={'config': identity_config},
)

if created:
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.

@MeredithAnya should this be if not created

@github-actions github-actions Bot locked and limited conversation to collaborators Dec 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants