Add: http custom error pages, more checks js possible error, check if file delete from storage by cli
This commit is contained in:
		
							parent
							
								
									431541b3cb
								
							
						
					
					
						commit
						b2bea677ef
					
				| @ -83,29 +83,35 @@ class ArchiveViewSet(viewsets.ModelViewSet): | |||||||
|                 bound_ticket = Ticket.objects.get(token=upload_token) |                 bound_ticket = Ticket.objects.get(token=upload_token) | ||||||
|                 if bound_ticket.resolved: |                 if bound_ticket.resolved: | ||||||
|                     return Response( |                     return Response( | ||||||
|                         {'error': f'ticket {bound_ticket} already resolved'}, |                         {'detail': f'ticket {bound_ticket} already resolved'}, | ||||||
|                         status=status.HTTP_423_LOCKED |                         status=status.HTTP_423_LOCKED | ||||||
|                     ) |                     ) | ||||||
|                 if bound_ticket.attempts <= 0: |                 if bound_ticket.attempts <= 0: | ||||||
|                     return Response( |                     return Response( | ||||||
|                         {'error': f'token {upload_token} expired'}, |                         {'detail': f'token {upload_token} expired'}, | ||||||
|                         status=status.HTTP_423_LOCKED |                         status=status.HTTP_423_LOCKED | ||||||
|                     ) |                     ) | ||||||
|                 bound_ticket.attempts -= 1 |                 bound_ticket.attempts -= 1 | ||||||
|                 bound_ticket.save() |                 bound_ticket.save() | ||||||
|                 # ? mixin bound ticket number to request.data from user |                 # ? mixin bound ticket number to request.data from user | ||||||
|  |                 try: | ||||||
|                     request.data['ticket'] = bound_ticket.number |                     request.data['ticket'] = bound_ticket.number | ||||||
|  |                 except AttributeError: | ||||||
|  |                     return Response( | ||||||
|  |                         {'detail': 'Bad Request'}, | ||||||
|  |                         status=status.HTTP_400_BAD_REQUEST | ||||||
|  |                     ) | ||||||
|                 # ? change serializer for guest user |                 # ? change serializer for guest user | ||||||
|                 if not request.user.is_authenticated: |                 if not request.user.is_authenticated: | ||||||
|                     self.serializer_class = PublicArchiveUploadSerializer |                     self.serializer_class = PublicArchiveUploadSerializer | ||||||
|             except (ValidationError, ObjectDoesNotExist,): |             except (ValidationError, ObjectDoesNotExist,): | ||||||
|                 return Response( |                 return Response( | ||||||
|                     {'error': f'token {upload_token} is not valid'}, |                     {'detail': f'token {upload_token} is not valid'}, | ||||||
|                     status=status.HTTP_403_FORBIDDEN |                     status=status.HTTP_403_FORBIDDEN | ||||||
|                 ) |                 ) | ||||||
|         else: |         else: | ||||||
|             return Response( |             return Response( | ||||||
|                 {'error': 'Header Upload-Token is required'}, |                 {'detail': 'Header Upload-Token is required'}, | ||||||
|                 status=status.HTTP_401_UNAUTHORIZED |                 status=status.HTTP_401_UNAUTHORIZED | ||||||
|             ) |             ) | ||||||
|         # ! default create method: |         # ! default create method: | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								logs_collector/collector/middleware.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								logs_collector/collector/middleware.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | from django.http import HttpResponse | ||||||
|  | from django.template import loader | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class HttpResponseNotAllowedMiddleware: | ||||||
|  |     def __init__(self, get_response): | ||||||
|  |         self.get_response = get_response | ||||||
|  |         # One-time configuration and initialization. | ||||||
|  | 
 | ||||||
|  |     def __call__(self, request): | ||||||
|  | 
 | ||||||
|  |         # Code to be executed for each request before | ||||||
|  |         # the view (and later middleware) are called. | ||||||
|  | 
 | ||||||
|  |         response = self.get_response(request) | ||||||
|  | 
 | ||||||
|  |         # Code to be executed for each request/response after | ||||||
|  |         # the view is called. | ||||||
|  |         if response.status_code == 405: | ||||||
|  |             context = {} | ||||||
|  |             template = loader.get_template('405.html') | ||||||
|  |             return HttpResponse(template.render(context, request)) | ||||||
|  | 
 | ||||||
|  |         return response | ||||||
| @ -54,7 +54,6 @@ $(function () { | |||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|                 success: function(data, textStatus, jqXHR){ |                 success: function(data, textStatus, jqXHR){ | ||||||
|                     console.log(jqXHR.status); |  | ||||||
|                     alertContainer.innerHTML = genAlertMessage( |                     alertContainer.innerHTML = genAlertMessage( | ||||||
|                         'The file has been successfully uploaded to the server. Thank you!', |                         'The file has been successfully uploaded to the server. Thank you!', | ||||||
|                         'success', |                         'success', | ||||||
| @ -69,13 +68,15 @@ $(function () { | |||||||
|                     }; |                     }; | ||||||
|                 }, |                 }, | ||||||
|                 error: function(jqXHR, textStatus, errorThrown){ |                 error: function(jqXHR, textStatus, errorThrown){ | ||||||
|                     console.log(jqXHR); |  | ||||||
|                     let errorMessage = "Unexpected error. Try again please" |                     let errorMessage = "Unexpected error. Try again please" | ||||||
|                     if (jqXHR.status === 423 || jqXHR.status === 403) { |                     if (jqXHR.status === 423 || jqXHR.status === 403) { | ||||||
|                         errorMessage = `Error ${jqXHR.status}: ${jqXHR.responseJSON.error}` |                         errorMessage = `Error ${jqXHR.status} <br> ${jqXHR.responseJSON.detail}` | ||||||
|                     } |                     } | ||||||
|                     if (jqXHR.status === 401) { |                     if (jqXHR.status === 401) { | ||||||
|                         errorMessage = 'The token field cannot be empty' |                         errorMessage = `Error ${jqXHR.status} <br> The token field cannot be empty` | ||||||
|  |                     } | ||||||
|  |                     if (jqXHR.status === 400) { | ||||||
|  |                         errorMessage = `Error ${jqXHR.status} <br> ${jqXHR.responseJSON.detail}` | ||||||
|                     } |                     } | ||||||
|                     alertContainer.innerHTML = genAlertMessage( |                     alertContainer.innerHTML = genAlertMessage( | ||||||
|                         errorMessage, |                         errorMessage, | ||||||
| @ -97,14 +98,14 @@ $(function () { | |||||||
|             success: function (data, textStatus, jqXHR) { |             success: function (data, textStatus, jqXHR) { | ||||||
|                 if (data.attempts === 0) { |                 if (data.attempts === 0) { | ||||||
|                     alertContainer.innerHTML = genAlertMessage( |                     alertContainer.innerHTML = genAlertMessage( | ||||||
|                         `Token: ${uploadToken} expired`, |                         `Error 423 <br> Token: ${uploadToken} expired`, | ||||||
|                         'danger', |                         'danger', | ||||||
|                         'col-lg-6' |                         'col-lg-6' | ||||||
|                     ); |                     ); | ||||||
|                 } |                 } | ||||||
|                 else if (data.resolved === true) { |                 else if (data.resolved === true) { | ||||||
|                     alertContainer.innerHTML = genAlertMessage( |                     alertContainer.innerHTML = genAlertMessage( | ||||||
|                         `Ticket bound with token: ${uploadToken} <br> already resolved`, |                         `Error 423 <br> Ticket bound with token: ${uploadToken} <br> already resolved`, | ||||||
|                         'danger', |                         'danger', | ||||||
|                         'col-lg-6' |                         'col-lg-6' | ||||||
|                     ); |                     ); | ||||||
| @ -118,11 +119,9 @@ $(function () { | |||||||
|                 }; |                 }; | ||||||
|             }, |             }, | ||||||
|             error: function(jqXHR){ |             error: function(jqXHR){ | ||||||
|                 console.log(jqXHR) |  | ||||||
|                 console.log(jqXHR.responseJSON.detail) |  | ||||||
|                 if (jqXHR.responseJSON.detail) { |                 if (jqXHR.responseJSON.detail) { | ||||||
|                     alertContainer.innerHTML = genAlertMessage( |                     alertContainer.innerHTML = genAlertMessage( | ||||||
|                         `Token: ${uploadToken} is not valid`, |                         `Error 403 <br> Token: ${uploadToken} is not valid`, | ||||||
|                         'danger', |                         'danger', | ||||||
|                         'col-lg-6' |                         'col-lg-6' | ||||||
|                     ) |                     ) | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| from django.contrib.auth.mixins import LoginRequiredMixin | from django.contrib.auth.mixins import LoginRequiredMixin | ||||||
| from django.http import FileResponse | from django.http import FileResponse, Http404 | ||||||
| from django.views import generic | from django.views import generic | ||||||
| from django.views.generic.detail import SingleObjectMixin | from django.views.generic.detail import SingleObjectMixin | ||||||
| from django.db.models import Q | from django.db.models import Q | ||||||
| @ -35,6 +35,10 @@ class ArchiveHandlerView( | |||||||
| 
 | 
 | ||||||
|     def get(self, request, path): |     def get(self, request, path): | ||||||
|         self.object = self.get_object() |         self.object = self.get_object() | ||||||
|  |         try: | ||||||
|  |             self.object.file.size | ||||||
|  |         except FileNotFoundError: | ||||||
|  |             raise Http404(f'File: {self.object.file} not found') | ||||||
|         return FileResponse(self.object.file) |         return FileResponse(self.object.file) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -89,6 +89,7 @@ MIDDLEWARE = [ | |||||||
|     'django.contrib.messages.middleware.MessageMiddleware', |     'django.contrib.messages.middleware.MessageMiddleware', | ||||||
|     'django.middleware.clickjacking.XFrameOptionsMiddleware', |     'django.middleware.clickjacking.XFrameOptionsMiddleware', | ||||||
|     'whitenoise.middleware.WhiteNoiseMiddleware', |     'whitenoise.middleware.WhiteNoiseMiddleware', | ||||||
|  |     'collector.middleware.HttpResponseNotAllowedMiddleware', | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| ROOT_URLCONF = 'logs_collector.urls' | ROOT_URLCONF = 'logs_collector.urls' | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								logs_collector/templates/403_csrf.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								logs_collector/templates/403_csrf.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | {% extends 'errors.html' %} | ||||||
|  | {% load static %} | ||||||
|  | 
 | ||||||
|  | {% block title %} Logs Collector - CSRF error {% endblock title %} | ||||||
|  | 
 | ||||||
|  | {% block status_code %}403{% endblock status_code %} | ||||||
|  | {% block error_message %} | ||||||
|  | <p class="fs-3"> <span class="text-danger">Opps!</span> CSRF verification failed.</p> | ||||||
|  | <p class="lead">Request aborted</p> | ||||||
|  | {% endblock error_message %} | ||||||
							
								
								
									
										10
									
								
								logs_collector/templates/404.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								logs_collector/templates/404.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | {% extends 'errors.html' %} | ||||||
|  | {% load static %} | ||||||
|  | 
 | ||||||
|  | {% block title %} Logs Collector - Not Found {% endblock title %} | ||||||
|  | 
 | ||||||
|  | {% block status_code %}404{% endblock status_code %} | ||||||
|  | {% block error_message %} | ||||||
|  | <p class="fs-3"> <span class="text-danger">Opps!</span> Page not found.</p> | ||||||
|  | <p class="lead">The content you're looking for doesn't exist.</p> | ||||||
|  | {% endblock error_message %} | ||||||
							
								
								
									
										14
									
								
								logs_collector/templates/405.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								logs_collector/templates/405.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | {% extends 'errors.html' %} | ||||||
|  | {% load static %} | ||||||
|  | 
 | ||||||
|  | {% block title %} Logs Collector - Method not allowed {% endblock title %} | ||||||
|  | 
 | ||||||
|  | {% block status_code %}405{% endblock status_code %} | ||||||
|  | {% block error_message %} | ||||||
|  | <p class="fs-3"> <span class="text-danger">Opps!</span> Method not allowed</p> | ||||||
|  | <p class="lead"> | ||||||
|  |   Request method:  | ||||||
|  |   <span class="text-danger">{{ request.method }}</span>  | ||||||
|  |   isn't allowed for this URL | ||||||
|  | </p> | ||||||
|  | {% endblock error_message %} | ||||||
							
								
								
									
										10
									
								
								logs_collector/templates/500.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								logs_collector/templates/500.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | {% extends 'errors.html' %} | ||||||
|  | {% load static %} | ||||||
|  | 
 | ||||||
|  | {% block title %} Logs Collector - Server error {% endblock title %} | ||||||
|  | 
 | ||||||
|  | {% block status_code %}500{% endblock status_code %} | ||||||
|  | {% block error_message %} | ||||||
|  | <p class="fs-3"> <span class="text-danger">Opps!</span> Server error</p> | ||||||
|  | <p class="lead">Unexpected error, please try again or contact system admin </p> | ||||||
|  | {% endblock error_message %} | ||||||
| @ -34,10 +34,12 @@ | |||||||
|     rel="stylesheet" |     rel="stylesheet" | ||||||
|     href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" |     href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" | ||||||
|     > |     > | ||||||
|  |     {% block errors_head %}{% endblock errors_head %} | ||||||
|     {% block collector_head %}{% endblock collector_head %} |     {% block collector_head %}{% endblock collector_head %} | ||||||
|     {% block account_head %}{% endblock account_head %} |     {% block account_head %}{% endblock account_head %} | ||||||
|   </head> |   </head> | ||||||
|   <body class="d-flex flex-column min-vh-100"> |   <body class="d-flex flex-column min-vh-100"> | ||||||
|  |     {% block http_errors %}{% endblock http_errors %} | ||||||
|     {% block collector_content %}{% endblock collector_content %} |     {% block collector_content %}{% endblock collector_content %} | ||||||
|     {% block account_content %}{% endblock account_content %} |     {% block account_content %}{% endblock account_content %} | ||||||
|     <!-- BS dependences JS--> |     <!-- BS dependences JS--> | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								logs_collector/templates/errors.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								logs_collector/templates/errors.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | {% extends 'base.html' %} | ||||||
|  | {% load static %} | ||||||
|  | 
 | ||||||
|  | {% block errors_head %} | ||||||
|  |   <title>{% block title %}{% endblock title %}</title> | ||||||
|  | {% endblock errors_head %} | ||||||
|  | 
 | ||||||
|  | {% block http_errors %} | ||||||
|  | <div class="d-flex align-items-center justify-content-center vh-100" > | ||||||
|  |   <div class="text-center"> | ||||||
|  |       <h1 class="display-1 fw-bold">{% block status_code %}{% endblock status_code %}</h1> | ||||||
|  |       {% block error_message %}{% endblock error_message %} | ||||||
|  |       <a href="{% url 'collector:index' %}" class="btn btn-secondary">Go Home</a> | ||||||
|  |   </div> | ||||||
|  |   <!-- Theme switcher --> | ||||||
|  |   <div class="dropdown position-fixed bottom-0 end-0 mb-3 me-3 bd-mode-toggle"> | ||||||
|  |     {% include 'includes/theme_switcher.html' %} | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  | {% endblock http_errors %} | ||||||
| @ -1,21 +1,29 @@ | |||||||
| <nav class="navbar navbar-expand-lg bg-body-tertiary"> | <nav class="navbar navbar-expand-lg bg-body-tertiary"> | ||||||
|   <div class="container d-flex justify-content-between"> |   <div class="container"> | ||||||
|     <ul class="navbar-nav"> |     <ul class="navbar-nav"> | ||||||
|       <li class="nav-item"> |       <li class="nav-item"> | ||||||
|         <span class="text-muted"> |         <button class="btn"> | ||||||
|           v{{ version }} |           v{{ version }} | ||||||
|           {% if environment != 'Production' %} |           {% if environment != 'Production' %} | ||||||
|             Staging: {{ environment }} |             Staging: {{ environment }} | ||||||
|           {% endif %} |           {% endif %} | ||||||
|           | © {{ author }}  |         </button> | ||||||
|         </span> |       </li> | ||||||
|  |       <!-- Separator --> | ||||||
|  |       <li class="nav-item py-2 py-lg-1 col-12 col-lg-auto"> | ||||||
|  |         <div class="vr d-none d-lg-flex h-100 mx-lg-2 text-white"></div> | ||||||
|  |         <hr class="d-lg-none my-2 text-white-50"> | ||||||
|  |       </li> | ||||||
|  |       <li class="nav-item"> | ||||||
|  |         <button class='btn'> © {{ author }} </button> | ||||||
|       </li> |       </li> | ||||||
|     </ul> |     </ul> | ||||||
|  |     {% if request.user.is_authenticated %} | ||||||
|     <ul class="navbar-nav"> |     <ul class="navbar-nav"> | ||||||
|       <li class="nav-item"> |       <li class="nav-item"> | ||||||
|         <li> |         <li> | ||||||
|           <a |           <a | ||||||
|             class="nav-link" |             class="btn" | ||||||
|             type="button" |             type="button" | ||||||
|             href="{% url 'swagger-ui' %}" |             href="{% url 'swagger-ui' %}" | ||||||
|             target="_blank" |             target="_blank" | ||||||
| @ -28,5 +36,6 @@ | |||||||
|         </a> |         </a> | ||||||
|       </li> |       </li> | ||||||
|     </ul> |     </ul> | ||||||
|  |     {% endif %} | ||||||
|   </div> |   </div> | ||||||
| </nav> | </nav> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user