mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-03-16 05:23:33 +00:00
Resolve "Remove the _DOMAIN variables"
This commit is contained in:
parent
9a066f674c
commit
6160eaa926
15 changed files with 57 additions and 94 deletions
backend
src/baserow
api/user
config/settings
core
tests/baserow
docs
getting-started
guides/installation
plugin-boilerplate/{{ cookiecutter.project_slug }}
|
@ -4,8 +4,8 @@ from rest_framework.status import HTTP_400_BAD_REQUEST
|
|||
ERROR_ALREADY_EXISTS = 'ERROR_EMAIL_ALREADY_EXISTS'
|
||||
ERROR_USER_NOT_FOUND = 'ERROR_USER_NOT_FOUND'
|
||||
ERROR_INVALID_OLD_PASSWORD = 'ERROR_INVALID_OLD_PASSWORD'
|
||||
ERROR_DOMAIN_URL_IS_NOT_ALLOWED = (
|
||||
'ERROR_DOMAIN_URL_IS_NOT_ALLOWED',
|
||||
ERROR_HOSTNAME_IS_NOT_ALLOWED = (
|
||||
'ERROR_HOSTNAME_IS_NOT_ALLOWED',
|
||||
HTTP_400_BAD_REQUEST,
|
||||
'Only the domain of the web frontend is allowed.'
|
||||
'Only the hostname of the web frontend is allowed.'
|
||||
)
|
||||
|
|
|
@ -20,7 +20,7 @@ from baserow.api.errors import BAD_TOKEN_SIGNATURE, EXPIRED_TOKEN_SIGNATURE
|
|||
from baserow.api.schemas import get_error_schema
|
||||
from baserow.core.user.handler import UserHandler
|
||||
from baserow.core.user.exceptions import (
|
||||
UserAlreadyExist, UserNotFound, InvalidPassword, BaseURLDomainNotAllowed
|
||||
UserAlreadyExist, UserNotFound, InvalidPassword, BaseURLHostnameNotAllowed
|
||||
)
|
||||
|
||||
from .serializers import (
|
||||
|
@ -30,7 +30,7 @@ from .serializers import (
|
|||
)
|
||||
from .errors import (
|
||||
ERROR_ALREADY_EXISTS, ERROR_USER_NOT_FOUND, ERROR_INVALID_OLD_PASSWORD,
|
||||
ERROR_DOMAIN_URL_IS_NOT_ALLOWED
|
||||
ERROR_HOSTNAME_IS_NOT_ALLOWED
|
||||
)
|
||||
from .schemas import create_user_response_schema, authenticate_user_schema
|
||||
|
||||
|
@ -171,7 +171,7 @@ class SendResetPasswordEmailView(APIView):
|
|||
204: None,
|
||||
400: get_error_schema([
|
||||
'ERROR_REQUEST_BODY_VALIDATION',
|
||||
'ERROR_DOMAIN_URL_IS_NOT_ALLOWED'
|
||||
'ERROR_HOSTNAME_IS_NOT_ALLOWED'
|
||||
])
|
||||
},
|
||||
auth=[None],
|
||||
|
@ -179,7 +179,7 @@ class SendResetPasswordEmailView(APIView):
|
|||
@transaction.atomic
|
||||
@validate_body(SendResetPasswordEmailBodyValidationSerializer)
|
||||
@map_exceptions({
|
||||
BaseURLDomainNotAllowed: ERROR_DOMAIN_URL_IS_NOT_ALLOWED
|
||||
BaseURLHostnameNotAllowed: ERROR_HOSTNAME_IS_NOT_ALLOWED
|
||||
})
|
||||
def post(self, request, data):
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import os
|
||||
import datetime
|
||||
from urllib.parse import urlparse
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
@ -10,7 +11,7 @@ SECRET_KEY = os.getenv('SECRET_KEY', 'CHANGE_THIS_TO_SOMETHING_SECRET_IN_PRODUCT
|
|||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = ['localhost', 'backend', 'sandbox']
|
||||
ALLOWED_HOSTS = ['localhost']
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.auth',
|
||||
|
@ -176,13 +177,18 @@ MJML_TCPSERVERS = [
|
|||
(os.getenv('MJML_SERVER_HOST', 'mjml'), int(os.getenv('MJML_SERVER_PORT', 28101))),
|
||||
]
|
||||
|
||||
PUBLIC_BACKEND_DOMAIN = os.getenv('PUBLIC_BACKEND_DOMAIN', 'localhost:8000')
|
||||
PUBLIC_BACKEND_URL = os.getenv('PUBLIC_BACKEND_URL', 'http://localhost:8000')
|
||||
PUBLIC_WEB_FRONTEND_DOMAIN = os.getenv('PUBLIC_WEB_FRONTEND_DOMAIN', 'localhost:3000')
|
||||
PUBLIC_WEB_FRONTEND_URL = os.getenv('PUBLIC_WEB_FRONTEND_URL', 'http://localhost:3000')
|
||||
PRIVATE_BACKEND_URL = os.getenv('PRIVATE_BACKEND_URL', 'http://backend:8000')
|
||||
PUBLIC_BACKEND_HOSTNAME = urlparse(PUBLIC_BACKEND_URL).hostname
|
||||
PUBLIC_WEB_FRONTEND_HOSTNAME = urlparse(PUBLIC_WEB_FRONTEND_URL).hostname
|
||||
PRIVATE_BACKEND_HOSTNAME = urlparse(PRIVATE_BACKEND_URL).hostname
|
||||
|
||||
if PUBLIC_BACKEND_DOMAIN:
|
||||
ALLOWED_HOSTS.append(PUBLIC_BACKEND_DOMAIN)
|
||||
if PUBLIC_BACKEND_HOSTNAME:
|
||||
ALLOWED_HOSTS.append(PUBLIC_BACKEND_HOSTNAME)
|
||||
|
||||
if PRIVATE_BACKEND_HOSTNAME:
|
||||
ALLOWED_HOSTS.append(PRIVATE_BACKEND_HOSTNAME)
|
||||
|
||||
FROM_EMAIL = os.getenv('FROM_EMAIL', 'no-reply@localhost')
|
||||
RESET_PASSWORD_TOKEN_MAX_AGE = 60 * 60 * 48 # 48 hours
|
||||
|
|
|
@ -52,9 +52,9 @@ class BaseEmailMessage(EmailMultiAlternatives):
|
|||
|
||||
def get_context(self):
|
||||
return {
|
||||
'public_backend_domain': settings.PUBLIC_BACKEND_DOMAIN,
|
||||
'public_backend_hostname': settings.PUBLIC_BACKEND_HOSTNAME,
|
||||
'public_backend_url': settings.PUBLIC_BACKEND_URL,
|
||||
'public_web_frontend_domain': settings.PUBLIC_WEB_FRONTEND_DOMAIN,
|
||||
'public_web_frontend_hostname': settings.PUBLIC_WEB_FRONTEND_HOSTNAME,
|
||||
'public_web_frontend_url': settings.PUBLIC_WEB_FRONTEND_URL
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<mj-text mj-class="title">Reset password</mj-text>
|
||||
<mj-text mj-class="text">
|
||||
A password reset was requested for your account ({{ user.username }}) on
|
||||
Baserow ({{ public_web_frontend_domain }}). If you did not authorize this, you
|
||||
Baserow ({{ public_web_frontend_hostname }}). If you did not authorize this, you
|
||||
may simply ignore this email.
|
||||
</mj-text>
|
||||
<mj-text mj-class="text" padding-bottom="20px">
|
||||
|
|
|
@ -10,7 +10,7 @@ class InvalidPassword(Exception):
|
|||
"""Raised when the provided password is incorrect."""
|
||||
|
||||
|
||||
class BaseURLDomainNotAllowed(Exception):
|
||||
class BaseURLHostnameNotAllowed(Exception):
|
||||
"""
|
||||
Raised when the provided base url is not allowed when requesting a password
|
||||
reset email.
|
||||
|
|
|
@ -9,7 +9,7 @@ from baserow.core.handler import CoreHandler
|
|||
from baserow.core.registries import plugin_registry
|
||||
|
||||
from .exceptions import (
|
||||
UserAlreadyExist, UserNotFound, InvalidPassword, BaseURLDomainNotAllowed
|
||||
UserAlreadyExist, UserNotFound, InvalidPassword, BaseURLHostnameNotAllowed
|
||||
)
|
||||
from .emails import ResetPasswordEmail
|
||||
from .utils import normalize_email_address
|
||||
|
@ -101,14 +101,15 @@ class UserHandler:
|
|||
:type user: User
|
||||
:param base_url: The base url of the frontend, where the user can reset his
|
||||
password. The reset token is appended to the URL (base_url + '/TOKEN').
|
||||
Only the PUBLIC_WEB_FRONTEND_DOMAIN is allowed as domain name.
|
||||
Only the PUBLIC_WEB_FRONTEND_HOSTNAME is allowed as domain name.
|
||||
:type base_url: str
|
||||
"""
|
||||
|
||||
parsed_base_url = urlparse(base_url)
|
||||
if parsed_base_url.netloc != settings.PUBLIC_WEB_FRONTEND_DOMAIN:
|
||||
raise BaseURLDomainNotAllowed(f'The domain {parsed_base_url.netloc} is '
|
||||
f'not allowed.')
|
||||
if parsed_base_url.hostname != settings.PUBLIC_WEB_FRONTEND_HOSTNAME:
|
||||
raise BaseURLHostnameNotAllowed(
|
||||
f'The hostname {parsed_base_url.netloc} is not allowed.'
|
||||
)
|
||||
|
||||
signer = self.get_reset_password_signer()
|
||||
signed_user_id = signer.dumps(user.id)
|
||||
|
|
|
@ -106,7 +106,7 @@ def test_send_reset_password_email(data_fixture, client, mailoutbox):
|
|||
)
|
||||
response_json = response.json()
|
||||
assert response.status_code == HTTP_400_BAD_REQUEST
|
||||
assert response_json['error'] == 'ERROR_DOMAIN_URL_IS_NOT_ALLOWED'
|
||||
assert response_json['error'] == 'ERROR_HOSTNAME_IS_NOT_ALLOWED'
|
||||
assert len(mailoutbox) == 0
|
||||
|
||||
response = client.post(
|
||||
|
|
|
@ -35,9 +35,9 @@ def test_base_email_message():
|
|||
|
||||
email = SimpleResetPasswordEmail(['test@baserow.io'])
|
||||
context = email.get_context()
|
||||
assert 'public_backend_domain' in context
|
||||
assert 'public_backend_url' in context
|
||||
assert 'public_web_frontend_domain' in context
|
||||
assert 'public_backend_hostname' in context
|
||||
assert 'public_web_frontend_url' in context
|
||||
assert 'public_web_frontend_hostname' in context
|
||||
assert email.get_from_email() == 'no-reply@localhost'
|
||||
assert email.get_subject() == 'Reset password'
|
||||
|
|
|
@ -11,7 +11,7 @@ from baserow.contrib.database.models import (
|
|||
)
|
||||
from baserow.contrib.database.views.models import GridViewFieldOptions
|
||||
from baserow.core.user.exceptions import (
|
||||
UserAlreadyExist, UserNotFound, InvalidPassword, BaseURLDomainNotAllowed
|
||||
UserAlreadyExist, UserNotFound, InvalidPassword, BaseURLHostnameNotAllowed
|
||||
)
|
||||
from baserow.core.user.handler import UserHandler
|
||||
|
||||
|
@ -81,7 +81,7 @@ def test_send_reset_password_email(data_fixture, mailoutbox):
|
|||
user = data_fixture.create_user(email='test@localhost')
|
||||
handler = UserHandler()
|
||||
|
||||
with pytest.raises(BaseURLDomainNotAllowed):
|
||||
with pytest.raises(BaseURLHostnameNotAllowed):
|
||||
handler.send_reset_password_email(user, 'http://test.nl/reset-password')
|
||||
|
||||
signer = handler.get_reset_password_signer()
|
||||
|
|
|
@ -93,9 +93,6 @@ are accepted.
|
|||
* `MJML_SERVER_HOST` (default `mjml`): The hostname of the MJML TCP server. In the
|
||||
development environment we use the `liminspace/mjml-tcpserver:latest` image.
|
||||
* `MJML_SERVER_PORT` (default `28101`): The port of the MJML TCP server.
|
||||
* `PUBLIC_BACKEND_DOMAIN` (default `localhost:8000`): The publicly accessible domain
|
||||
name of the backend. For the development environment this is localhost:8000, but if
|
||||
you change the port to 9000, for example, it will be `localhost:9000`.
|
||||
* `PUBLIC_BACKEND_URL` (default `http://localhost:8000`): The publicly accessible URL
|
||||
of the backend. For the development environment this is `http://localhost:8000`, but
|
||||
if you change the port to 9000 it will be `http://localhost:9000`.
|
||||
|
@ -107,9 +104,6 @@ are accepted.
|
|||
development environment the backend container be accessed via the `backend` hostname
|
||||
and because the server is also running on port 8000 inside the container, the private
|
||||
backend URL should be `http://backend:8000`.
|
||||
* `PUBLIC_WEB_FRONTEND_DOMAIN` (default `localhost:3000`): The publicly accessible
|
||||
domain name of the web-frontend. For the development environment this is
|
||||
localhost:3000, but if you change the port to 4000 it would be `localhost:4000`.
|
||||
* `PUBLIC_WEB_FRONTEND_URL` (default `http://localhost:3000`): The publicly accessible
|
||||
URL of the web-frontend. For the development environment this is
|
||||
`http://localhost:3000`, but again you can change the port to whatever you wish. This
|
||||
|
|
|
@ -2,7 +2,14 @@
|
|||
nodaemon = true
|
||||
|
||||
[program:gunicorn]
|
||||
environment = DJANGO_SETTINGS_MODULE="baserow.config.settings.base",DATABASE_PASSWORD="yourpassword",DATABASE_HOST="localhost",SECRET_KEY="SOMETHING_SECRET"
|
||||
environment =
|
||||
DJANGO_SETTINGS_MODULE="baserow.config.settings.base",
|
||||
DATABASE_HOST="localhost",
|
||||
DATABASE_PASSWORD="yourpassword",
|
||||
SECRET_KEY="SOMETHING_SECRET",
|
||||
PRIVATE_BACKEND_URL='http://localhost:8000',
|
||||
PUBLIC_WEB_FRONTEND_URL='https://FRONTEND_DOMAIN',
|
||||
PUBLIC_BACKEND_URL='https://BACKEND_DOMAIN'
|
||||
command = /baserow/backend/env/bin/gunicorn -w 5 -b 127.0.0.1:8000 baserow.config.wsgi:application --log-level=debug --chdir=/baserow
|
||||
stdout_logfile=/var/log/baserow/backend.log
|
||||
stderr_logfile=/var/log/baserow/backend.error
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
[supervisord]
|
||||
nodaemon = true
|
||||
environment=PRIVATE_BACKEND_URL='http://localhost',PUBLIC_WEB_FRONTEND_URL='https://FRONTEND_DOMAIN',PUBLIC_BACKEND_URL='https://BACKEND_DOMAIN',PUBLIC_WEB_FRONTEND_DOMAIN='FRONTEND_DOMAIN',PUBLIC_BACKEND_DOMAIN='BACKEND_DOMAIN'
|
||||
|
||||
[program:nuxt]
|
||||
environment =
|
||||
PRIVATE_BACKEND_URL='http://localhost:8000',
|
||||
PUBLIC_WEB_FRONTEND_URL='https://FRONTEND_DOMAIN',
|
||||
PUBLIC_BACKEND_URL='https://BACKEND_DOMAIN'
|
||||
directory = /baserow/web-frontend
|
||||
command = sh -c './node_modules/.bin/nuxt start --hostname 127.0.0.1 --config-file ./config/nuxt.config.demo.js'
|
||||
stdout_logfile=/var/log/baserow/frontend.log
|
||||
|
|
|
@ -111,8 +111,8 @@ $ yarn install
|
|||
$ ./node_modules/nuxt/bin/nuxt.js build --config-file config/nuxt.config.demo.js
|
||||
```
|
||||
|
||||
|
||||
## Install NGINX
|
||||
|
||||
Baserow uses NGINX as a reverse proxy for it's frontend and backend. Through that, you
|
||||
can easily add SSL Certificates and add more applications to your server if you want
|
||||
to.
|
||||
|
@ -127,6 +127,7 @@ $ service nginx start
|
|||
```
|
||||
|
||||
## Setup NGINX
|
||||
|
||||
If you're unfamiliar with NGINX: NGINX uses so called "virtualhosts" to direct web
|
||||
traffic from outside of your network to the correct application on your server. These
|
||||
virtual hosts are defined in `.conf` files which are put into the
|
||||
|
@ -152,57 +153,8 @@ $ sed -i 's/\*YOUR_DOMAIN\*/baserow.domain.com/g' /etc/nginx/sites-enabled/baser
|
|||
$ service nginx restart
|
||||
```
|
||||
|
||||
## Baserow Configuration
|
||||
## Import relations into database
|
||||
|
||||
### Configuration
|
||||
|
||||
Baserow needs a few environment variables to be set in order to work properly. Here is
|
||||
a list of the environment variables with explanations for them. This list is solely
|
||||
for reference, there is no need to set these variables because they will be set
|
||||
through `supervisor` later on. This list does not describe all environment variables
|
||||
that can be set. For a better understanding of the available environment variables,
|
||||
take a look at `/baserow/backend/src/config/settings/base.py`.
|
||||
|
||||
We discourage changing the content of the `base.py` file since it might be overridden
|
||||
through a future update with `git pull`. It is only mentioned in this guide so that
|
||||
you're able to modify your Baserow instance as easily as possible with environment
|
||||
variables.
|
||||
|
||||
```
|
||||
# Backend Domain & URL
|
||||
PUBLIC_BACKEND_DOMAIN="api.domain.com"
|
||||
PUBLIC_BACKEND_URL="https://api.domain.com"
|
||||
|
||||
# Frontend Domain & URL
|
||||
PUBLIC_WEB_FRONTEND_DOMAIN="baserow.domain.com"
|
||||
PUBLIC_WEB_FRONTEND_URL="https://baserow.domain.com"
|
||||
|
||||
# Private Backend URL & Database Password & Database Host
|
||||
PRIVATE_BACKEND_URL="http://localhost"
|
||||
DATABASE_PASSWORD="yourpassword"
|
||||
DATABASE_HOST="localhost"
|
||||
|
||||
# Django Settings Module & Python Path
|
||||
DJANGO_SETTINGS_MODULE='baserow.config.settings.base'
|
||||
PYTHONPATH=/baserow:/baserow/plugins/saas/backend/src
|
||||
|
||||
# Secret Key
|
||||
SECRET_KEY="Something_Secret"
|
||||
```
|
||||
|
||||
Baserow uses the secret key to generate a variety of tokens (e.g. password reset
|
||||
token, ...). In order to generate a unique secret key, you can simply run the following
|
||||
command.
|
||||
|
||||
```bash
|
||||
$ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1
|
||||
```
|
||||
|
||||
The output will be a alphanumeric string with 80 characters. You can shorten or
|
||||
lengthen the string by changing the number value in `fold -w 80` to a length you're
|
||||
satisfied with.
|
||||
|
||||
### Import relations into database
|
||||
In the "*Install & Setup PostgreSQL*" Section, we created a database called `baserow`
|
||||
for the application. Since we didn't do anything with that database it is still empty,
|
||||
which will result in a non-working application since Baserow expects certain tables
|
||||
|
@ -223,6 +175,7 @@ $ deactivate
|
|||
```
|
||||
|
||||
## Install & Configure Supervisor
|
||||
|
||||
Supervisor is an application that starts and keeps track of processes and will restart
|
||||
them if the process finishes. For Baserow this is used to reduce downtime and in order
|
||||
to restart the application in the unlikely event of an unforseen termination. You can
|
||||
|
@ -239,23 +192,24 @@ $ mkdir /var/log/baserow/
|
|||
$ cd /baserow
|
||||
$ cp docs/guides/installation/configuration-files/supervisor/* /etc/supervisor/conf.d/
|
||||
```
|
||||
|
||||
You will need to edit the `baserow-frontend.conf` and `baserow-backend.conf` files
|
||||
(located now at `/etc/supervisor/conf.d/`) in order to set the necessary environment
|
||||
variables. You will need to change at least the following variables which can be found
|
||||
in the `environment=` section.
|
||||
in the `environment =` section.
|
||||
|
||||
**Frontend**
|
||||
**Web frontend and backend**
|
||||
- `PUBLIC_WEB_FRONTEND_URL`: The URL under which your frontend can be reached from the
|
||||
internet (HTTP or HTTPS)
|
||||
- `PUBLIC_BACKEND_URL`: The URL under which your backend can be reached from the
|
||||
internet (HTTP or HTTPS)
|
||||
- `PUBLIC_WEB_FRONTEND_DOMAIN`: The domain under which you frontend can be reached from
|
||||
the internet (same as URL but without `https://`)
|
||||
- `PUBLIC_BACKEND_DOMAIN`: The domain under which you backend can be reached from the
|
||||
internet (same as URL but without `https://`)
|
||||
|
||||
**Backend**
|
||||
- `SECRET_KEY`: The secret key that is used to generate tokens and other random strings
|
||||
- `SECRET_KEY`: The secret key that is used to generate tokens and other random
|
||||
strings. You can generate one with the following commands:
|
||||
```bash
|
||||
$ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 80 | head -n 1
|
||||
```
|
||||
- `DATABASE_PASSWORD`: The password of the `baserow` database user
|
||||
- `DATABASE_HOST`: The host computer that runs the database (usually `localhost`)
|
||||
|
||||
|
|
|
@ -31,9 +31,7 @@ services:
|
|||
- db
|
||||
- mjml
|
||||
environment:
|
||||
- PUBLIC_BACKEND_DOMAIN=localhost:8001
|
||||
- PUBLIC_BACKEND_URL=http://localhost:8001
|
||||
- PUBLIC_WEB_FRONTEND_DOMAIN=localhost:3001
|
||||
- PUBLIC_WEB_FRONTEND_URL=http://localhost:3001
|
||||
|
||||
web-frontend:
|
||||
|
|
Loading…
Reference in a new issue