Fixing functionality
This commit is contained in:
parent
edb16382f3
commit
25ef7b5675
14 changed files with 76 additions and 27 deletions
16
CHANGELOG
16
CHANGELOG
|
@ -1,3 +1,19 @@
|
|||
Mon, 02 Sep 2019 09:42:24 -0500
|
||||
Keaton <kii-chan@tutanota.com>
|
||||
Fixing functionality
|
||||
|
||||
A bare-bones test server was set up and account creation and authentication was
|
||||
achieved through SQRL. Old documentation needs to be updated, and new
|
||||
documentation needs to be written (mostly for using the drop-in login).
|
||||
|
||||
At this point, the SQRL authentication protocol for Django is functional!
|
||||
|
||||
Further work needs to be done to test drop-in support for already-running sites.
|
||||
If possible, that would be the ideal end goal; making it as easy as possible to
|
||||
propagate SQRL through the internet.
|
||||
|
||||
--------------------
|
||||
|
||||
Mon, 02 Sep 2019 04:56:45 -0500
|
||||
Keaton <kii-chan@tutanota.com>
|
||||
Completing functional conversions
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
Django
|
||||
django-braces
|
||||
ed25519
|
||||
|
|
|
@ -1,3 +1,30 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
from .models import SQRLIdentity, SQRLNut
|
||||
|
||||
|
||||
class SQRLIdentityAdmin(admin.ModelAdmin):
|
||||
model = SQRLIdentity
|
||||
list_display = (
|
||||
'user',
|
||||
'is_enabled',
|
||||
'is_only_sqrl',
|
||||
)
|
||||
raw_id_fields = (
|
||||
'user',
|
||||
)
|
||||
|
||||
|
||||
class SQRLNutAdmin(admin.ModelAdmin):
|
||||
model = SQRLNut
|
||||
list_display = (
|
||||
'nonce',
|
||||
'is_transaction_complete',
|
||||
'ip_address',
|
||||
)
|
||||
|
||||
|
||||
admin.site.register(SQRLNut, SQRLNutAdmin)
|
||||
admin.site.register(SQRLIdentity, SQRLIdentityAdmin)
|
||||
|
|
|
@ -190,6 +190,10 @@ class RequestForm(forms.Form):
|
|||
pidk = self.cleaned_data['client'].get('pidk')
|
||||
pids = self.cleaned_data.get('pids')
|
||||
|
||||
if not any((pids, pidk)):
|
||||
# There are no previous ID key/secrets, which shouldn't break the validation.
|
||||
return pids
|
||||
|
||||
if not all((pids, pidk)):
|
||||
raise forms.ValidationError(
|
||||
'Cannot validate previous ID signature without server knowing pid public and secret keys.'
|
||||
|
|
|
@ -45,11 +45,11 @@ class SQRLHttpResponse(HttpResponse):
|
|||
for k, v in normalized_data.items():
|
||||
self['X-SQRL-{}'.format(k)] = v
|
||||
|
||||
log.debug('Response encoded data:\n{}'
|
||||
log.error('Response encoded data:\n{}'
|
||||
''.format(content))
|
||||
log.debug('Response data:\n{}'
|
||||
log.error('Response data:\n{}'
|
||||
''.format(pformat(normalized_data)))
|
||||
log.debug('Response TIF breakdown:\n{}'
|
||||
log.error('Response TIF breakdown:\n{}'
|
||||
''.format(pformat(TIF(int(data['tif'], 16)).breakdown())))
|
||||
|
||||
def sign_response(self, nut, data):
|
||||
|
|
|
@ -139,7 +139,7 @@ class SQRLInitialization(object):
|
|||
"""
|
||||
return (
|
||||
'{scheme}://{host}{url}'
|
||||
''.format(scheme='sqrl', if self.request.is_secure() else 'qrl',
|
||||
''.format(scheme='sqrl' if self.request.is_secure() else 'qrl',
|
||||
host=self.request.get_host(),
|
||||
url=self.url)
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
return input.length > 0 ? input[0].value : null;
|
||||
},
|
||||
current_url = window.location.href,
|
||||
sqrl_frequency = 1500,
|
||||
sqrl_frequency = 2500,
|
||||
sqrl_call = function() {
|
||||
setTimeout(sqrl_handler, sqrl_frequency);
|
||||
},
|
||||
|
@ -29,6 +29,7 @@
|
|||
var data = JSON.parse(this.responseText);
|
||||
if (data.transaction_complete === true) {
|
||||
if (data.redirect_to !== undefined) {
|
||||
console.log(data.redirect_to);
|
||||
window.location.href = data.redirect_to;
|
||||
} else {
|
||||
console.error('Server indicated that SQRL transaction is complete ' +
|
||||
|
@ -44,6 +45,7 @@
|
|||
try {
|
||||
request.send(null);
|
||||
} catch (exception) {
|
||||
console.log("stopping requests due to error??");
|
||||
// do not send anymore requests if error occurred
|
||||
}
|
||||
};
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
{% if user.has_usable_password %}
|
||||
<a href="{% url 'admin:password_change' %}">{% trans 'Change password' %}</a> /
|
||||
{% endif %}
|
||||
<a href="{% url 'admin-sqrl_manage' %}">{% trans 'Manage SQRL' %}</a> /
|
||||
<a href="{% url 'sqrl:admin-sqrl_manage' %}">{% trans 'Manage SQRL' %}</a> /
|
||||
<a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</p>
|
||||
|
||||
{% sqrl as session_sqrl %}
|
||||
{% sqrl_login_dropin session_sqrl %}
|
||||
{% sqrl_login_dropin session_sqrl login %}
|
||||
{% endblock %}
|
||||
|
||||
{% comment %}
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
|
||||
<p>
|
||||
Already have account?
|
||||
Login <a href="{% url 'login' %}">here</a> to associate
|
||||
SQRL identity with existing account.
|
||||
Login <a href="{% url 'sqrl:login' %}">here</a> to associate
|
||||
SQRL identity with an existing account.
|
||||
</p>
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit">
|
||||
</form>
|
||||
|
|
|
@ -28,13 +28,8 @@
|
|||
</div>
|
||||
|
||||
<input type="hidden" name="nut" value="{{ session_sqrl.nut.nonce }}">
|
||||
{% if session_sqrl.method == "manage" %}
|
||||
{# redirect to manage page after successful SQRL transaction #}
|
||||
<input type="hidden" name="next" value="{% url 'sqrl:manage' %}">
|
||||
<input type="submit" value="Manage SQRL">
|
||||
{% else %}
|
||||
<input type="submit" value="Log in using SQRL">
|
||||
{% endif %}
|
||||
<input type="hidden" name="next" value="{{ redir }}">
|
||||
<input type="submit" value="Authenticate using SQRL">
|
||||
</form>
|
||||
</div>
|
||||
<script>SQRL_CHECK_URL="{% sqrl_status_url_script_tag session_sqrl %}"</script>
|
||||
|
|
|
@ -7,7 +7,6 @@ from ..sqrl import SQRLInitialization
|
|||
|
||||
|
||||
register = template.Library()
|
||||
print(register)
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
|
@ -16,7 +15,7 @@ def sqrl(context):
|
|||
|
||||
|
||||
@register.inclusion_tag('sqrl/sqrl-dropin.html')
|
||||
def sqrl_login_dropin(session_sqrl, method="login"):
|
||||
def sqrl_login_dropin(session_sqrl, redir):
|
||||
"""
|
||||
Creates a drop-in SQRL element in your template pages.
|
||||
Add it to your login template to make it SQRL-aware.
|
||||
|
@ -24,19 +23,17 @@ def sqrl_login_dropin(session_sqrl, method="login"):
|
|||
Usage:
|
||||
{% load sqrl %}
|
||||
{% sqrl as session_sqrl %}
|
||||
{% sqrl_login_dropin session_sqrl [method=METHOD] %}
|
||||
{% sqrl_login_dropin session_sqrl REDIR %}
|
||||
|
||||
METHOD is an optional argument that changes the way the form
|
||||
behaves. Possible arguments are:
|
||||
- login: The default method. No special redirections occur
|
||||
- manage: Will redirect the user to sqrl/manage
|
||||
REDIR is the registered name of the page to move to once the login
|
||||
is completed.
|
||||
|
||||
Notes:
|
||||
The drop-in is defaulted to a max-width of 300px. Set the width
|
||||
property of the parent if you want or need it smaller. You will
|
||||
likely want to change the font-size as well in this case.
|
||||
"""
|
||||
return {'session_sqrl':session_sqrl, 'method': method}
|
||||
return {'session_sqrl':session_sqrl, 'redir': reverse(redir)}
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
|
|
|
@ -7,6 +7,7 @@ from .views import (
|
|||
SQRLIdentityManagementView,
|
||||
SQRLLoginView,
|
||||
SQRLStatusView,
|
||||
AdminSiteSQRLIdentityManagementView
|
||||
)
|
||||
|
||||
app_name = "sqrl"
|
||||
|
@ -17,4 +18,5 @@ urlpatterns = [
|
|||
path("manage/", SQRLIdentityManagementView.as_view(), name='manage'),
|
||||
path("register/",SQRLCompleteRegistrationView.as_view(), name='complete-registration'),
|
||||
re_path(r"^status/(?P<transaction>[A-Za-z0-9_-]{43})/$", SQRLStatusView.as_view(), name='status'),
|
||||
path('admin/sqrl_manage/', AdminSiteSQRLIdentityManagementView.as_view(), name='admin-sqrl_manage'),
|
||||
]
|
||||
|
|
|
@ -17,6 +17,8 @@ from django.urls import reverse
|
|||
from django.http import Http404, HttpResponse, JsonResponse, QueryDict
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.views.generic import FormView, TemplateView, View
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from .backends import SQRL_MODEL_BACKEND
|
||||
from .exceptions import TIF, TIFException
|
||||
|
@ -51,7 +53,7 @@ class SQRLLoginView(TemplateView):
|
|||
"""
|
||||
template_name = 'sqrl/login.html'
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt,"dispatch")
|
||||
class SQRLStatusView(View):
|
||||
"""
|
||||
Ajax view which returns the status of the SQRL transaction back to the user.
|
||||
|
@ -96,7 +98,7 @@ class SQRLStatusView(View):
|
|||
else:
|
||||
url = self.success_url
|
||||
|
||||
if all([not self.request.user.is_authenticated(),
|
||||
if all([not self.request.user.is_authenticated,
|
||||
SQRL_IDENTITY_SESSION_KEY in self.request.session]):
|
||||
return reverse('sqrl:complete-registration') + '?next={}'.format(url)
|
||||
else:
|
||||
|
@ -140,6 +142,7 @@ class SQRLStatusView(View):
|
|||
return JsonResponse(data)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt,"dispatch")
|
||||
class SQRLAuthView(View):
|
||||
"""
|
||||
This is the main view responsible for all interactions with SQRL client.
|
||||
|
|
Loading…
Reference in a new issue