Split account views into seperate files
This commit is contained in:
parent
21fc5ef8e7
commit
87378a3533
7 changed files with 253 additions and 210 deletions
|
|
@ -1,210 +0,0 @@
|
||||||
from django.contrib import messages
|
|
||||||
from django.contrib.auth import views as django_views
|
|
||||||
from django.core.cache import cache
|
|
||||||
from django.shortcuts import render
|
|
||||||
from django.urls import reverse_lazy
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
from django.views.generic import RedirectView, TemplateView
|
|
||||||
from django.views.generic.edit import FormView, ModelFormMixin
|
|
||||||
|
|
||||||
from registration.backends.default import views as registration_views
|
|
||||||
|
|
||||||
from newsreader.accounts.forms import UserSettingsForm
|
|
||||||
from newsreader.accounts.models import User
|
|
||||||
from newsreader.news.collection.exceptions import StreamException
|
|
||||||
from newsreader.news.collection.reddit import (
|
|
||||||
get_reddit_access_token,
|
|
||||||
get_reddit_authorization_url,
|
|
||||||
)
|
|
||||||
from newsreader.news.collection.tasks import RedditTokenTask
|
|
||||||
|
|
||||||
|
|
||||||
class LoginView(django_views.LoginView):
|
|
||||||
template_name = "accounts/views/login.html"
|
|
||||||
success_url = reverse_lazy("index")
|
|
||||||
|
|
||||||
|
|
||||||
class LogoutView(django_views.LogoutView):
|
|
||||||
next_page = reverse_lazy("accounts:login")
|
|
||||||
|
|
||||||
|
|
||||||
# RegistrationView shows a registration form and sends the email
|
|
||||||
# RegistrationCompleteView shows after filling in the registration form
|
|
||||||
# ActivationView is send within the activation email and activates the account
|
|
||||||
# ActivationCompleteView shows the success screen when activation was succesful
|
|
||||||
# ActivationResendView can be used when activation links are expired
|
|
||||||
# RegistrationClosedView shows when registration is disabled
|
|
||||||
class RegistrationView(registration_views.RegistrationView):
|
|
||||||
disallowed_url = reverse_lazy("accounts:register-closed")
|
|
||||||
template_name = "registration/registration_form.html"
|
|
||||||
success_url = reverse_lazy("accounts:register-complete")
|
|
||||||
|
|
||||||
|
|
||||||
class RegistrationCompleteView(TemplateView):
|
|
||||||
template_name = "registration/registration_complete.html"
|
|
||||||
|
|
||||||
|
|
||||||
class RegistrationClosedView(TemplateView):
|
|
||||||
template_name = "registration/registration_closed.html"
|
|
||||||
|
|
||||||
|
|
||||||
# Redirects or renders failed activation template
|
|
||||||
class ActivationView(registration_views.ActivationView):
|
|
||||||
template_name = "registration/activation_failure.html"
|
|
||||||
|
|
||||||
def get_success_url(self, user):
|
|
||||||
return ("accounts:activate-complete", (), {})
|
|
||||||
|
|
||||||
|
|
||||||
class ActivationCompleteView(TemplateView):
|
|
||||||
template_name = "registration/activation_complete.html"
|
|
||||||
|
|
||||||
|
|
||||||
# Renders activation form resend or resend_activation_complete
|
|
||||||
class ActivationResendView(registration_views.ResendActivationView):
|
|
||||||
template_name = "registration/activation_resend_form.html"
|
|
||||||
|
|
||||||
def render_form_submitted_template(self, form):
|
|
||||||
"""
|
|
||||||
Renders resend activation complete template with the submitted email.
|
|
||||||
|
|
||||||
"""
|
|
||||||
email = form.cleaned_data["email"]
|
|
||||||
context = {"email": email}
|
|
||||||
|
|
||||||
return render(
|
|
||||||
self.request, "registration/activation_resend_complete.html", context
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# PasswordResetView sends the mail
|
|
||||||
# PasswordResetDoneView shows a success message for the above
|
|
||||||
# PasswordResetConfirmView checks the link the user clicked and
|
|
||||||
# prompts for a new password
|
|
||||||
# PasswordResetCompleteView shows a success message for the above
|
|
||||||
class PasswordResetView(django_views.PasswordResetView):
|
|
||||||
template_name = "password-reset/password-reset.html"
|
|
||||||
subject_template_name = "password-reset/password-reset-subject.txt"
|
|
||||||
email_template_name = "password-reset/password-reset-email.html"
|
|
||||||
success_url = reverse_lazy("accounts:password-reset-done")
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordResetDoneView(django_views.PasswordResetDoneView):
|
|
||||||
template_name = "password-reset/password-reset-done.html"
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordResetConfirmView(django_views.PasswordResetConfirmView):
|
|
||||||
template_name = "password-reset/password-reset-confirm.html"
|
|
||||||
success_url = reverse_lazy("accounts:password-reset-complete")
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordResetCompleteView(django_views.PasswordResetCompleteView):
|
|
||||||
template_name = "password-reset/password-reset-complete.html"
|
|
||||||
|
|
||||||
|
|
||||||
class PasswordChangeView(django_views.PasswordChangeView):
|
|
||||||
template_name = "accounts/views/password-change.html"
|
|
||||||
success_url = reverse_lazy("accounts:settings")
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsView(ModelFormMixin, FormView):
|
|
||||||
template_name = "accounts/views/settings.html"
|
|
||||||
success_url = reverse_lazy("accounts:settings")
|
|
||||||
form_class = UserSettingsForm
|
|
||||||
model = User
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
self.object = self.get_object()
|
|
||||||
return super().get(request, *args, **kwargs)
|
|
||||||
|
|
||||||
def get_object(self, **kwargs):
|
|
||||||
return self.request.user
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
user = self.request.user
|
|
||||||
|
|
||||||
reddit_authorization_url = None
|
|
||||||
reddit_refresh_url = None
|
|
||||||
reddit_task_active = cache.get(f"{user.email}-reddit-refresh")
|
|
||||||
|
|
||||||
if (
|
|
||||||
user.reddit_refresh_token
|
|
||||||
and not user.reddit_access_token
|
|
||||||
and not reddit_task_active
|
|
||||||
):
|
|
||||||
reddit_refresh_url = reverse_lazy("accounts:reddit-refresh")
|
|
||||||
|
|
||||||
if not user.reddit_refresh_token:
|
|
||||||
reddit_authorization_url = get_reddit_authorization_url(user)
|
|
||||||
|
|
||||||
return {
|
|
||||||
**super().get_context_data(**kwargs),
|
|
||||||
"reddit_authorization_url": reddit_authorization_url,
|
|
||||||
"reddit_refresh_url": reddit_refresh_url,
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
|
||||||
return {**super().get_form_kwargs(), "instance": self.request.user}
|
|
||||||
|
|
||||||
|
|
||||||
class RedditTemplateView(TemplateView):
|
|
||||||
template_name = "accounts/views/reddit.html"
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
context = self.get_context_data(**kwargs)
|
|
||||||
|
|
||||||
error = request.GET.get("error", None)
|
|
||||||
state = request.GET.get("state", None)
|
|
||||||
code = request.GET.get("code", None)
|
|
||||||
|
|
||||||
if error:
|
|
||||||
return self.render_to_response({**context, "error": error})
|
|
||||||
|
|
||||||
if not code or not state:
|
|
||||||
return self.render_to_response(context)
|
|
||||||
|
|
||||||
cached_state = cache.get(f"{request.user.email}-reddit-auth")
|
|
||||||
|
|
||||||
if state != cached_state:
|
|
||||||
return self.render_to_response(
|
|
||||||
{
|
|
||||||
**context,
|
|
||||||
"error": "The saved state for Reddit authorization did not match",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
access_token, refresh_token = get_reddit_access_token(code, request.user)
|
|
||||||
|
|
||||||
return self.render_to_response(
|
|
||||||
{
|
|
||||||
**context,
|
|
||||||
"access_token": access_token,
|
|
||||||
"refresh_token": refresh_token,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
except StreamException as e:
|
|
||||||
return self.render_to_response({**context, "error": str(e)})
|
|
||||||
except KeyError:
|
|
||||||
return self.render_to_response(
|
|
||||||
{**context, "error": "Access and refresh token not found in response"}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class RedditTokenRedirectView(RedirectView):
|
|
||||||
url = reverse_lazy("accounts:settings")
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
response = super().get(request, *args, **kwargs)
|
|
||||||
|
|
||||||
user = request.user
|
|
||||||
task_active = cache.get(f"{user.email}-reddit-refresh")
|
|
||||||
|
|
||||||
if not task_active:
|
|
||||||
RedditTokenTask.delay(user.pk)
|
|
||||||
messages.success(request, _("Access token is being retrieved"))
|
|
||||||
cache.set(f"{user.email}-reddit-refresh", 1, 300)
|
|
||||||
return response
|
|
||||||
|
|
||||||
messages.error(request, _("Unable to retrieve token"))
|
|
||||||
return response
|
|
||||||
21
src/newsreader/accounts/views/__init__.py
Normal file
21
src/newsreader/accounts/views/__init__.py
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
from newsreader.accounts.views.auth import LoginView, LogoutView
|
||||||
|
from newsreader.accounts.views.integrations import (
|
||||||
|
RedditTemplateView,
|
||||||
|
RedditTokenRedirectView,
|
||||||
|
)
|
||||||
|
from newsreader.accounts.views.password import (
|
||||||
|
PasswordChangeView,
|
||||||
|
PasswordResetCompleteView,
|
||||||
|
PasswordResetConfirmView,
|
||||||
|
PasswordResetDoneView,
|
||||||
|
PasswordResetView,
|
||||||
|
)
|
||||||
|
from newsreader.accounts.views.registration import (
|
||||||
|
ActivationCompleteView,
|
||||||
|
ActivationResendView,
|
||||||
|
ActivationView,
|
||||||
|
RegistrationClosedView,
|
||||||
|
RegistrationCompleteView,
|
||||||
|
RegistrationView,
|
||||||
|
)
|
||||||
|
from newsreader.accounts.views.settings import SettingsView
|
||||||
11
src/newsreader/accounts/views/auth.py
Normal file
11
src/newsreader/accounts/views/auth.py
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
from django.contrib.auth import views as django_views
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
|
||||||
|
class LoginView(django_views.LoginView):
|
||||||
|
template_name = "accounts/views/login.html"
|
||||||
|
success_url = reverse_lazy("index")
|
||||||
|
|
||||||
|
|
||||||
|
class LogoutView(django_views.LogoutView):
|
||||||
|
next_page = reverse_lazy("accounts:login")
|
||||||
75
src/newsreader/accounts/views/integrations.py
Normal file
75
src/newsreader/accounts/views/integrations.py
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.core.cache import cache
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
from django.views.generic import RedirectView, TemplateView
|
||||||
|
|
||||||
|
from newsreader.news.collection.exceptions import StreamException
|
||||||
|
from newsreader.news.collection.reddit import (
|
||||||
|
get_reddit_access_token,
|
||||||
|
get_reddit_authorization_url,
|
||||||
|
)
|
||||||
|
from newsreader.news.collection.tasks import RedditTokenTask
|
||||||
|
|
||||||
|
|
||||||
|
class RedditTemplateView(TemplateView):
|
||||||
|
template_name = "accounts/views/reddit.html"
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
context = self.get_context_data(**kwargs)
|
||||||
|
|
||||||
|
error = request.GET.get("error", None)
|
||||||
|
state = request.GET.get("state", None)
|
||||||
|
code = request.GET.get("code", None)
|
||||||
|
|
||||||
|
if error:
|
||||||
|
return self.render_to_response({**context, "error": error})
|
||||||
|
|
||||||
|
if not code or not state:
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
cached_state = cache.get(f"{request.user.email}-reddit-auth")
|
||||||
|
|
||||||
|
if state != cached_state:
|
||||||
|
return self.render_to_response(
|
||||||
|
{
|
||||||
|
**context,
|
||||||
|
"error": "The saved state for Reddit authorization did not match",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
access_token, refresh_token = get_reddit_access_token(code, request.user)
|
||||||
|
|
||||||
|
return self.render_to_response(
|
||||||
|
{
|
||||||
|
**context,
|
||||||
|
"access_token": access_token,
|
||||||
|
"refresh_token": refresh_token,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except StreamException as e:
|
||||||
|
return self.render_to_response({**context, "error": str(e)})
|
||||||
|
except KeyError:
|
||||||
|
return self.render_to_response(
|
||||||
|
{**context, "error": "Access and refresh token not found in response"}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RedditTokenRedirectView(RedirectView):
|
||||||
|
url = reverse_lazy("accounts:settings")
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
response = super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
user = request.user
|
||||||
|
task_active = cache.get(f"{user.email}-reddit-refresh")
|
||||||
|
|
||||||
|
if not task_active:
|
||||||
|
RedditTokenTask.delay(user.pk)
|
||||||
|
messages.success(request, _("Access token is being retrieved"))
|
||||||
|
cache.set(f"{user.email}-reddit-refresh", 1, 300)
|
||||||
|
return response
|
||||||
|
|
||||||
|
messages.error(request, _("Unable to retrieve token"))
|
||||||
|
return response
|
||||||
37
src/newsreader/accounts/views/password.py
Normal file
37
src/newsreader/accounts/views/password.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
from django.contrib.auth import views as django_views
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
from newsreader.news.collection.reddit import (
|
||||||
|
get_reddit_access_token,
|
||||||
|
get_reddit_authorization_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# PasswordResetView sends the mail
|
||||||
|
# PasswordResetDoneView shows a success message for the above
|
||||||
|
# PasswordResetConfirmView checks the link the user clicked and
|
||||||
|
# prompts for a new password
|
||||||
|
# PasswordResetCompleteView shows a success message for the above
|
||||||
|
class PasswordResetView(django_views.PasswordResetView):
|
||||||
|
template_name = "password-reset/password-reset.html"
|
||||||
|
subject_template_name = "password-reset/password-reset-subject.txt"
|
||||||
|
email_template_name = "password-reset/password-reset-email.html"
|
||||||
|
success_url = reverse_lazy("accounts:password-reset-done")
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordResetDoneView(django_views.PasswordResetDoneView):
|
||||||
|
template_name = "password-reset/password-reset-done.html"
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordResetConfirmView(django_views.PasswordResetConfirmView):
|
||||||
|
template_name = "password-reset/password-reset-confirm.html"
|
||||||
|
success_url = reverse_lazy("accounts:password-reset-complete")
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordResetCompleteView(django_views.PasswordResetCompleteView):
|
||||||
|
template_name = "password-reset/password-reset-complete.html"
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordChangeView(django_views.PasswordChangeView):
|
||||||
|
template_name = "accounts/views/password-change.html"
|
||||||
|
success_url = reverse_lazy("accounts:settings")
|
||||||
59
src/newsreader/accounts/views/registration.py
Normal file
59
src/newsreader/accounts/views/registration.py
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
from registration.backends.default import views as registration_views
|
||||||
|
|
||||||
|
from newsreader.news.collection.reddit import (
|
||||||
|
get_reddit_access_token,
|
||||||
|
get_reddit_authorization_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# RegistrationView shows a registration form and sends the email
|
||||||
|
# RegistrationCompleteView shows after filling in the registration form
|
||||||
|
# ActivationView is send within the activation email and activates the account
|
||||||
|
# ActivationCompleteView shows the success screen when activation was succesful
|
||||||
|
# ActivationResendView can be used when activation links are expired
|
||||||
|
# RegistrationClosedView shows when registration is disabled
|
||||||
|
class RegistrationView(registration_views.RegistrationView):
|
||||||
|
disallowed_url = reverse_lazy("accounts:register-closed")
|
||||||
|
template_name = "registration/registration_form.html"
|
||||||
|
success_url = reverse_lazy("accounts:register-complete")
|
||||||
|
|
||||||
|
|
||||||
|
class RegistrationCompleteView(TemplateView):
|
||||||
|
template_name = "registration/registration_complete.html"
|
||||||
|
|
||||||
|
|
||||||
|
class RegistrationClosedView(TemplateView):
|
||||||
|
template_name = "registration/registration_closed.html"
|
||||||
|
|
||||||
|
|
||||||
|
# Redirects or renders failed activation template
|
||||||
|
class ActivationView(registration_views.ActivationView):
|
||||||
|
template_name = "registration/activation_failure.html"
|
||||||
|
|
||||||
|
def get_success_url(self, user):
|
||||||
|
return ("accounts:activate-complete", (), {})
|
||||||
|
|
||||||
|
|
||||||
|
class ActivationCompleteView(TemplateView):
|
||||||
|
template_name = "registration/activation_complete.html"
|
||||||
|
|
||||||
|
|
||||||
|
# Renders activation form resend or resend_activation_complete
|
||||||
|
class ActivationResendView(registration_views.ResendActivationView):
|
||||||
|
template_name = "registration/activation_resend_form.html"
|
||||||
|
|
||||||
|
def render_form_submitted_template(self, form):
|
||||||
|
"""
|
||||||
|
Renders resend activation complete template with the submitted email.
|
||||||
|
|
||||||
|
"""
|
||||||
|
email = form.cleaned_data["email"]
|
||||||
|
context = {"email": email}
|
||||||
|
|
||||||
|
return render(
|
||||||
|
self.request, "registration/activation_resend_complete.html", context
|
||||||
|
)
|
||||||
50
src/newsreader/accounts/views/settings.py
Normal file
50
src/newsreader/accounts/views/settings.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
from django.core.cache import cache
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
from django.views.generic.edit import FormView, ModelFormMixin
|
||||||
|
|
||||||
|
from newsreader.accounts.forms import UserSettingsForm
|
||||||
|
from newsreader.accounts.models import User
|
||||||
|
from newsreader.news.collection.reddit import (
|
||||||
|
get_reddit_access_token,
|
||||||
|
get_reddit_authorization_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsView(ModelFormMixin, FormView):
|
||||||
|
template_name = "accounts/views/settings.html"
|
||||||
|
success_url = reverse_lazy("accounts:settings")
|
||||||
|
form_class = UserSettingsForm
|
||||||
|
model = User
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_object(self, **kwargs):
|
||||||
|
return self.request.user
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
user = self.request.user
|
||||||
|
|
||||||
|
reddit_authorization_url = None
|
||||||
|
reddit_refresh_url = None
|
||||||
|
reddit_task_active = cache.get(f"{user.email}-reddit-refresh")
|
||||||
|
|
||||||
|
if (
|
||||||
|
user.reddit_refresh_token
|
||||||
|
and not user.reddit_access_token
|
||||||
|
and not reddit_task_active
|
||||||
|
):
|
||||||
|
reddit_refresh_url = reverse_lazy("accounts:reddit-refresh")
|
||||||
|
|
||||||
|
if not user.reddit_refresh_token:
|
||||||
|
reddit_authorization_url = get_reddit_authorization_url(user)
|
||||||
|
|
||||||
|
return {
|
||||||
|
**super().get_context_data(**kwargs),
|
||||||
|
"reddit_authorization_url": reddit_authorization_url,
|
||||||
|
"reddit_refresh_url": reddit_refresh_url,
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
return {**super().get_form_kwargs(), "instance": self.request.user}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue