mirror of https://github.com/snachodog/mybuddy.git
Add login QR-code to settings-page
This commit is contained in:
parent
3ae5aa378e
commit
d5bbbd4ee4
1
Pipfile
1
Pipfile
|
@ -23,6 +23,7 @@ pyyaml = "*"
|
||||||
uritemplate = "*"
|
uritemplate = "*"
|
||||||
whitenoise = "*"
|
whitenoise = "*"
|
||||||
django-taggit = "*"
|
django-taggit = "*"
|
||||||
|
qrcode = "*"
|
||||||
|
|
||||||
[dev-packages]
|
[dev-packages]
|
||||||
coveralls = "*"
|
coveralls = "*"
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import pytz
|
import pytz
|
||||||
|
import json
|
||||||
|
import io
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
@ -12,6 +14,8 @@ from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
|
import qrcode
|
||||||
|
|
||||||
|
|
||||||
class Settings(models.Model):
|
class Settings(models.Model):
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
|
@ -82,6 +86,22 @@ class Settings(models.Model):
|
||||||
Token.objects.get(user=self.user).delete()
|
Token.objects.get(user=self.user).delete()
|
||||||
return Token.objects.get_or_create(user=self.user)[0]
|
return Token.objects.get_or_create(user=self.user)[0]
|
||||||
|
|
||||||
|
def generate_login_qr_code_png(self, page_root: str) -> bytes:
|
||||||
|
json_data = {
|
||||||
|
"url": page_root,
|
||||||
|
"api_key": str(self.api_key()),
|
||||||
|
}
|
||||||
|
qr_code_data = r"BABYBUDDY-LOGIN:" + json.dumps(json_data)
|
||||||
|
|
||||||
|
qr = qrcode.QRCode(border=1, box_size=5)
|
||||||
|
qr.add_data(qr_code_data)
|
||||||
|
qr.make(fit=True)
|
||||||
|
image = qr.make_image()
|
||||||
|
|
||||||
|
bytesio = io.BytesIO()
|
||||||
|
image.save(bytesio, format="png")
|
||||||
|
return bytesio.getbuffer()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dashboard_refresh_rate_milliseconds(self):
|
def dashboard_refresh_rate_milliseconds(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -78,12 +78,18 @@
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "API" %}</legend>
|
<legend>{% trans "API" %}</legend>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="id_email" class="col-sm-2 col-form-label">{% trans "Key" %}</label>
|
<label class="col-sm-2 col-form-label">{% trans "Key" %}</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<samp>{{ user.settings.api_key }}</samp>
|
<samp>{{ user.settings.api_key }}</samp>
|
||||||
<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">
|
||||||
|
<img src="data:image/png;base64,{{ login_qr_code_png }}">
|
||||||
|
</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">
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
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
|
||||||
|
@ -158,14 +162,22 @@ class UserSettings(LoginRequiredMixin, View):
|
||||||
template_name = "babybuddy/user_settings_form.html"
|
template_name = "babybuddy/user_settings_form.html"
|
||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
settings = request.user.settings
|
||||||
|
|
||||||
|
page_root = request.build_absolute_uri(reverse("babybuddy:root-router"))
|
||||||
|
base64_png = base64.b64encode(
|
||||||
|
settings.generate_login_qr_code_png(page_root)
|
||||||
|
)
|
||||||
|
|
||||||
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(
|
"form_settings": self.form_settings_class(
|
||||||
instance=request.user.settings
|
instance=settings
|
||||||
),
|
),
|
||||||
|
"login_qr_code_png": base64_png.decode(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ python-dateutil==2.8.2
|
||||||
python-dotenv==0.20.0
|
python-dotenv==0.20.0
|
||||||
pytz==2022.1
|
pytz==2022.1
|
||||||
pyyaml==6.0
|
pyyaml==6.0
|
||||||
|
qrcode==7.3.1
|
||||||
s3transfer==0.6.0
|
s3transfer==0.6.0
|
||||||
setuptools==63.1.0
|
setuptools==63.1.0
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
|
|
Loading…
Reference in New Issue