Skip to content

Commit

Permalink
fix: enable websocket cors for production (#1425)
Browse files Browse the repository at this point in the history
* fix: enable websocket cors for production

* fix linter

* add breaking change
  • Loading branch information
jczhong84 authored Mar 13, 2024
1 parent 1e664d3 commit 3e992ee
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 27 deletions.
4 changes: 4 additions & 0 deletions docs_website/docs/changelog/breaking_change.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ slug: /changelog

Here are the list of breaking changes that you should be aware of when updating Querybook:

## v3.32.0

Added config `WS_CORS_ALLOWED_ORIGINS` to configure allowed CORS origins for WebSocket connection. This is required for Prod environment.

## v3.31.0

Upgraded langchain to [0.1.6](https://blog.langchain.dev/langchain-v0-1-0/).
Expand Down
58 changes: 33 additions & 25 deletions docs_website/docs/configurations/infra_config.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Otherwise you can also pass the environment variable directly when launching the

`FLASK_CACHE_CONFIG` (optional): This can be used to provide caching for API endpoints and internal logic. Follow https://pythonhosted.org/Flask-Cache/ for more details. You should provide a serialized JSON dictionary to be passed into the config.

### WebSocket

`WS_CORS_ALLOWED_ORIGINS`: (**required for production**): This is the allowed list of origins for CORS. For dev environment, all origins will be allowed.

### Database

`DATABASE_CONN` (**required**): A sqlalchemy connection string to the database. Please check here https://docs.sqlalchemy.org/en/13/core/engines.html for formatting.
Expand Down Expand Up @@ -100,6 +104,7 @@ You can also add addtional loggers in the event logger plugin. See [Add Event Lo
- console: This will print the stats logs to the console. Could be used for debugging purpose.

You need to add your own stats logger plugin to use it. See [Add Stats Logger guide](../integrations/add_stats_logger.mdx) for more details.

## Authentication

`AUTH_BACKEND` (optional, defaults to **app.auth.password_auth**): Python path to the authentication file. By default Querybook provides:
Expand All @@ -119,31 +124,34 @@ the next few configurations are only relevant if you are using OAuth based authe

for LDAP authentication:

- `LDAP_CONN`(**required**)
- `LDAP_USE_TLS` (optional, defaults to `False`)
- `LDAP_USE_BIND_USER` (optional, defaults to `False`)
- If `False`: Direct LDAP login
- Additional configuration:
- `LDAP_USER_DN` (**required**) DN with {} for username/etc (ex. `uid={},dc=example,dc=com`)
- Login flow:
- Direct login using formatted `LDAP_USER_DN` + password
- If `True`: Advanced LDAP login using _bind user_
- Additional configuration:
- `LDAP_BIND_USER` (**required**) Name of a _bind user_
- `LDAP_BIND_PASSWORD` (**required**) Password of a _bind user_
- `LDAP_SEARCH` (**required**) LDAP search base (ex. `ou=people,dc=example,dc=com`)
- `LDAP_FILTER` (optional) LDAP filter condition (ex. `(departmentNumber=01000)`)
- `LDAP_UID_FIELD` (optional) Field that matches the username when searching for the account to bind to (defaults to `uid`)
- `LDAP_EMAIL_FIELD`: (optional) Field that matches the user email (default to `mail`)
- `LDAP_LASTNAME_FIELD`: (optional) Field that matches the user surname (default to `sn`)
- `LDAP_FIRSTNAME_FIELD`: (optional) Field that matches the user given name (default to `givenName`)
- `LDAP_FULLNAME_FIELD`: (optional) Field that matches the user full/common name (default to `cn`)

- Login flow:
1) Initialized connection for the _bind user_.
2) Searching the _login user_ using the _bind user_ in LDAP dictionary based on `LDAP_SEARCH` and `LDAP_FILTER`.
3) The _login user_ credentials are tested in direct login.
4) If the previous steps were OK, the user is passed on.
- `LDAP_CONN`(**required**)
- `LDAP_USE_TLS` (optional, defaults to `False`)
- `LDAP_USE_BIND_USER` (optional, defaults to `False`)

- If `False`: Direct LDAP login
- Additional configuration:
- `LDAP_USER_DN` (**required**) DN with {} for username/etc (ex. `uid={},dc=example,dc=com`)
- Login flow:
- Direct login using formatted `LDAP_USER_DN` + password
- If `True`: Advanced LDAP login using _bind user_

- Additional configuration:

- `LDAP_BIND_USER` (**required**) Name of a _bind user_
- `LDAP_BIND_PASSWORD` (**required**) Password of a _bind user_
- `LDAP_SEARCH` (**required**) LDAP search base (ex. `ou=people,dc=example,dc=com`)
- `LDAP_FILTER` (optional) LDAP filter condition (ex. `(departmentNumber=01000)`)
- `LDAP_UID_FIELD` (optional) Field that matches the username when searching for the account to bind to (defaults to `uid`)
- `LDAP_EMAIL_FIELD`: (optional) Field that matches the user email (default to `mail`)
- `LDAP_LASTNAME_FIELD`: (optional) Field that matches the user surname (default to `sn`)
- `LDAP_FIRSTNAME_FIELD`: (optional) Field that matches the user given name (default to `givenName`)
- `LDAP_FULLNAME_FIELD`: (optional) Field that matches the user full/common name (default to `cn`)

- Login flow:
1. Initialized connection for the _bind user_.
2. Searching the _login user_ using the _bind user_ in LDAP dictionary based on `LDAP_SEARCH` and `LDAP_FILTER`.
3. The _login user_ credentials are tested in direct login.
4. If the previous steps were OK, the user is passed on.

If you want to force the user to login again after a certain time, you can the following variable:

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "querybook",
"version": "3.31.2",
"version": "3.32.0",
"description": "A Big Data Webapp",
"private": true,
"scripts": {
Expand Down
4 changes: 4 additions & 0 deletions querybook/config/querybook_default_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ LDAP_LASTNAME_FIELD: sn
LDAP_FIRSTNAME_FIELD: givenName
LDAP_FULLNAME_FIELD: cn

# Websocket CORS allowed origins
WS_CORS_ALLOWED_ORIGINS:
- http://localhost:10001

# --------------- Result Store ---------------
RESULT_STORE_TYPE: db

Expand Down
6 changes: 5 additions & 1 deletion querybook/server/app/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ def make_socketio(app):
path="-/socket.io",
message_queue=QuerybookSettings.REDIS_URL,
json=flask_json,
cors_allowed_origins="*",
cors_allowed_origins=(
QuerybookSettings.WS_CORS_ALLOWED_ORIGINS
if QuerybookSettings.PRODUCTION
else "*"
),
)
return socketio

Expand Down
1 change: 1 addition & 0 deletions querybook/server/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class QuerybookSettings(object):
PUBLIC_URL = get_env_config("PUBLIC_URL")
FLASK_SECRET_KEY = get_env_config("FLASK_SECRET_KEY", optional=False)
FLASK_CACHE_CONFIG = get_env_config("FLASK_CACHE_CONFIG")
WS_CORS_ALLOWED_ORIGINS = get_env_config("WS_CORS_ALLOWED_ORIGINS", optional=False)

# Celery
REDIS_URL = get_env_config("REDIS_URL", optional=False)
Expand Down

0 comments on commit 3e992ee

Please sign in to comment.