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