Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: enable websocket cors for production #1425

Merged
merged 3 commits into from
Mar 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading