From b7456861c6a5be02fb17ae3d4cc96c4024a83044 Mon Sep 17 00:00:00 2001 From: Neda Moeini <neda.moeini@geant.org> Date: Tue, 4 Mar 2025 11:59:30 +0100 Subject: [PATCH] Add logout functionality --- sage_validation/accounts/urls.py | 7 +++++ .../file_validator/templates/upload.html | 29 ++++++++++++++----- sage_validation/file_validator/views.py | 4 ++- sage_validation/settings.py | 2 +- sage_validation/templates/base.html | 12 ++++---- sage_validation/urls.py | 4 +-- 6 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 sage_validation/accounts/urls.py diff --git a/sage_validation/accounts/urls.py b/sage_validation/accounts/urls.py new file mode 100644 index 0000000..d2b6ead --- /dev/null +++ b/sage_validation/accounts/urls.py @@ -0,0 +1,7 @@ +"""URL configuration for the accounts' app.""" +from django.contrib.auth.views import LogoutView +from django.urls import path + +urlpatterns = [ + path("logout/", LogoutView.as_view(), name="logout"), +] diff --git a/sage_validation/file_validator/templates/upload.html b/sage_validation/file_validator/templates/upload.html index ec8619d..a942890 100644 --- a/sage_validation/file_validator/templates/upload.html +++ b/sage_validation/file_validator/templates/upload.html @@ -77,19 +77,32 @@ successSection.classList.remove('hidden'); downloadLink.href = result.download_url; downloadSection.classList.remove('hidden'); - } else if (response.status === 400 && result.status === 'error') { - for (const [field, messages] of Object.entries(result.errors)) { - messages.forEach(message => { - const li = document.createElement('li'); - li.textContent = `${field}: ${message}`; - errorList.appendChild(li); - }); + } else { + errorList.innerHTML = ''; + + if (response.status === 403) { + const li = document.createElement('li'); + li.textContent = 'You are not authorized to perform this action.'; + errorList.appendChild(li); + } else if (response.status === 400 && result.status === 'error') { + for (const [field, messages] of Object.entries(result.errors)) { + messages.forEach(message => { + const li = document.createElement('li'); + li.textContent = `${field}: ${message}`; + errorList.appendChild(li); + }); + } + } else { + const li = document.createElement('li'); + li.textContent = 'An unexpected error occurred. Please try again.'; + errorList.appendChild(li); } + errorSection.classList.remove('hidden'); } } catch (error) { const li = document.createElement('li'); - li.textContent = 'An unexpected error occurred. Please try again.'; + li.textContent = 'Failed to connect to the server. Please check your internet connection.'; errorList.appendChild(li); errorSection.classList.remove('hidden'); } diff --git a/sage_validation/file_validator/views.py b/sage_validation/file_validator/views.py index 9bea9c6..a041fbc 100644 --- a/sage_validation/file_validator/views.py +++ b/sage_validation/file_validator/views.py @@ -1,6 +1,7 @@ """Views for the file_validator app.""" import csv import io +from typing import ClassVar from django.http import HttpRequest, HttpResponse from django.shortcuts import render @@ -29,7 +30,8 @@ def upload_page_view(request: HttpRequest) -> HttpResponse: class CSVUploadAPIView(APIView): """API view for uploading a CSV file.""" - permission_classes = [IsAuthenticated] + + permission_classes: ClassVar[list] = [IsAuthenticated] def post(self, request: Request) -> Response: """Handle CSV upload and validation.""" diff --git a/sage_validation/settings.py b/sage_validation/settings.py index dea87df..2b9bf7d 100644 --- a/sage_validation/settings.py +++ b/sage_validation/settings.py @@ -167,4 +167,4 @@ SOCIAL_AUTH_GOOGLE_OAUTH2_REDIRECT_URI = "http://localhost:8000/complete/google- SOCIAL_AUTH_JSONFIELD_ENABLED = True SOCIAL_AUTH_URL_NAMESPACE = 'social' LOGIN_REDIRECT_URL = "/" -SOCIAL_AUTH_ALLOW_DISCONNECT = True \ No newline at end of file +LOGOUT_REDIRECT_URL = "/" \ No newline at end of file diff --git a/sage_validation/templates/base.html b/sage_validation/templates/base.html index 38f87f4..71daa8e 100644 --- a/sage_validation/templates/base.html +++ b/sage_validation/templates/base.html @@ -20,11 +20,13 @@ <div class="flex items-center"> <!-- Login link --> {% if user.is_authenticated %} <p class="text-white">Welcome, {{ user.username }}!</p> - {# <a href="{% url 'social:disconnect' 'google-oauth2' %}" class="text-white hover:text-gray-300">Logout</a>#} -{# <form action="{% url 'social:disconnect' 'google-oauth2' %}" method="post">#} -{# {% csrf_token %}#} -{# <button type="submit">Logout</button>#} -{# </form>#} + <form action="{% url 'logout' %}" method="post" class="inline-block ml-4"> + {% csrf_token %} + <button type="submit" + class="bg-red-600 text-white px-4 py-2 rounded-lg hover:bg-red-700 focus:outline-none focus:ring focus:ring-red-400"> + Logout + </button> + </form> {% else %} <a href="{% url "social:begin" "google-oauth2" %}" class="text-white hover:text-gray-300">Login</a> {% endif %} diff --git a/sage_validation/urls.py b/sage_validation/urls.py index f839b99..1146896 100644 --- a/sage_validation/urls.py +++ b/sage_validation/urls.py @@ -9,6 +9,6 @@ urlpatterns = [ path("admin/", admin.site.urls), path("file-validator/", include("sage_validation.file_validator.urls")), path("", index_view, name="index"), - path("", include("social_django.urls", namespace="social")) - + path("", include("social_django.urls", namespace="social")), + path("accounts/", include("sage_validation.accounts.urls")), ] -- GitLab