From ea632ca17f5b906ff56beac5de16ee0ad3d2aa54 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Tue, 21 Nov 2023 13:56:09 +0100 Subject: [PATCH] Adapt user login (based on django.contrib.auth) --- .../project_template/project_name/settings.py | 16 +++++++++- orchestra/contrib/musician/api.py | 28 ++++++++--------- orchestra/contrib/musician/forms.py | 8 ++--- orchestra/contrib/musician/mixins.py | 30 +++++-------------- orchestra/contrib/musician/views.py | 12 ++++---- 5 files changed, 46 insertions(+), 48 deletions(-) diff --git a/orchestra/conf/project_template/project_name/settings.py b/orchestra/conf/project_template/project_name/settings.py index c858b53c..cd586d51 100644 --- a/orchestra/conf/project_template/project_name/settings.py +++ b/orchestra/conf/project_template/project_name/settings.py @@ -220,8 +220,22 @@ EMAIL_BACKEND = 'orchestra.contrib.mailer.backends.EmailBackend' DATA_UPLOAD_MAX_NUMBER_FIELDS = None +############################ +## MUSICIAN CONFIGURATION ## +############################ + +# Direcction than go when you login +LOGIN_REDIRECT_URL = 'musician:dashboard' + +# Where requests are redirected for login +LOGIN_URL = 'musician:login' + +# The URL or named URL pattern where requests are redirected after logout +LOGOUT_REDIRECT_URL = 'musician:login' + + ################################# -## 3RD PARTY APPS CONIGURATION ## +## 3RD PARTY APPS CONFIGURATION ## ################################# # Admin Tools diff --git a/orchestra/contrib/musician/api.py b/orchestra/contrib/musician/api.py index 6b60c0c0..fa4c5343 100644 --- a/orchestra/contrib/musician/api.py +++ b/orchestra/contrib/musician/api.py @@ -1,12 +1,13 @@ import urllib.parse -import requests from django.conf import settings +from django.contrib.auth import authenticate, login from django.http import Http404 from django.urls.exceptions import NoReverseMatch from django.utils.translation import gettext_lazy as _ -from .models import Address, DatabaseService, Domain, Mailbox, SaasService, UserAccount, WebSite +from .models import (Address, DatabaseService, Domain, Mailbox, SaasService, + UserAccount, WebSite) DOMAINS_PATH = 'domains/' TOKEN_PATH = '/api-token-auth/' @@ -37,14 +38,10 @@ API_PATHS = { class Orchestra(object): - def __init__(self, *args, username=None, password=None, **kwargs): - self.base_url = kwargs.pop('base_url', settings.API_BASE_URL) + def __init__(self, request, username=None, password=None, **kwargs): + self.request = request self.username = username - self.session = requests.Session() - self.auth_token = kwargs.pop("auth_token", None) - - if self.auth_token is None: - self.auth_token = self.authenticate(self.username, password) + self.user = self.authenticate(self.username, password) def build_absolute_uri(self, path_name): path = API_PATHS.get(path_name, None) @@ -55,13 +52,14 @@ class Orchestra(object): return urllib.parse.urljoin(self.base_url, path) def authenticate(self, username, password): - url = self.build_absolute_uri('token-auth') - response = self.session.post( - url, - data={"username": username, "password": password}, - ) + user = authenticate(self.request, username=username, password=password) - return response.json().get("token", None) + if user is not None: + login(self.request, user) + return user + + # Return an 'invalid login' error message. + return None def request(self, verb, resource=None, url=None, data=None, render_as="json", querystring=None, raise_exception=True): assert verb in ["HEAD", "GET", "POST", "PATCH", "PUT", "DELETE"] diff --git a/orchestra/contrib/musician/forms.py b/orchestra/contrib/musician/forms.py index 98e23c41..eae90a37 100644 --- a/orchestra/contrib/musician/forms.py +++ b/orchestra/contrib/musician/forms.py @@ -6,6 +6,7 @@ from django.utils.translation import gettext_lazy as _ from . import api + class LoginForm(AuthenticationForm): def clean(self): @@ -13,14 +14,13 @@ class LoginForm(AuthenticationForm): password = self.cleaned_data.get('password') if username is not None and password: - orchestra = api.Orchestra(username=username, password=password) + orchestra = api.Orchestra(self.request, username=username, password=password) - if orchestra.auth_token is None: + if orchestra.user is None: raise self.get_invalid_login_error() else: self.username = username - self.token = orchestra.auth_token - self.user = orchestra.retrieve_profile() + self.user = orchestra.user return self.cleaned_data diff --git a/orchestra/contrib/musician/mixins.py b/orchestra/contrib/musician/mixins.py index 19a783af..f11cfd7b 100644 --- a/orchestra/contrib/musician/mixins.py +++ b/orchestra/contrib/musician/mixins.py @@ -1,9 +1,10 @@ -from django.contrib.auth.mixins import UserPassesTestMixin +from django.conf import settings +from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.utils.translation import gettext_lazy as _ from django.views.generic.base import ContextMixin -from django.conf import settings from orchestra import get_version + from . import api from .auth import SESSION_KEY_TOKEN @@ -49,30 +50,13 @@ class ExtendedPaginationMixin: return paginate_by -class UserTokenRequiredMixin(UserPassesTestMixin): - """ - Checks that the request has a token that authenticates him/her. - If the user is logged adds context variable 'profile' with its information. - """ - - def test_func(self): - """Check that the user has an authorized token.""" - token = self.request.session.get(SESSION_KEY_TOKEN, None) - if token is None: - return False - - # initialize orchestra api orm - self.orchestra = api.Orchestra(auth_token=token) - - # verify if the token is valid - if self.orchestra.verify_credentials() is None: - return False - - return True +class UserTokenRequiredMixin(LoginRequiredMixin): + # TODO XXX adapt this code def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context.update({ - 'profile': self.orchestra.retrieve_profile(), + # TODO XXX + # 'profile': self.orchestra.retrieve_profile(), }) return context diff --git a/orchestra/contrib/musician/views.py b/orchestra/contrib/musician/views.py index c6885b6f..7816eaad 100644 --- a/orchestra/contrib/musician/views.py +++ b/orchestra/contrib/musician/views.py @@ -1,12 +1,13 @@ +import datetime import logging import smtplib -import datetime from django.conf import settings from django.contrib import messages from django.core.exceptions import ImproperlyConfigured from django.core.mail import mail_managers -from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect +from django.http import (HttpResponse, HttpResponseNotFound, + HttpResponseRedirect) from django.urls import reverse_lazy from django.utils import translation from django.utils.html import format_html @@ -20,9 +21,11 @@ from django.views.generic.list import ListView from requests.exceptions import HTTPError from orchestra import get_version -from .auth import login as auth_login + +# from .auth import login as auth_login from .auth import logout as auth_logout -from .forms import LoginForm, MailboxChangePasswordForm, MailboxCreateForm, MailboxUpdateForm, MailForm +from .forms import (LoginForm, MailboxChangePasswordForm, MailboxCreateForm, + MailboxUpdateForm, MailForm) from .mixins import (CustomContextMixin, ExtendedPaginationMixin, UserTokenRequiredMixin) from .models import (Address, Bill, DatabaseService, Mailbox, @@ -553,7 +556,6 @@ class LoginView(FormView): def form_valid(self, form): """Security check complete. Log the user in.""" - auth_login(self.request, form.username, form.token) # set user language as active language user_language = form.user.language