mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-07 18:14:10 +00:00
expose cookie options and pass them down to spawners
enables forcing all-session cookies with: ```python c.JupyterHub.tornado_settings['cookie_options'] = { 'expires_days': None, } ```
This commit is contained in:
@@ -30,7 +30,10 @@ from tornado.httputil import url_concat
|
||||
from tornado.web import HTTPError, RequestHandler
|
||||
|
||||
from traitlets.config import SingletonConfigurable
|
||||
from traitlets import Unicode, Integer, Instance, default, observe, validate
|
||||
from traitlets import (
|
||||
Unicode, Integer, Instance, Dict,
|
||||
default, observe, validate,
|
||||
)
|
||||
|
||||
from ..utils import url_path_join
|
||||
|
||||
@@ -197,6 +200,24 @@ class HubAuth(SingletonConfigurable):
|
||||
help="""The name of the cookie I should be looking for"""
|
||||
).tag(config=True)
|
||||
|
||||
cookie_options = Dict(
|
||||
help="""Additional options to pass when setting cookies.
|
||||
|
||||
Can include things like `expires_days=None` for session-expiry
|
||||
or `secure=True` if served on HTTPS and default HTTPS discovery fails
|
||||
(e.g. behind some proxies).
|
||||
"""
|
||||
).tag(config=True)
|
||||
|
||||
@default('cookie_options')
|
||||
def _default_cookie_options(self):
|
||||
# load default from env
|
||||
options_env = os.environ.get('JUPYTERHUB_COOKIE_OPTIONS')
|
||||
if options_env:
|
||||
return json.loads(options_env)
|
||||
else:
|
||||
return {}
|
||||
|
||||
cookie_cache_max_age = Integer(help="DEPRECATED. Use cache_max_age")
|
||||
@observe('cookie_cache_max_age')
|
||||
def _deprecated_cookie_cache(self, change):
|
||||
@@ -580,6 +601,8 @@ class HubOAuth(HubAuth):
|
||||
}
|
||||
if handler.request.protocol == 'https':
|
||||
kwargs['secure'] = True
|
||||
# load user cookie overrides
|
||||
kwargs.update(self.cookie_options)
|
||||
handler.set_secure_cookie(
|
||||
cookie_name,
|
||||
b64_state,
|
||||
@@ -627,6 +650,8 @@ class HubOAuth(HubAuth):
|
||||
}
|
||||
if handler.request.protocol == 'https':
|
||||
kwargs['secure'] = True
|
||||
# load user cookie overrides
|
||||
kwargs.update(self.cookie_options)
|
||||
app_log.debug("Setting oauth cookie for %s: %s, %s",
|
||||
handler.request.remote_ip, self.cookie_name, kwargs)
|
||||
handler.set_secure_cookie(
|
||||
|
@@ -218,6 +218,7 @@ class Service(LoggingConfigurable):
|
||||
base_url = Unicode()
|
||||
db = Any()
|
||||
orm = Any()
|
||||
cookie_options = Dict()
|
||||
|
||||
oauth_provider = Any()
|
||||
|
||||
@@ -299,6 +300,7 @@ class Service(LoggingConfigurable):
|
||||
environment=env,
|
||||
api_token=self.api_token,
|
||||
oauth_client_id=self.oauth_client_id,
|
||||
cookie_options=self.cookie_options,
|
||||
cwd=self.cwd,
|
||||
hub=self.hub,
|
||||
user=_MockUser(
|
||||
|
@@ -6,6 +6,7 @@ Contains base Spawner class & default implementation
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import errno
|
||||
import json
|
||||
import os
|
||||
import pipes
|
||||
import shutil
|
||||
@@ -99,11 +100,12 @@ class Spawner(LoggingConfigurable):
|
||||
"""
|
||||
return bool(self.pending or self.ready)
|
||||
|
||||
|
||||
# options passed by constructor
|
||||
authenticator = Any()
|
||||
hub = Any()
|
||||
orm_spawner = Any()
|
||||
db = Any()
|
||||
cookie_options = Dict()
|
||||
|
||||
@observe('orm_spawner')
|
||||
def _orm_spawner_changed(self, change):
|
||||
@@ -587,6 +589,8 @@ class Spawner(LoggingConfigurable):
|
||||
env['JUPYTERHUB_ADMIN_ACCESS'] = '1'
|
||||
# OAuth settings
|
||||
env['JUPYTERHUB_CLIENT_ID'] = self.oauth_client_id
|
||||
if self.cookie_options:
|
||||
env['JUPYTERHUB_COOKIE_OPTIONS'] = json.dumps(self.cookie_options)
|
||||
env['JUPYTERHUB_HOST'] = self.hub.public_host
|
||||
env['JUPYTERHUB_OAUTH_CALLBACK_URL'] = \
|
||||
url_path_join(self.user.url, self.name, 'oauth_callback')
|
||||
|
@@ -215,6 +215,7 @@ class User:
|
||||
proxy_spec=url_path_join(self.proxy_spec, name, '/'),
|
||||
db=self.db,
|
||||
oauth_client_id=client_id,
|
||||
cookie_options = self.settings.get('cookie_options', {}),
|
||||
)
|
||||
# update with kwargs. Mainly for testing.
|
||||
spawn_kwargs.update(kwargs)
|
||||
|
Reference in New Issue
Block a user