diff --git a/logs_collector/account/__init__.py b/logs_collector/account/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/logs_collector/account/admin.py b/logs_collector/account/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/logs_collector/account/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/logs_collector/account/apps.py b/logs_collector/account/apps.py new file mode 100644 index 0000000..2b08f1a --- /dev/null +++ b/logs_collector/account/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class AccountConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'account' diff --git a/logs_collector/account/migrations/__init__.py b/logs_collector/account/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/logs_collector/account/models.py b/logs_collector/account/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/logs_collector/account/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/logs_collector/account/tests.py b/logs_collector/account/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/logs_collector/account/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/logs_collector/account/urls.py b/logs_collector/account/urls.py new file mode 100644 index 0000000..f7f1785 --- /dev/null +++ b/logs_collector/account/urls.py @@ -0,0 +1,40 @@ +from django.conf import settings +from django.urls import path +from django.contrib.auth.views import LogoutView + +from rest_framework_simplejwt.views import ( + TokenObtainPairView, + TokenRefreshView, + TokenVerifyView +) + + +app_name = 'account' + +urlpatterns = [ + # WEB LOGOUT: + path( + 'accounts/logout/', + LogoutView.as_view(next_page=settings.LOGOUT_REDIRECT_URL), + name='logout' + ) +] + +urlpatterns += [ + # JWT AUTH: + path( + 'api/v1/auth/token/', + TokenObtainPairView.as_view(), + name='token_obtain_pair' + ), + path( + 'api/v1/auth/token/refresh/', + TokenRefreshView.as_view(), + name='token_refresh' + ), + path( + 'api/v1/auth/token/verify/', + TokenVerifyView.as_view(), + name='token_verify' + ), +] diff --git a/logs_collector/account/utils.py b/logs_collector/account/utils.py new file mode 100644 index 0000000..63643e8 --- /dev/null +++ b/logs_collector/account/utils.py @@ -0,0 +1,46 @@ +from django.conf import settings +from django.contrib.auth import REDIRECT_FIELD_NAME +from django.contrib.auth.views import redirect_to_login +from django.http import HttpResponseRedirect +from django.shortcuts import resolve_url +from django.urls import reverse +from django.utils.http import url_has_allowed_host_and_scheme # renamed Dj^3.* +from two_factor.admin import AdminSiteOTPRequired, AdminSiteOTPRequiredMixin + + +# https://stackoverflow.com/questions/48600737/django-two-factor-auth-cant-access-admin-site +class AdminSiteOTPRequiredMixinRedirectSetup(AdminSiteOTPRequired): + """ + Fixes the current implementation of django-two-factor-auth = 1.15.3 + when admin page is patched for 2fa + (circular redirect - super user created with manage.py + and cannot log in because he does not have a device configured). + The class redirects to the setup page. + After that, you can log in as usual. + """ + def login(self, request, extra_context=None): + redirect_to = request.POST.get( + REDIRECT_FIELD_NAME, request.GET.get(REDIRECT_FIELD_NAME) + ) + # For users not yet verified the AdminSiteOTPRequired.has_permission + # will fail. So use the standard admin has_permission check: + # (is_active and is_staff) and then check for verification. + # Go to index if they pass, otherwise make them setup OTP device. + if request.method == "GET" and super( + AdminSiteOTPRequiredMixin, self + ).has_permission(request): + # Already logged-in and verified by OTP + if request.user.is_verified(): + # User has permission + index_path = reverse("admin:index", current_app=self.name) + else: + # User has permission but no OTP set: + index_path = reverse("two_factor:setup", current_app=self.name) + return HttpResponseRedirect(index_path) + + if not redirect_to or not url_has_allowed_host_and_scheme( + url=redirect_to, allowed_hosts=[request.get_host()] + ): + redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) + + return redirect_to_login(redirect_to) diff --git a/logs_collector/account/views.py b/logs_collector/account/views.py new file mode 100644 index 0000000..e69de29 diff --git a/logs_collector/collector/templates/collector/base.html b/logs_collector/collector/templates/collector/base.html index 7d8b44e..7d4ca7a 100644 --- a/logs_collector/collector/templates/collector/base.html +++ b/logs_collector/collector/templates/collector/base.html @@ -2,39 +2,8 @@ - - - - - - - - - {% block title %}{% endblock title %} + {% include 'collector/includes/metalinks.html' %} + {% block title %}{% endblock title %}
diff --git a/logs_collector/collector/templates/collector/includes/metalinks.html b/logs_collector/collector/templates/collector/includes/metalinks.html new file mode 100644 index 0000000..bdab324 --- /dev/null +++ b/logs_collector/collector/templates/collector/includes/metalinks.html @@ -0,0 +1,33 @@ +{% load static %} + + + + + + + + diff --git a/logs_collector/collector/templates/collector/includes/navigation.html b/logs_collector/collector/templates/collector/includes/navigation.html index 8d050ba..040c451 100644 --- a/logs_collector/collector/templates/collector/includes/navigation.html +++ b/logs_collector/collector/templates/collector/includes/navigation.html @@ -1,20 +1,5 @@ {% load collector_extras %} {% get_platforms as platforms %} - - - - - - - - - - - - - - -