Misc updates

This commit is contained in:
= 2019-09-04 21:08:57 -05:00
parent 25ef7b5675
commit f000e564f9
Signed by: kiichan
GPG key ID: 619DFD67F0976616
10 changed files with 183 additions and 27 deletions

View file

@ -1,3 +1,13 @@
Wed, 04 Sep 2019 21:08:57 -0500
Keaton <kii-chan@tutanota.com>
Misc updates
- Fleshed out the readme
- Changed variable name to be more sensical
- Altered how `next` redirection works so it's a little more robust
--------------------
Mon, 02 Sep 2019 09:42:24 -0500 Mon, 02 Sep 2019 09:42:24 -0500
Keaton <kii-chan@tutanota.com> Keaton <kii-chan@tutanota.com>
Fixing functionality Fixing functionality

BIN
docs/example_dropin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

139
readme.md
View file

@ -1,9 +1,144 @@
# SQRL for Django # SQRL for Django
This package allows for developers to easily create SQRL-aware websites with a
few simple steps.
**(This document was written for the future. Things that are not yet implemented
will be ~~struck out~~. Non-functional code snippets will be `#commented out`)**
This is a reboot of [Miki725's django-sqrl](https://github.com/miki725/django-sqrl), This is a reboot of [Miki725's django-sqrl](https://github.com/miki725/django-sqrl),
updated for Python 3.7 and Django 2.2. The vast majority of the code is unchanged, updated for Python 3.7 and Django 2.2. The vast majority of the code is unchanged,
so all credit for this working belongs with them. so all credit for this working belongs with them.
## Installation (eventually) * Free software: MIT license
* GitHub: https://gitlab.com/WolfgangAxel/django-sqrl-2
* ~~Documentation: https://django-sqrl-2.readthedocs.org~~
* What is SQRL?: https://sqrl.grc.com/pages/what_is_sqrl/
* SQRL documentation: https://www.grc.com/sqrl/sqrl.htm
It still isn't complete. This is placeholder. ## Installing
### SQRL Package
First step is to install `django-sqrl-2` which is easies to do using pip:
$ python3 -m pip install #django-sqrl-2
### Django settings
Once installed there are a few required changes in Django settings:
* Make sure that some required Django apps are used:
INSTALLED_APPS = [
...,
'sqrl',
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.staticfiles',
]
* Make sure that some required Django middleware are used:
MIDDLEWARE_CLASSES = [
...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
]
* Change `AUTHENTICATION_BACKENDS` to use SQRL backend vs Django's
`ModelBackend` (default):
AUTHENTICATION_BACKENDS = [
'sqrl.backends.SQRLModelBackend',
]
* If you are using Django admin, following are required:
* Make sure that `sqrl` is listed before `admin` in the `INSTALLED_APPS`.
This allows Django to prioritize `sqrl` templates since `django-sqrl`
overwrites some of them.
INSTALLED_APPS = [
...,
'sqrl',
'django.contrib.admin',
...
]
* Make sure to add a custom template directory in settings. `django-sqrl`
extends Django admin's `base.html` which by default causes infinite recursion.
To solve that, simply add a custom template directory which allows `django-sqrl`
to explicitly extend from `django.contrib.admin` `base.html` template:
import os
import django
TEMPLATE_DIRS = [
os.path.dirname(django.__file__),
]
## URLs
All of SQRL functionality is enabled by adding its URLs to the root URL config:
from django.urls import path, include
urlpatterns = [
...
path('sqrl/', include('sqrl.urls', namespace="sqrl")),
...
]
If you use Django admin, the `/admin/sqrl_manage` will be available to manage
your site's SQRL identities.
## Templates
Now that SQRL is installed in your Django project, you can use it on any login
page with three simple template tag:
{% load sqrl %}
{% sqrl as sqrl_session %}
{% sqrl_login_dropin sqrl_session [[a named redirect]] %}
The [[named redirect]] is the page that should be redirected to after logging
in. Any name that can be resolved by django's `reverse` function will work (i.e.
`path("scheme/", view, name="example")` in the app `app` with namespace "app"
could be selected as `app:example`).
These three tags will add a simple element to your login page:
![A very basic SQRL QR code](docs/example_dropin.png "example dropin")
If that doesn't suit your fancy, you may build your own template from the
following essential tags:
{% load sqrl %}
{% sqrl as sqrl_session %}
<a href="{{ sqrl_session.sqrl_url }}">
<div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
</a>
<script>SQRL_NEXT="{{ your desired redirect }}"; SQRL_CHECK_URL="{% sqrl_status_url_script_tag sqrl_session %}"</script>
<script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script>
## Management Command
SQRL uses server state to keep track of open SQRL transactions in order to
mitigate replay attacks. Since this state will constantly grow if not cleared,
`django-sqrl` provides a helper management command to clear expired states:
$ python3 manage.py clearsqrlnuts
It is recommended to run this command as repeating task. Here is an example
configuration for `cron`:
*/5 * * * * python manage.py clearsqrlnuts >/dev/null 2>&1
## ~~Testing~~
~~To run the tests, you need to install the testing requirements first:~~
$ #make install
~~Then to run the tests, you can use use the Makefile command:~~
$ #make test

View file

@ -1,5 +1,16 @@
(function() { (function() {
var get_next_url = function() { var get_next_url = function() {
// A Next defined in the URL has priority
var urlparam = document.URL.match(/next=([^&#]+)/)
if (urlparam.length == 2) {
return urlparam[1]
}
// Next highest priority is a defined SQRL_NEXT
if (typeof SQRL_NEXT !== "undefined") {
return SQRL_NEXT
}
// Lowest priority is the first input element
// named "next", otherwise return null
var input = document.querySelectorAll('input[name="next"]'); var input = document.querySelectorAll('input[name="next"]');
return input.length > 0 ? input[0].value : null; return input.length > 0 ? input[0].value : null;
}, },

View file

@ -60,13 +60,13 @@
</p> </p>
{% endif %} {% endif %}
{% sqrl as session_sqrl %} {% sqrl as sqrl_session %}
<fieldset class="module aligned"> <fieldset class="module aligned">
<div class="sqrl-wrap"> <div class="sqrl-wrap">
SQRL Login SQRL Login
<a href="{{ session_sqrl.sqrl_url }}"> <a href="{{ sqrl_session.sqrl_url }}">
<div id="sqrl-qr" data-sqrl="{{ session_sqrl.sqrl_url }}"></div> <div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
</a> </a>
<a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a> <a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a>
{# redirect to manage page after successful SQRL transaction #} {# redirect to manage page after successful SQRL transaction #}
@ -74,9 +74,9 @@
</div> </div>
</fieldset> </fieldset>
<form method="get" action="{{ session_sqrl.sqrl_url }}" class="sqrl"> <form method="get" action="{{ sqrl_session.sqrl_url }}" class="sqrl">
<div class="submit-row"> <div class="submit-row">
<input type="hidden" name="nut" value="{{ session_sqrl.nut.nonce }}"> <input type="hidden" name="nut" value="{{ sqrl_session.nut.nonce }}">
<input type="submit" value="Manage SQRL" class="default" style="float: left;"> <input type="submit" value="Manage SQRL" class="default" style="float: left;">
</div> </div>
</form> </form>

View file

@ -57,9 +57,9 @@
</div> </div>
</form> </form>
{% sqrl as session_sqrl %} {% sqrl as sqrl_session %}
<form method="get" action="{{ session_sqrl.sqrl_url }}" class="sqrl"> <form method="get" action="{{ sqrl_session.sqrl_url }}" class="sqrl">
<p class="align-center or"> <p class="align-center or">
<span class="line-center">or</span> <span class="line-center">or</span>
</p> </p>
@ -69,21 +69,21 @@
<div class="sqrl-wrap"> <div class="sqrl-wrap">
SQRL Login SQRL Login
<a href="{{ session_sqrl.sqrl_url }}"> <a href="{{ sqrl_session.sqrl_url }}">
<div id="sqrl-qr" data-sqrl="{{ session_sqrl.sqrl_url }}"></div> <div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
</a> </a>
<a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a> <a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a>
</div> </div>
<div class="submit-row"> <div class="submit-row">
<input type="hidden" name="nut" value="{{ session_sqrl.nut.nonce }}"> <input type="hidden" name="nut" value="{{ sqrl_session.nut.nonce }}">
<input type="submit" value="{% trans 'Log in using SQRL' %}"/> <input type="submit" value="{% trans 'Log in using SQRL' %}"/>
</div> </div>
</div> </div>
</form> </form>
<script type="text/javascript"> <script type="text/javascript">
SQRL_CHECK_URL="{% sqrl_status_url_script_tag session_sqrl %}" SQRL_CHECK_URL="{% sqrl_status_url_script_tag sqrl_session %}"
document.getElementById('id_username').focus() document.getElementById('id_username').focus()
</script> </script>
<script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script> <script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script>

View file

@ -11,8 +11,8 @@
Please use via SQRL using the information below. Please use via SQRL using the information below.
</p> </p>
{% sqrl as session_sqrl %} {% sqrl as sqrl_session %}
{% sqrl_login_dropin session_sqrl login %} {% sqrl_login_dropin sqrl_session login %}
{% endblock %} {% endblock %}
{% comment %} {% comment %}

View file

@ -32,8 +32,8 @@
</p> </p>
{% endif %} {% endif %}
{% sqrl as session_sqrl %} {% sqrl as sqrl_session %}
{% sqrl_login_dropin session_sqrl method="manage" %} {% sqrl_login_dropin sqrl_session method="manage" %}
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}

View file

@ -18,19 +18,19 @@
} }
</style> </style>
<div> <div>
<form method="get" action="{{ session_sqrl.sqrl_url }}"> <form method="get" action="{{ sqrl_session.sqrl_url }}">
<div class="sqrl-wrap"> <div class="sqrl-wrap">
SQRL Login SQRL Login
<a href="{{ session_sqrl.sqrl_url }}"> <a href="{{ sqrl_session.sqrl_url }}">
<div id="sqrl-qr" data-sqrl="{{ session_sqrl.sqrl_url }}"></div> <div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
</a> </a>
<a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a> <a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a>
</div> </div>
<input type="hidden" name="nut" value="{{ session_sqrl.nut.nonce }}"> <input type="hidden" name="nut" value="{{ sqrl_session.nut.nonce }}">
<input type="hidden" name="next" value="{{ redir }}"> <input type="hidden" name="next" value="{{ redir }}">
<input type="submit" value="Authenticate using SQRL"> <input type="submit" value="Authenticate using SQRL">
</form> </form>
</div> </div>
<script>SQRL_CHECK_URL="{% sqrl_status_url_script_tag session_sqrl %}"</script> <script>SQRL_NEXT="{{ redir }}"; SQRL_CHECK_URL="{% sqrl_status_url_script_tag sqrl_session %}"</script>
<script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script> <script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script>

View file

@ -15,25 +15,25 @@ def sqrl(context):
@register.inclusion_tag('sqrl/sqrl-dropin.html') @register.inclusion_tag('sqrl/sqrl-dropin.html')
def sqrl_login_dropin(session_sqrl, redir): def sqrl_login_dropin(sqrl_session, redir=""):
""" """
Creates a drop-in SQRL element in your template pages. Creates a drop-in SQRL element in your template pages.
Add it to your login template to make it SQRL-aware. Add it to your login template to make it SQRL-aware.
Usage: Usage:
{% load sqrl %} {% load sqrl %}
{% sqrl as session_sqrl %} {% sqrl as sqrl_session %}
{% sqrl_login_dropin session_sqrl REDIR %} {% sqrl_login_dropin sqrl_session REDIR %}
REDIR is the registered name of the page to move to once the login REDIR is the registered name of the page to move to once the login
is completed. is completed. It can be blank to not define a redirection.
Notes: Notes:
The drop-in is defaulted to a max-width of 300px. Set the width 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 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. likely want to change the font-size as well in this case.
""" """
return {'session_sqrl':session_sqrl, 'redir': reverse(redir)} return {'sqrl_session':sqrl_session, 'redir': reverse(redir)}
@register.simple_tag @register.simple_tag