Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #3
0
 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
async def test__exclude_cookies(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, exclude_cookies=['custom']) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server), headers={'Cookie': 'custom = test ; custom2 = test2'})
        html = response.body
        token = extract_token_from_json(html)
        payload = get_token_payload(token)
        assert 'cookies' in payload
        assert payload['cookies'] == {'custom2': 'test2'}
async def test__exclude_headers(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, exclude_headers=['Connection', 'Host']) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server))
        html = response.body
        token = extract_token_from_json(html)
        payload = get_token_payload(token)
        assert 'headers' in payload
        assert payload["headers"].get("Accept-Encoding") == "gzip"
async def test__include_headers(ManagedServerLoop) -> None:
    application = Application()
    with ManagedServerLoop(application, include_headers=['Custom']) as server:
        sessions = server.get_sessions('/')
        assert 0 == len(sessions)

        response = await http_get(server.io_loop, url(server), headers={'Custom': 'Test'})
        html = response.body
        token = extract_token_from_json(html)
        payload = get_token_payload(token)
        assert 'headers' in payload
        assert payload['headers'] == {'Custom': 'Test'}
Beispiel #7
0
 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
Beispiel #8
0
    async def connect(self):
        log.info('WebSocket connection opened')

        subprotocols = self.scope["subprotocols"]
        if len(subprotocols) != 2 or subprotocols[0] != 'bokeh':
            self.close()
            raise RuntimeError("Subprotocol header is not 'bokeh'")

        token = subprotocols[1]
        if token is None:
            self.close()
            raise RuntimeError("No token received in subprotocol header")

        now = calendar.timegm(dt.datetime.now().utctimetuple())
        payload = get_token_payload(token)
        if 'session_expiry' not in payload:
            self.close()
            raise RuntimeError("Session expiry has not been provided")
        elif now >= payload['session_expiry']:
            self.close()
            raise RuntimeError("Token is expired.")
        elif not check_token_signature(token,
                                       signed=False,
                                       secret_key=None):
            session_id = get_session_id(token)
            log.error("Token for session %r had invalid signature", session_id)
            raise RuntimeError("Invalid token signature")

        def on_fully_opened(future):
            e = future.exception()
            if e is not None:
                # this isn't really an error (unless we have a
                # bug), it just means a client disconnected
                # immediately, most likely.
                log.debug("Failed to fully open connlocksection %r", e)

        future = self._async_open(token)

        # rewrite above line using asyncio
        # this task is scheduled to run soon once context is back to event loop
        task = asyncio.ensure_future(future)
        task.add_done_callback(on_fully_opened)
        await self.accept("bokeh")
Beispiel #9
0
    def open(self):
        ''' Initialize a connection to a client.

        Returns:
            None

        '''
        log.info('WebSocket connection opened')
        token = self._token

        if self.selected_subprotocol != 'bokeh':
            self.close()
            raise ProtocolError("Subprotocol header is not 'bokeh'")
        elif token is None:
            self.close()
            raise ProtocolError("No token received in subprotocol header")

        now = calendar.timegm(dt.datetime.utcnow().utctimetuple())
        payload = get_token_payload(token)
        if 'session_expiry' not in payload:
            self.close()
            raise ProtocolError("Session expiry has not been provided")
        elif now >= payload['session_expiry']:
            self.close()
            raise ProtocolError("Token is expired.")
        elif not check_token_signature(token,
                                       signed=self.application.sign_sessions,
                                       secret_key=self.application.secret_key):
            session_id = get_session_id(token)
            log.error("Token for session %r had invalid signature", session_id)
            raise ProtocolError("Invalid token signature")

        try:
            self.application.io_loop.spawn_callback(self._async_open,
                                                    self._token)
        except Exception as e:
            # this isn't really an error (unless we have a
            # bug), it just means a client disconnected
            # immediately, most likely.
            log.debug("Failed to fully open connection %r", e)