mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	use django authentication instead of auth tokens.
This commit is contained in:
		
							
								
								
									
										7
									
								
								src/documents/static/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/documents/static/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										44
									
								
								src/documents/static/signin.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/documents/static/signin.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| html, | ||||
| body { | ||||
|   height: 100%; | ||||
| } | ||||
|  | ||||
| body { | ||||
|   display: -ms-flexbox; | ||||
|   display: flex; | ||||
|   -ms-flex-align: center; | ||||
|   align-items: center; | ||||
|   padding-top: 40px; | ||||
|   padding-bottom: 40px; | ||||
|   background-color: #f5f5f5; | ||||
| } | ||||
|  | ||||
| .form-signin { | ||||
|   width: 100%; | ||||
|   max-width: 330px; | ||||
|   padding: 15px; | ||||
|   margin: auto; | ||||
| } | ||||
| .form-signin .checkbox { | ||||
|   font-weight: 400; | ||||
| } | ||||
| .form-signin .form-control { | ||||
|   position: relative; | ||||
|   box-sizing: border-box; | ||||
|   height: auto; | ||||
|   padding: 10px; | ||||
|   font-size: 16px; | ||||
| } | ||||
| .form-signin .form-control:focus { | ||||
|   z-index: 2; | ||||
| } | ||||
| .form-signin input[type="text"] { | ||||
|   margin-bottom: -1px; | ||||
|   border-bottom-right-radius: 0; | ||||
|   border-bottom-left-radius: 0; | ||||
| } | ||||
| .form-signin input[type="password"] { | ||||
|   margin-bottom: 10px; | ||||
|   border-top-left-radius: 0; | ||||
|   border-top-right-radius: 0; | ||||
| } | ||||
| @@ -9,11 +9,11 @@ | ||||
|   <base href="/"> | ||||
|   <meta name="viewport" content="width=device-width, initial-scale=1"> | ||||
|   <link rel="icon" type="image/x-icon" href="favicon.ico"> | ||||
| <link rel="stylesheet" href="{% static 'styles.css' %}"></head> | ||||
| <link rel="stylesheet" href="{% static 'frontend/styles.css' %}"></head> | ||||
| <body> | ||||
|   <app-root>Loading...</app-root> | ||||
| 	<script src="{% static 'runtime.js' %}" defer></script> | ||||
| 	<script src="{% static 'polyfills.js' %}" defer></script> | ||||
| 	<script src="{% static 'main.js' %}" defer></script> | ||||
| 	<script src="{% static 'frontend/runtime.js' %}" defer></script> | ||||
| 	<script src="{% static 'frontend/polyfills.js' %}" defer></script> | ||||
| 	<script src="{% static 'frontend/main.js' %}" defer></script> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
							
								
								
									
										44
									
								
								src/documents/templates/registration/logged_out.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/documents/templates/registration/logged_out.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| <!doctype html> | ||||
|  | ||||
| {% load static %} | ||||
|  | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||||
|     <meta name="description" content=""> | ||||
|     <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> | ||||
|     <meta name="generator" content="Jekyll v4.1.1"> | ||||
|     <title>Paperless Sign In</title> | ||||
|  | ||||
|     <!-- Bootstrap core CSS --> | ||||
| 		<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet"> | ||||
|  | ||||
|     <style> | ||||
|       .bd-placeholder-img { | ||||
|         font-size: 1.125rem; | ||||
|         text-anchor: middle; | ||||
|         -webkit-user-select: none; | ||||
|         -moz-user-select: none; | ||||
|         -ms-user-select: none; | ||||
|         user-select: none; | ||||
|       } | ||||
|  | ||||
|       @media (min-width: 768px) { | ||||
|         .bd-placeholder-img-lg { | ||||
|           font-size: 3.5rem; | ||||
|         } | ||||
|       } | ||||
|     </style> | ||||
|     <!-- Custom styles for this template --> | ||||
|     <link href="{% static 'signin.css' %}" rel="stylesheet"> | ||||
|   </head> | ||||
|  | ||||
|   <body class="text-center"> | ||||
|     <div class="form-signin"> | ||||
| 			<img class="mb-4" src="{% static 'frontend/assets/logo.svg' %}" alt="" width="300"> | ||||
| 			<p>You have been successfully logged out. Bye!</p> | ||||
| 			<a href="/">Sign in again</a> | ||||
| 		</div> | ||||
| 	</body> | ||||
| </html> | ||||
							
								
								
									
										54
									
								
								src/documents/templates/registration/login.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/documents/templates/registration/login.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| <!doctype html> | ||||
|  | ||||
| {% load static %} | ||||
|  | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="utf-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | ||||
|     <meta name="description" content=""> | ||||
|     <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"> | ||||
|     <meta name="generator" content="Jekyll v4.1.1"> | ||||
|     <title>Paperless Sign In</title> | ||||
|  | ||||
|     <!-- Bootstrap core CSS --> | ||||
| 		<link href="{% static 'bootstrap.min.css' %}" rel="stylesheet"> | ||||
|  | ||||
|     <style> | ||||
|       .bd-placeholder-img { | ||||
|         font-size: 1.125rem; | ||||
|         text-anchor: middle; | ||||
|         -webkit-user-select: none; | ||||
|         -moz-user-select: none; | ||||
|         -ms-user-select: none; | ||||
|         user-select: none; | ||||
|       } | ||||
|  | ||||
|       @media (min-width: 768px) { | ||||
|         .bd-placeholder-img-lg { | ||||
|           font-size: 3.5rem; | ||||
|         } | ||||
|       } | ||||
|     </style> | ||||
|     <!-- Custom styles for this template --> | ||||
|     <link href="{% static 'signin.css' %}" rel="stylesheet"> | ||||
|   </head> | ||||
|  | ||||
|   <body class="text-center"> | ||||
|     <form class="form-signin" method="post"> | ||||
| 			{% csrf_token %} | ||||
| 			<img class="mb-4" src="{% static 'frontend/assets/logo.svg' %}" alt="" width="300"> | ||||
| 			<p>Please sign in.</p> | ||||
| 			{% if form.errors %} | ||||
| 				<div class="alert alert-danger" role="alert"> | ||||
| 					Your username and password didn't match. Please try again. | ||||
| 				</div> | ||||
| 			{% endif %} | ||||
| 			<label for="inputUsername" class="sr-only">Username</label> | ||||
| 			<input type="text" name="username" id="inputUsername" class="form-control" placeholder="Username" required autofocus> | ||||
| 			<label for="inputPassword" class="sr-only">Password</label> | ||||
| 			<input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required> | ||||
| 			<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> | ||||
| 		</form> | ||||
| 	</body> | ||||
| </html> | ||||
| @@ -1,11 +1,17 @@ | ||||
| from rest_framework.authentication import TokenAuthentication | ||||
| from django.conf import settings | ||||
| from django.contrib.auth.models import User | ||||
| from rest_framework import authentication | ||||
|  | ||||
|  | ||||
| class AngularApiAuthenticationOverride(authentication.BaseAuthentication): | ||||
|     """ This class is here to provide authentication to the angular dev server | ||||
|         during development. This is disabled in production. | ||||
|     """ | ||||
|  | ||||
| # This authentication method is required to serve documents and thumbnails for the front end. | ||||
| # https://stackoverflow.com/questions/29433416/token-in-query-string-with-django-rest-frameworks-tokenauthentication | ||||
| class QueryTokenAuthentication(TokenAuthentication): | ||||
|     def authenticate(self, request): | ||||
|         # Check if 'token_auth' is in the request query params. | ||||
|         if 'auth_token' in request.query_params and 'HTTP_AUTHORIZATION' not in request.META: | ||||
|             return self.authenticate_credentials(request.query_params.get('auth_token')) | ||||
|         if settings.DEBUG and 'Origin' in request.headers and request.headers['Origin'] == 'http://localhost:4200': | ||||
|             user = User.objects.filter(is_staff=True).first() | ||||
|             print("Auto-Login with user {}".format(user)) | ||||
|             return (user, None) | ||||
|         else: | ||||
|             return None | ||||
|   | ||||
| @@ -21,6 +21,9 @@ def __get_boolean(key, default="NO"): | ||||
|     """ | ||||
|     return bool(os.getenv(key, default).lower() in ("yes", "y", "1", "t", "true")) | ||||
|  | ||||
| # NEVER RUN WITH DEBUG IN PRODUCTION. | ||||
| DEBUG = __get_boolean("PAPERLESS_DEBUG", "NO") | ||||
|  | ||||
| ############################################################################### | ||||
| # Directories                                                                 # | ||||
| ############################################################################### | ||||
| @@ -66,7 +69,6 @@ INSTALLED_APPS = [ | ||||
|     "django.contrib.admin", | ||||
|  | ||||
|     "rest_framework", | ||||
|     "rest_framework.authtoken", | ||||
|     "django_filters", | ||||
|  | ||||
| ] | ||||
| @@ -74,11 +76,15 @@ INSTALLED_APPS = [ | ||||
| REST_FRAMEWORK = { | ||||
|     'DEFAULT_AUTHENTICATION_CLASSES': [ | ||||
|         'rest_framework.authentication.BasicAuthentication', | ||||
|         'rest_framework.authentication.TokenAuthentication', | ||||
|         'paperless.auth.QueryTokenAuthentication' | ||||
|         'rest_framework.authentication.SessionAuthentication' | ||||
|     ] | ||||
| } | ||||
|  | ||||
| if DEBUG: | ||||
|     REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'].append( | ||||
|         'paperless.auth.AngularApiAuthenticationOverride' | ||||
|     ) | ||||
|  | ||||
| MIDDLEWARE = [ | ||||
|     'django.middleware.security.SecurityMiddleware', | ||||
|     'whitenoise.middleware.WhiteNoiseMiddleware', | ||||
| @@ -93,8 +99,6 @@ MIDDLEWARE = [ | ||||
|  | ||||
| ROOT_URLCONF = 'paperless.urls' | ||||
|  | ||||
| LOGIN_URL = "admin:login" | ||||
|  | ||||
| FORCE_SCRIPT_NAME = os.getenv("PAPERLESS_FORCE_SCRIPT_NAME") | ||||
|  | ||||
| WSGI_APPLICATION = 'paperless.wsgi.application' | ||||
| @@ -122,9 +126,6 @@ TEMPLATES = [ | ||||
| # Security                                                                    # | ||||
| ############################################################################### | ||||
|  | ||||
| # NEVER RUN WITH DEBUG IN PRODUCTION. | ||||
| DEBUG = __get_boolean("PAPERLESS_DEBUG", "NO") | ||||
|  | ||||
| if DEBUG: | ||||
|     X_FRAME_OPTIONS = '' | ||||
|     # this should really be 'allow-from uri' but its not supported in any mayor | ||||
|   | ||||
| @@ -1,9 +1,9 @@ | ||||
| from django.conf.urls import include, url | ||||
| from django.contrib import admin | ||||
| from django.contrib.auth.decorators import login_required | ||||
| from django.urls import path | ||||
| from django.views.decorators.csrf import csrf_exempt | ||||
| from django.views.generic import RedirectView | ||||
| from rest_framework.authtoken import views | ||||
| from rest_framework.routers import DefaultRouter | ||||
|  | ||||
| from paperless.views import FaviconView | ||||
| @@ -34,7 +34,7 @@ urlpatterns = [ | ||||
|     url(r"^api/search/autocomplete/", SearchAutoCompleteView.as_view(), name="autocomplete"), | ||||
|     url(r"^api/search/", SearchView.as_view(), name="search"), | ||||
|     url(r"^api/statistics/", StatisticsView.as_view(), name="statistics"), | ||||
|     url(r"^api/token/", views.obtain_auth_token), url(r"^api/", include((api_router.urls, 'drf'), namespace="drf")), | ||||
|     url(r"^api/", include((api_router.urls, 'drf'), namespace="drf")), | ||||
|  | ||||
|     # Favicon | ||||
|     url(r"^favicon.ico$", FaviconView.as_view(), name="favicon"), | ||||
| @@ -58,10 +58,12 @@ urlpatterns = [ | ||||
|     url(r"^push$", csrf_exempt(RedirectView.as_view(url='/api/documents/post_document/'))), | ||||
|  | ||||
|     # Frontend assets TODO: this is pretty bad. | ||||
|     path('assets/<path:path>', RedirectView.as_view(url='/static/assets/%(path)s')), | ||||
|     path('assets/<path:path>', RedirectView.as_view(url='/static/frontend/assets/%(path)s')), | ||||
|  | ||||
|     path('accounts/', include('django.contrib.auth.urls')), | ||||
|  | ||||
|     # Root of the Frontent | ||||
|     url(r".*", IndexView.as_view()), | ||||
|     url(r".*", login_required(IndexView.as_view())), | ||||
|  | ||||
| ] | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonas Winkler
					Jonas Winkler