Add new "Add a device" view, remove QR-code from settings-view

This commit is contained in:
Paul Konstantin Gerke 2022-10-17 09:40:06 +02:00
parent 5e2b847ed8
commit 0f4c006c05
5 changed files with 85 additions and 18 deletions

View File

@ -323,6 +323,7 @@
<h6 class="dropdown-header">{% trans "User" %}</h6> <h6 class="dropdown-header">{% trans "User" %}</h6>
<a href="{% url 'babybuddy:user-settings' %}" class="dropdown-item">{% trans "Settings" %}</a> <a href="{% url 'babybuddy:user-settings' %}" class="dropdown-item">{% trans "Settings" %}</a>
<a href="{% url 'babybuddy:user-password' %}" class="dropdown-item">{% trans "Password" %}</a> <a href="{% url 'babybuddy:user-password' %}" class="dropdown-item">{% trans "Password" %}</a>
<a href="{% url 'babybuddy:user-add-device' %}" class="dropdown-item">{% trans "Add a device" %}</a>
<form action="{% url 'babybuddy:logout' %}" role="form" method="post"> <form action="{% url 'babybuddy:logout' %}" role="form" method="post">
{% csrf_token %} {% csrf_token %}
<button class="dropdown-item"> <button class="dropdown-item">

View File

@ -0,0 +1,44 @@
{% extends 'babybuddy/page.html' %}
{% load i18n widget_tweaks babybuddy_tags qr_code %}
{% block title %}{% trans "Add a device" %}{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item">{% trans "User" %}</li>
<li class="breadcrumb-item active">{% trans "Settings" %}</li>
{% endblock %}
{% block content %}
<h1>{% trans "Add a device" %}</h1>
<p>
{% blocktrans trimmed %}
This page allows you to gain access to babybuddy from a
third party app or device.
{% endblocktrans %}
</p>
<div class="container-fluid">
<fieldset>
<legend>{% trans "Device login options" %}</legend>
<div class="form-group row">
<label class="col-sm-2 col-form-label">{% trans "Key" %}</label>
<div class="col-sm-10">
<form method="post">
{% csrf_token %}
<samp>{{ user.settings.api_key }}</samp>
<input type="submit" name="api_key_regenerate" value="{% trans "Regenerate" %}" class="btn btn-danger btn-xs" />
</form>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">{% trans "Login QR code" %}</label>
<div class="col-sm-10">
<div style="display:inline-block;background-color:white;" data-qr-code-content="{{ qr_code_data }}">
{% qr_from_text qr_code_data size="s" %}
</div>
</div>
</div>
</fieldset>
</div>
{% endblock %}

View File

@ -84,14 +84,6 @@
<input type="submit" name="api_key_regenerate" value="{% trans "Regenerate" %}" class="btn btn-danger btn-xs" /> <input type="submit" name="api_key_regenerate" value="{% trans "Regenerate" %}" class="btn btn-danger btn-xs" />
</div> </div>
</div> </div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">{% trans "Login QR code" %}</label>
<div class="col-sm-10">
<div style="display:inline-block;background-color:white;" data-qr-code-content="{{ qr_code_data }}">
{% qr_from_text qr_code_data size="s" %}
</div>
</div>
</div>
</fieldset> </fieldset>
<input type="hidden" name="next" value="{% url 'babybuddy:user-settings' %}" /> <input type="hidden" name="next" value="{% url 'babybuddy:user-settings' %}" />
<input type="submit" name="save_settings" value="{% trans "Submit" %}" class="btn btn-primary"> <input type="submit" name="save_settings" value="{% trans "Submit" %}" class="btn btn-primary">

View File

@ -42,6 +42,7 @@ app_patterns = [
path("users/<int:pk>/delete/", views.UserDelete.as_view(), name="user-delete"), path("users/<int:pk>/delete/", views.UserDelete.as_view(), name="user-delete"),
path("user/password/", views.UserPassword.as_view(), name="user-password"), path("user/password/", views.UserPassword.as_view(), name="user-password"),
path("user/settings/", views.UserSettings.as_view(), name="user-settings"), path("user/settings/", views.UserSettings.as_view(), name="user-settings"),
path("user/add-device/", views.UserAddDevice.as_view(), name="user-add-device"),
] ]
urlpatterns = [ urlpatterns = [

View File

@ -1,10 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from xmlrpc.client import Boolean
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import update_session_auth_hash from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.views import LogoutView as LogoutViewBase from django.contrib.auth.views import LogoutView as LogoutViewBase
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import BadRequest
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.middleware.csrf import REASON_BAD_ORIGIN from django.middleware.csrf import REASON_BAD_ORIGIN
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
@ -147,7 +149,16 @@ class UserPassword(LoginRequiredMixin, View):
return render(request, self.template_name, {"form": form}) return render(request, self.template_name, {"form": form})
class UserSettings(LoginRequiredMixin, View): class RegenerateApiKey:
def handle_api_key_post(self, request) -> Boolean:
if request.POST.get("api_key_regenerate"):
request.user.settings.api_key(reset=True)
messages.success(request, _("User API key regenerated."))
return True
return False
class UserSettings(LoginRequiredMixin, RegenerateApiKey, View):
""" """
Handles both the User and Settings models. Handles both the User and Settings models.
Based on this SO answer: https://stackoverflow.com/a/45056835. Based on this SO answer: https://stackoverflow.com/a/45056835.
@ -156,28 +167,21 @@ class UserSettings(LoginRequiredMixin, View):
form_user_class = forms.UserForm form_user_class = forms.UserForm
form_settings_class = forms.UserSettingsForm form_settings_class = forms.UserSettingsForm
template_name = "babybuddy/user_settings_form.html" template_name = "babybuddy/user_settings_form.html"
qr_code_template = "babybuddy/login_qr_code.txt"
def get(self, request): def get(self, request):
settings = request.user.settings settings = request.user.settings
qr_code_response = render(request, self.qr_code_template)
qr_code_data = qr_code_response.content.decode().strip()
return render( return render(
request, request,
self.template_name, self.template_name,
{ {
"form_user": self.form_user_class(instance=request.user), "form_user": self.form_user_class(instance=request.user),
"form_settings": self.form_settings_class(instance=settings), "form_settings": self.form_settings_class(instance=settings),
"qr_code_data": qr_code_data,
}, },
) )
def post(self, request): def post(self, request):
if request.POST.get("api_key_regenerate"): if self.handle_api_key_post(request):
request.user.settings.api_key(reset=True)
messages.success(request, _("User API key regenerated."))
return redirect("babybuddy:user-settings") return redirect("babybuddy:user-settings")
form_user = self.form_user_class(instance=request.user, data=request.POST) form_user = self.form_user_class(instance=request.user, data=request.POST)
@ -200,6 +204,31 @@ class UserSettings(LoginRequiredMixin, View):
) )
class UserAddDevice(LoginRequiredMixin, RegenerateApiKey, View):
form_user_class = forms.UserForm
template_name = "babybuddy/user_add_device.html"
qr_code_template = "babybuddy/login_qr_code.txt"
def get(self, request):
qr_code_response = render(request, self.qr_code_template)
qr_code_data = qr_code_response.content.decode().strip()
return render(
request,
self.template_name,
{
"form_user": self.form_user_class(instance=request.user),
"qr_code_data": qr_code_data,
},
)
def post(self, request):
if self.handle_api_key_post(request):
return redirect("babybuddy:user-settings")
else:
raise BadRequest()
class Welcome(LoginRequiredMixin, TemplateView): class Welcome(LoginRequiredMixin, TemplateView):
""" """
Basic introduction to Baby Buddy (meant to be shown when no data is in the Basic introduction to Baby Buddy (meant to be shown when no data is in the