def test_generate_unsigned(self) -> None: token = generate_jwt_token(generate_session_id(), signed=False) assert '.' not in token assert 123 == len(token) assert "session_id" in json.loads(_base64_decode(token, encoding='utf-8')) another_token = generate_jwt_token(generate_session_id(), signed=False) assert '.' not in another_token assert 123 == len(another_token) assert "session_id" in json.loads(_base64_decode(another_token, encoding='utf-8')) assert token != another_token
def test_generate_unsigned(self) -> None: token = generate_jwt_token(generate_session_id(), signed=False) assert '.' not in token assert 123 == len(token) assert "session_id" in json.loads(_b64_to_utf8(token)) another_token = generate_jwt_token(generate_session_id(), signed=False) assert '.' not in another_token assert 123 == len(another_token) assert "session_id" in json.loads(_b64_to_utf8(another_token)) assert token != another_token
def test_payload_unsigned(self): token = generate_jwt_token(generate_session_id(), signed=False, extra_payload=dict(foo=10)) assert '.' not in token payload = json.loads(_base64_decode(token, encoding='utf-8')) assert payload['foo'] == 10
async def check_connect_session_fails(self, server, origin): with pytest.raises(HTTPError): subprotocols = ["bokeh", generate_jwt_token("foo")] await websocket_open(server.io_loop, ws_url(server), origin=origin, subprotocols=subprotocols)
async def get_session(self): token = self.get_argument("bokeh-token", default=None) session_id = self.get_argument("bokeh-session-id", default=None) if 'Bokeh-Session-Id' in self.request.headers: if session_id is not None: log.debug("Server received session ID in request argument and header, expected only one") raise HTTPError(status_code=403, reason="session ID was provided as an argument and header") session_id = self.request.headers.get('Bokeh-Session-Id') if token is not None: if session_id is not None: log.debug("Server received both token and session ID, expected only one") raise HTTPError(status_code=403, reason="Both token and session ID were provided") session_id = get_session_id(token) elif session_id is None: if self.application.generate_session_ids: session_id = generate_session_id(secret_key=self.application.secret_key, signed=self.application.sign_sessions) else: log.debug("Server configured not to generate session IDs and none was provided") raise HTTPError(status_code=403, reason="No bokeh-session-id provided") if token is None: if self.application.include_headers is None: excluded_headers = (self.application.exclude_headers or []) allowed_headers = [header for header in self.request.headers if header not in excluded_headers] else: allowed_headers = self.application.include_headers headers = {k: v for k, v in self.request.headers.items() if k in allowed_headers} if self.application.include_cookies is None: excluded_cookies = (self.application.exclude_cookies or []) allowed_cookies = [cookie for cookie in self.request.cookies if cookie not in excluded_cookies] else: allowed_cookies = self.application.include_cookies cookies = {k: v.value for k, v in self.request.cookies.items() if k in allowed_cookies} payload = {'headers': headers, 'cookies': cookies} payload.update(self.application_context.application.process_request(self.request)) token = generate_jwt_token(session_id, secret_key=self.application.secret_key, signed=self.application.sign_sessions, expiration=self.application.session_token_expiration, extra_payload=payload) if not check_token_signature(token, secret_key=self.application.secret_key, signed=self.application.sign_sessions): log.error("Session id had invalid signature: %r", session_id) raise HTTPError(status_code=403, reason="Invalid token or session ID") session = await self.application_context.create_session_if_needed(session_id, self.request, token) return session
def test_generate_signed(self) -> None: session_id = generate_session_id(signed=True, secret_key="abc") token = generate_jwt_token(session_id, signed=True, secret_key="abc") assert '.' in token decoded = json.loads(_base64_decode(token.split('.')[0], encoding='utf-8')) assert "session_id" in decoded assert decoded['session_id'] == session_id assert check_token_signature(token, secret_key="abc", signed=True) assert not check_token_signature(token, secret_key="qrs", signed=True)
def test_payload_with_zlib_key(self): token = generate_jwt_token(generate_session_id(), signed=False, extra_payload=dict([(_TOKEN_ZLIB_KEY, 10)])) assert '.' not in token assert _TOKEN_ZLIB_KEY in json.loads(_b64_to_utf8(token)) payload = get_token_payload(token) assert _TOKEN_ZLIB_KEY in payload assert payload[_TOKEN_ZLIB_KEY] == 10
def test_payload_unsigned(self): token = generate_jwt_token(generate_session_id(), signed=False, extra_payload=dict(foo=10)) assert '.' not in token assert _TOKEN_ZLIB_KEY in json.loads(_b64_to_utf8(token)) payload = get_token_payload(token) assert _TOKEN_ZLIB_KEY not in payload assert payload['foo'] == 10
def test_jwt_token_uses_utc_time(self) -> None: # django server generates token using UTC timezone token = generate_jwt_token("foo", expiration=0) with patch.object(dt, "datetime", Mock(wraps=dt.datetime)) as patched_dt: # mock bokeh server localtime to be UTC + 10 patched_dt.now.return_value = dt.datetime.utcnow() + dt.timedelta(hours=10) payload = get_token_payload(token) utcnow = calendar.timegm(dt.datetime.utcnow().utctimetuple()) assert utcnow -1 <= payload['session_expiry'] <= utcnow + 1
def test_payload_signed(self): session_id = generate_session_id(signed=True, secret_key="abc") token = generate_jwt_token(session_id, signed=True, secret_key="abc", extra_payload=dict(foo=10)) assert '.' in token decoded = json.loads(_base64_decode(token.split('.')[0], encoding='utf-8')) assert 'session_id' in decoded session_id = get_session_id(token) assert check_token_signature(token, secret_key="abc", signed=True) assert not check_token_signature(token, secret_key="qrs", signed=True) assert decoded['foo'] == 10
async def test__no_autocreate_session_websocket(ManagedServerLoop) -> None: application = Application() with ManagedServerLoop(application) as server: sessions = server.get_sessions('/') assert 0 == len(sessions) token = generate_jwt_token("") await websocket_open(server.io_loop, ws_url(server), subprotocols=["bokeh", token]) sessions = server.get_sessions('/') assert 0 == len(sessions)
async def test__reject_unsigned_session_websocket(ManagedServerLoop) -> None: application = Application() with ManagedServerLoop(application, sign_sessions=True, secret_key='bar') as server: sessions = server.get_sessions('/') assert 0 == len(sessions) expected = 'foo' token = generate_jwt_token(expected) await websocket_open(server.io_loop, ws_url(server), subprotocols=["bokeh", token]) sessions = server.get_sessions('/') assert 0 == len(sessions)
async def _get_session(self) -> ServerSession: session_id = self.arguments.get('bokeh-session-id', generate_session_id(secret_key=None, signed=False)) payload = {'headers': {k.decode('utf-8'): v.decode('utf-8') for k, v in self.request.headers}, 'cookies': dict(self.request.cookies)} token = generate_jwt_token(session_id, secret_key=None, signed=False, expiration=300, extra_payload=payload) session = await self.application_context.create_session_if_needed(session_id, self.request, token) return session
async def test__use_provided_session_websocket(ManagedServerLoop) -> None: application = Application() with ManagedServerLoop(application) as server: sessions = server.get_sessions('/') assert 0 == len(sessions) expected = 'foo' token = generate_jwt_token(expected) await websocket_open(server.io_loop, ws_url(server), subprotocols=["bokeh", token]) sessions = server.get_sessions('/') assert 1 == len(sessions) assert expected == sessions[0].id
async def test__reject_unsigned_token_autoload(ManagedServerLoop) -> None: application = Application() with ManagedServerLoop(application, sign_sessions=True, secret_key='bar') as server: sessions = server.get_sessions('/') assert 0 == len(sessions) expected = 'foo' token = generate_jwt_token(expected) with (pytest.raises(HTTPError)) as info: await http_get(server.io_loop, autoload_url(server) + "&bokeh-token=" + token) assert 'Invalid token or session ID' in repr(info.value) sessions = server.get_sessions('/') assert 0 == len(sessions)
def test_payload_signed(self): session_id = generate_session_id(signed=True, secret_key="abc") token = generate_jwt_token(session_id, signed=True, secret_key="abc", extra_payload=dict(foo=10)) assert '.' in token decoded = json.loads(_b64_to_utf8(token.split('.')[0])) assert _TOKEN_ZLIB_KEY in decoded assert 'session_id' in decoded session_id = get_session_id(token) assert check_token_signature(token, secret_key="abc", signed=True) assert not check_token_signature(token, secret_key="qrs", signed=True) payload = get_token_payload(token) assert _TOKEN_ZLIB_KEY not in payload assert payload['foo'] == 10
async def test__use_provided_session_autoload_token(ManagedServerLoop) -> None: application = Application() with ManagedServerLoop(application) as server: sessions = server.get_sessions('/') assert 0 == len(sessions) expected = 'foo' expected_token = generate_jwt_token(expected) response = await http_get(server.io_loop, autoload_url(server) + "&bokeh-token=" + expected_token) js = response.body token = extract_token_from_json(js) assert expected_token == token sessionid = get_session_id(token) assert expected == sessionid sessions = server.get_sessions('/') assert 1 == len(sessions) assert expected == sessions[0].id
async def get_plots(request): loaded_request = PlotsRequestSchema().load(request.query) offset = loaded_request['offset'] limit = loaded_request['limit'] total_length = len(request.app['keys_df'].index) selected_keys = request.app['keys_df'].sort_values( loaded_request['sort'], ascending=loaded_request['ascending']).iloc[offset:limit + offset] record_dicts_list = selected_keys.to_dict(orient='records') for i, record in enumerate(record_dicts_list): localhost_url = 'http://' + os.environ[ 'SERVER_HOST_NAME'] + ':5006/image' arguments = { 'key': record['Key'], 'bucket': request.app['bucket'], 'width': loaded_request['width'], 'height': loaded_request['height'] } resources = 'default' if i == 0 else None record['bokeh_tag'] = server_document(localhost_url, arguments=arguments) record['script_src'] = re.search(', "(.*)", true', record['bokeh_tag']).group(1) record['script_id'] = re.search('id="(.*)"', record['bokeh_tag']).group(1) record['session_id'] = generate_session_id() # session.id record['token'] = generate_jwt_token(record['session_id']) response_data = S3ObjectBokehPlotsGetResponseSchema().dump({ 'plots': record_dicts_list, 'length': total_length }) return web.json_response(response_data)
def test_payload_error(self): session_id = generate_session_id() with pytest.raises(RuntimeError): generate_jwt_token(session_id, extra_payload=dict(session_id=10))
def test_string_encoding_does_not_affect_session_id_check(self) -> None: # originates from #6653 session_id = generate_session_id(signed=True, secret_key="abc") token = generate_jwt_token(session_id, signed=True, secret_key="abc") assert check_token_signature(token, secret_key="abc", signed=True)
def test_check_signature_of_unsigned(self) -> None: # secret shouldn't be used token = generate_jwt_token(generate_session_id(), signed=False, secret_key="abc") assert not check_token_signature(token, secret_key="abc", signed=True)
async def check_connect_session(self, server, origin): subprotocols = ["bokeh", generate_jwt_token("foo")] await websocket_open(server.io_loop, ws_url(server), origin=origin, subprotocols=subprotocols)