optional basic HTTP authentication, resolves #62

This commit is contained in:
meeb 2021-02-19 12:58:34 +11:00
parent d6852bf828
commit 6fbf72d0e7
6 changed files with 79 additions and 2 deletions

View File

@ -17,6 +17,7 @@ httptools = "*"
youtube-dl = "*" youtube-dl = "*"
django-background-tasks = "*" django-background-tasks = "*"
requests = "*" requests = "*"
django-basicauth = "*"
[requires] [requires]
python_version = "3" python_version = "3"

10
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "a4bb556fc61ee4583f9588980450b071814298ee4d1a1023fad149c14d14aaba" "sha256": "f698e2853dec2d325d2d7e752620fc81d911022d394a57f2f8a9349ac2682752"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -59,6 +59,14 @@
"index": "pypi", "index": "pypi",
"version": "==1.2.5" "version": "==1.2.5"
}, },
"django-basicauth": {
"hashes": [
"sha256:15e9e366f698f53c71b1e794dafea060f990a2ac556bae6b7330dd25324a091c",
"sha256:e5e47d1acdc1943bedcc1bf673059d6c15e257dfe9eef67a22fb824f79546c0d"
],
"index": "pypi",
"version": "==0.5.3"
},
"django-compat": { "django-compat": {
"hashes": [ "hashes": [
"sha256:3ac9a3bedc56b9365d9eb241bc5157d0c193769bf995f9a78dc1bc24e7c2331b" "sha256:3ac9a3bedc56b9365d9eb241bc5157d0c193769bf995f9a78dc1bc24e7c2331b"

View File

@ -139,6 +139,40 @@ Alternatively, for Docker Compose, you can use something like:
- PGID=1000 - PGID=1000
``` ```
## Optional authentication
If you want to enable a basic username and password to be required to access the
TubeSync dashboard you can set them with the following environment variables:
```bash
HTTP_USER
HTTP_PASS
```
For example in the `docker run ...` line add in:
```bash
...
-e HTTP_USER=some-username \
-e HTTP_PASS=some-secure-password \
...
```
Or in your Docker Compose file you would add in:
```yaml
...
environment:
- HTTP_USER=some-username
- HTTP_PASS=some-secure-password
...
```
When BOTH `HTTP_USER` and `HTTP_PASS` are set then basic HTTP authentication will be
enabled.
# Updating # Updating
To update, you can just pull a new version of the container image as they are released. To update, you can just pull a new version of the container image as they are released.
@ -300,7 +334,9 @@ can log in at http://localhost:4848/admin
### Are there user accounts or multi-user support? ### Are there user accounts or multi-user support?
No not at the moment. This could be added later if there is demand for it. There is support for basic HTTP authentication by setting the `HTTP_USER` and
`HTTP_PASS` environment variables. There is not support for multi-user or user
management.
### Does TubeSync support HTTPS? ### Does TubeSync support HTTPS?
@ -328,6 +364,8 @@ useful if you are manually installing TubeSync in some other environment. These
| GUNICORN_WORKERS | Number of gunicorn workers to spawn | 3 | | GUNICORN_WORKERS | Number of gunicorn workers to spawn | 3 |
| LISTEN_HOST | IP address for gunicorn to listen on | 127.0.0.1 | | LISTEN_HOST | IP address for gunicorn to listen on | 127.0.0.1 |
| LISTEN_PORT | Port number for gunicorn to listen on | 8080 | | LISTEN_PORT | Port number for gunicorn to listen on | 8080 |
| HTTP_USER | Sets the username for HTTP basic authentication | some-username |
| HTTP_PASS | Sets the password for HTTP basic authentication | some-secure-password |
# Manual, non-containerised, installation # Manual, non-containerised, installation

View File

@ -1,4 +1,6 @@
from django.conf import settings
from django.forms import BaseForm from django.forms import BaseForm
from basicauth.middleware import BasicAuthMiddleware as BaseBasicAuthMiddleware
class MaterializeDefaultFieldsMiddleware: class MaterializeDefaultFieldsMiddleware:
@ -19,3 +21,12 @@ class MaterializeDefaultFieldsMiddleware:
for _, field in v.fields.items(): for _, field in v.fields.items():
field.widget.attrs.update({'class':'browser-default'}) field.widget.attrs.update({'class':'browser-default'})
return response return response
class BasicAuthMiddleware(BaseBasicAuthMiddleware):
def process_request(self, request):
bypass_uris = getattr(settings, 'BASICAUTH_ALWAYS_ALLOW_URIS', [])
if request.path in bypass_uris:
return None
return super().process_request(request)

View File

@ -38,3 +38,15 @@ if BACKGROUND_TASK_ASYNC_THREADS > MAX_BACKGROUND_TASK_ASYNC_THREADS:
MEDIA_ROOT = CONFIG_BASE_DIR / 'media' MEDIA_ROOT = CONFIG_BASE_DIR / 'media'
DOWNLOAD_ROOT = DOWNLOADS_BASE_DIR DOWNLOAD_ROOT = DOWNLOADS_BASE_DIR
YOUTUBE_DL_CACHEDIR = CONFIG_BASE_DIR / 'cache' YOUTUBE_DL_CACHEDIR = CONFIG_BASE_DIR / 'cache'
BASICAUTH_USERNAME = os.getenv('HTTP_USER', '').strip()
BASICAUTH_PASSWORD = os.getenv('HTTP_PASS', '').strip()
if BASICAUTH_USERNAME and BASICAUTH_PASSWORD:
BASICAUTH_DISABLE = False
BASICAUTH_USERS = {
BASICAUTH_USERNAME: BASICAUTH_PASSWORD,
}
else:
BASICAUTH_DISABLE = True
BASICAUTH_USERS = {}

View File

@ -37,6 +37,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware',
'common.middleware.MaterializeDefaultFieldsMiddleware', 'common.middleware.MaterializeDefaultFieldsMiddleware',
'common.middleware.BasicAuthMiddleware',
] ]
@ -117,6 +118,12 @@ Disallow: /
X_FRAME_OPTIONS = 'SAMEORIGIN' X_FRAME_OPTIONS = 'SAMEORIGIN'
BASICAUTH_DISABLE = True
BASICAUTH_REALM = 'Authenticate to TubeSync'
BASICAUTH_ALWAYS_ALLOW_URIS = ('/healthcheck',)
BASICAUTH_USERS = {}
HEALTHCHECK_FIREWALL = True HEALTHCHECK_FIREWALL = True
HEALTHCHECK_ALLOWED_IPS = ('127.0.0.1',) HEALTHCHECK_ALLOWED_IPS = ('127.0.0.1',)