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

[Globus] Remove the need for globus_sdk as a python dependency #337

Merged
merged 1 commit into from
Jun 11, 2020

Conversation

NickolausDS
Copy link
Contributor

The Globus OAuthenticator currently requires a custom dependency
in order to authenticate users. The Globus SDK was originally
chosen for its convenience functions in generating URLs and
automatically structuring tokens. However, it's not necessary
and can be replaced with generic components included in this
repo.

With these changes, the globus_sdk can also be removed from the
Zero to Jupyterhub 'hub' dependencies. While the globus_sdk is
extremely useful for transferring data within the Single User
Server, in the hub it is only used for the OAuthenticator.

self.log.info(
'Logout: Revoked tokens for user "{}" services: {}'.format(
user.name, ','.join(state['tokens'].keys())
)
)
state['tokens'] = ''
state['tokens'] = {}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a minor change, unrelated to removing the Globus SDK. Unit testing caught that it's possible to get tripped up by the type changing from dict to str, although in practice I think it would be difficult to get into a state where this caused an error. This change keeps types consistent, just in case.

@@ -79,7 +96,7 @@ def _authorize_url_default(self):
).tag(config=True)

def _identity_provider_default(self):
return os.getenv('IDENTITY_PROVIDER', 'globusid.org')
return os.getenv('IDENTITY_PROVIDER', '')
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is another change unrelated to streamlining dependencies, but I think it's preferable. The previous value of globusid.org essentially locks down the default installation to an identity almost nobody uses. Setting this to the empty string allows the user to login with any IdP initially.


def _allow_refresh_tokens_default(self):
return True

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the last refactor pulled out the code that could request refresh tokens, so this feature is no longer usable. In order to request refresh tokens, an additional parameter needs to be sent through the first leg of the OAuth flow.

for tok, v in tokens.by_resource_server.items()
if tok not in self.exclude_tokens
},
'tokens': by_resource_server,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The whole authenticate() method is very similar to the GenericOAuthenticator, where the only functional difference is the shape of tokens it returns. When the admin sets custom scopes, including scopes for third party resource servers secured with Globus Auth, the access/refresh tokens will come through the other_tokens key. If the admin didn't enable auth_state, this method behaves much the same as the GenericOAuthenticator

auth_state = await mock_globus_user.get_auth_state()
assert auth_state == {'tokens': ''}
assert auth_state == {'tokens': {}}
Copy link
Contributor Author

@NickolausDS NickolausDS Mar 6, 2020

Choose a reason for hiding this comment

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

Globus Test coverage is now 100%!

@NickolausDS NickolausDS force-pushed the streamline-globus-dependencies branch from 0435442 to 28b5dac Compare March 10, 2020 14:14
@NickolausDS
Copy link
Contributor Author

Rebased to include fixes for Generic tests #339. All tests pass!

The Globus OAuthenticator currently requires a custom dependency
in order to authenticate users. The Globus SDK was originally
chosen for its convenience functions in generating URLs and
automatically structuring tokens. However, it's not necessary
and can be replaced with generic components included in this
repo.

With these changes, the globus_sdk can also be removed from the
Zero to Jupyterhub 'hub' dependencies. While the globus_sdk is
extremely useful for transferring data within the Single User
Server, in the hub it is only used for the OAuthenticator.
@NickolausDS NickolausDS force-pushed the streamline-globus-dependencies branch from 28b5dac to b180ccc Compare March 23, 2020 15:34
@NickolausDS
Copy link
Contributor Author

Rebased on #343, which better organized the globus_sdk dependency install for Globus. These changes remove that dependency entirely to bring the Globus OAuthenticator more inline with how the other OAuthenticators work, instead of relying on oauth2 shortcuts within the globus_sdk. The implementation here is very similar to the Generic OAuthenticator, with some extensions to token handling to allow Globus Transfer tokens and any other third party tokens for user-created services.

@consideRatio
Copy link
Member

@NickolausDS I ran out of time for the moment to review the full PR, but I read through 50% and think everything has made sense so far. I also concluded that you are in this PR changing files in a way that will only influence globus.

@NickolausDS
Copy link
Contributor Author

@consideRatio Correct, this only modifies Globus.

#338 does affect this PR (it brings back refresh tokens), but I didn't want to add major changes outside of globus.py and test_globus.py, and so put it in a separate PR. Happy to do the same with other changes here, if you think they warrant further discussion.

Thanks for reviewing!

Copy link
Member

@minrk minrk left a comment

Choose a reason for hiding this comment

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

Thanks for the awesome PR and comments, and for your patience. I'm digging myself out of a PR review backlog, but slowly getting through it. Carefully commented PRs like this one are a huge help!

# Default scopes are below if unspecified. Add a custom transfer server if you have one.
c.LocalGlobusOAuthenticator.scope = ['openid', 'profile', 'urn:globus:auth:scope:transfer.api.globus.org:all']
c.GlobusOAuthenticator.scope = ['openid', 'profile', 'urn:globus:auth:scope:transfer.api.globus.org:all']
Copy link
Member

Choose a reason for hiding this comment

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

👍

@@ -113,7 +113,6 @@ def run(self):

setup_args['extras_require'] = {
'googlegroups': ['google-api-python-client==1.7.11', 'google-auth-oauthlib==0.4.1'],
'globus': ['globus_sdk[jwt]>=1.0.0,<2.0.0']
Copy link
Member

Choose a reason for hiding this comment

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

Awesome!

@minrk minrk merged commit a1a03a1 into jupyterhub:master Jun 11, 2020
@consideRatio consideRatio changed the title Streamline Globus requirements [Globus] Remove the need for globus_sdk as a requirement Oct 26, 2020
@consideRatio consideRatio changed the title [Globus] Remove the need for globus_sdk as a requirement [Globus] Remove the need for globus_sdk as a python dependency Oct 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants