use API token for oauth client secret

rather than a separate single-purpose secret

since we need the token anyway, use it for the secret handshake as well
This commit is contained in:
Min RK
2017-04-04 17:12:02 +02:00
parent d11c7ba4db
commit 6d647b5387
6 changed files with 6 additions and 32 deletions

View File

@@ -1086,7 +1086,7 @@ class JupyterHub(Application):
client_store.add_client( client_store.add_client(
client_id=service.oauth_client_id, client_id=service.oauth_client_id,
client_secret=service.oauth_client_secret, client_secret=service.api_token,
redirect_uri=host + url_path_join(service.prefix, 'oauth_callback'), redirect_uri=host + url_path_join(service.prefix, 'oauth_callback'),
) )
else: else:

View File

@@ -418,17 +418,7 @@ class HubOAuth(HubAuth):
def _client_id(self): def _client_id(self):
return os.getenv('JUPYTERHUB_CLIENT_ID', '') return os.getenv('JUPYTERHUB_CLIENT_ID', '')
oauth_client_secret = Unicode( @validate('oauth_client_id', 'api_token')
help="""The OAuth client secret for this application.
Use JUPYTERHUB_CLIENT_SECRET by default.
"""
).tag(config=True)
@default('oauth_client_secret')
def _client_secret(self):
return os.getenv('JUPYTERHUB_CLIENT_SECRET', '')
@validate('oauth_client_id', 'oauth_client_secret')
def _ensure_not_empty(self, proposal): def _ensure_not_empty(self, proposal):
if not proposal.value: if not proposal.value:
raise ValueError("%s cannot be empty." % proposal.trait.name) raise ValueError("%s cannot be empty." % proposal.trait.name)
@@ -472,7 +462,7 @@ class HubOAuth(HubAuth):
# GitHub specifies a POST request yet requires URL parameters # GitHub specifies a POST request yet requires URL parameters
params = dict( params = dict(
client_id=self.oauth_client_id, client_id=self.oauth_client_id,
client_secret=self.oauth_client_secret, client_secret=self.api_token,
grant_type='authorization_code', grant_type='authorization_code',
code=code, code=code,
redirect_uri=self.oauth_redirect_uri, redirect_uri=self.oauth_redirect_uri,

View File

@@ -211,17 +211,6 @@ class Service(LoggingConfigurable):
def _default_client_id(self): def _default_client_id(self):
return 'service-%s' % self.name return 'service-%s' % self.name
oauth_client_secret = Unicode(
help="""OAuth client secret for this service.
Default: Generated on each launch.
"""
).tag(input=True)
@default('oauth_client_secret')
def _default_client_secret(self):
self.log.debug("Generating new OAuth secret for service %s", self.name)
return new_token()
@property @property
def server(self): def server(self):
return self.orm.server return self.orm.server
@@ -267,7 +256,6 @@ class Service(LoggingConfigurable):
environment=env, environment=env,
api_token=self.api_token, api_token=self.api_token,
oauth_client_id=self.oauth_client_id, oauth_client_id=self.oauth_client_id,
oauth_client_secret=self.oauth_client_secret,
cwd=self.cwd, cwd=self.cwd,
user=_MockUser( user=_MockUser(
name=self.user, name=self.user,

View File

@@ -53,7 +53,6 @@ class Spawner(LoggingConfigurable):
admin_access = Bool(False) admin_access = Bool(False)
api_token = Unicode() api_token = Unicode()
oauth_client_id = Unicode() oauth_client_id = Unicode()
oauth_client_secret = Unicode()
will_resume = Bool(False, will_resume = Bool(False,
help="""Whether the Spawner will resume on next start help="""Whether the Spawner will resume on next start
@@ -394,7 +393,6 @@ class Spawner(LoggingConfigurable):
Subclasses should call super, to ensure that state is properly cleared. Subclasses should call super, to ensure that state is properly cleared.
""" """
self.api_token = '' self.api_token = ''
self.oauth_client_secret = ''
def get_env(self): def get_env(self):
"""Return the environment dict to use for the Spawner. """Return the environment dict to use for the Spawner.
@@ -433,7 +431,6 @@ class Spawner(LoggingConfigurable):
env['JUPYTERHUB_ADMIN_ACCESS'] = '1' env['JUPYTERHUB_ADMIN_ACCESS'] = '1'
# OAuth settings # OAuth settings
env['JUPYTERHUB_CLIENT_ID'] = self.oauth_client_id env['JUPYTERHUB_CLIENT_ID'] = self.oauth_client_id
env['JUPYTERHUB_CLIENT_SECRET'] = self.oauth_client_secret
# Put in limit and guarantee info if they exist. # Put in limit and guarantee info if they exist.
# Note that this is for use by the humans / notebook extensions in the # Note that this is for use by the humans / notebook extensions in the

View File

@@ -255,7 +255,7 @@ class StubSingleUserSpawner(MockSpawner):
app = self._app = MockSingleUserServer() app = self._app = MockSingleUserServer()
app.initialize(args) app.initialize(args)
assert app.hub_auth.oauth_client_id assert app.hub_auth.oauth_client_id
assert app.hub_auth.oauth_client_secret assert app.hub_auth.api_token
app.start() app.start()
self._thread = threading.Thread(target=_run) self._thread = threading.Thread(target=_run)

View File

@@ -256,8 +256,7 @@ class User(HasTraits):
# create a new OAuth client + secret on every launch, # create a new OAuth client + secret on every launch,
# except for resuming containers. # except for resuming containers.
if oauth_client is None or not spawner.will_resume: if oauth_client is None or not spawner.will_resume:
spawner.oauth_client_secret = client_secret = new_token() client_store.add_client(client_id, api_token,
client_store.add_client(client_id, client_secret,
url_path_join(server.base_url, 'oauth_callback'), url_path_join(server.base_url, 'oauth_callback'),
) )
db.commit() db.commit()