diff --git a/paperless.conf.example b/paperless.conf.example index 3d90b2915..8aa33216f 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -89,6 +89,11 @@ PAPERLESS_EMAIL_SECRET="" # as is "example.com,www.example.com", but NOT " example.com" or "example.com," #PAPERLESS_ALLOWED_HOSTS="example.com,www.example.com" +# If you decide to use Paperless APIs in an ajax calls, you need to add your +# servers to the allowed hosts that can do CORS calls. By default Paperless allows +# calls from localhost:8080. The same rules as above how the list should look like. +#PAPERLESS_CORS_ALLOWED_HOSTS="localhost:8080,example.com,localhost:8000" + # To host paperless under a subpath url like example.com/paperless you set # this value to /paperless. No trailing slash! # diff --git a/requirements.txt b/requirements.txt index 0c46e4f8d..125a89ac7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,6 +5,7 @@ chardet==3.0.4 coverage==4.5.1 coveralls==1.3.0 dateparser==0.7.0 +django-cors-headers==2.4.0 django-crispy-forms==1.7.2 django-extensions==2.0.7 django-filter==1.1.0 diff --git a/src/documents/filters.py b/src/documents/filters.py index c3c60ccc7..2ed7f29db 100644 --- a/src/documents/filters.py +++ b/src/documents/filters.py @@ -1,4 +1,4 @@ -from django_filters.rest_framework import CharFilter, FilterSet +from django_filters.rest_framework import CharFilter, FilterSet, BooleanFilter from .models import Correspondent, Document, Tag @@ -46,6 +46,9 @@ class DocumentFilterSet(FilterSet): correspondent__slug = CharFilter(name="correspondent__slug", **CHAR_KWARGS) tags__name = CharFilter(name="tags__name", **CHAR_KWARGS) tags__slug = CharFilter(name="tags__slug", **CHAR_KWARGS) + tags__empty = BooleanFilter(name='tags', + lookup_expr='isnull', + distinct=True) class Meta(object): model = Document diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 91d2d2651..e40af01d1 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -61,6 +61,7 @@ "django.contrib.messages", "django.contrib.staticfiles", + "corsheaders", "django_extensions", "documents.apps.DocumentsConfig", @@ -84,6 +85,7 @@ MIDDLEWARE_CLASSES = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -92,6 +94,9 @@ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +# We allow CORS from localhost:8080 +CORS_ORIGIN_WHITELIST = tuple(os.getenv("PAPERLESS_CORS_ALLOWED_HOSTS", "localhost:8080").split(",")) + # If auth is disabled, we just use our "bypass" authentication middleware if bool(os.getenv("PAPERLESS_DISABLE_LOGIN", "false").lower() in ("yes", "y", "1", "t", "true")): _index = MIDDLEWARE_CLASSES.index("django.contrib.auth.middleware.AuthenticationMiddleware")