Misc updates
This commit is contained in:
parent
25ef7b5675
commit
f000e564f9
10 changed files with 183 additions and 27 deletions
10
CHANGELOG
10
CHANGELOG
|
@ -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
|
||||
Keaton <kii-chan@tutanota.com>
|
||||
Fixing functionality
|
||||
|
|
BIN
docs/example_dropin.png
Normal file
BIN
docs/example_dropin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
139
readme.md
139
readme.md
|
@ -1,9 +1,144 @@
|
|||
# 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),
|
||||
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.
|
||||
|
||||
## 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
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
(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"]');
|
||||
return input.length > 0 ? input[0].value : null;
|
||||
},
|
||||
|
|
|
@ -60,13 +60,13 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% sqrl as session_sqrl %}
|
||||
{% sqrl as sqrl_session %}
|
||||
|
||||
<fieldset class="module aligned">
|
||||
<div class="sqrl-wrap">
|
||||
SQRL Login
|
||||
<a href="{{ session_sqrl.sqrl_url }}">
|
||||
<div id="sqrl-qr" data-sqrl="{{ session_sqrl.sqrl_url }}"></div>
|
||||
<a href="{{ sqrl_session.sqrl_url }}">
|
||||
<div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
|
||||
</a>
|
||||
<a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a>
|
||||
{# redirect to manage page after successful SQRL transaction #}
|
||||
|
@ -74,9 +74,9 @@
|
|||
</div>
|
||||
</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">
|
||||
<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;">
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -57,9 +57,9 @@
|
|||
</div>
|
||||
</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">
|
||||
<span class="line-center">or</span>
|
||||
</p>
|
||||
|
@ -69,21 +69,21 @@
|
|||
|
||||
<div class="sqrl-wrap">
|
||||
SQRL Login
|
||||
<a href="{{ session_sqrl.sqrl_url }}">
|
||||
<div id="sqrl-qr" data-sqrl="{{ session_sqrl.sqrl_url }}"></div>
|
||||
<a href="{{ sqrl_session.sqrl_url }}">
|
||||
<div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
|
||||
</a>
|
||||
<a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a>
|
||||
</div>
|
||||
|
||||
<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' %}"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<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()
|
||||
</script>
|
||||
<script type="application/javascript" src="{% static 'sqrl/sqrl.js' %}"></script>
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
Please use via SQRL using the information below.
|
||||
</p>
|
||||
|
||||
{% sqrl as session_sqrl %}
|
||||
{% sqrl_login_dropin session_sqrl login %}
|
||||
{% sqrl as sqrl_session %}
|
||||
{% sqrl_login_dropin sqrl_session login %}
|
||||
{% endblock %}
|
||||
|
||||
{% comment %}
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% sqrl as session_sqrl %}
|
||||
{% sqrl_login_dropin session_sqrl method="manage" %}
|
||||
{% sqrl as sqrl_session %}
|
||||
{% sqrl_login_dropin sqrl_session method="manage" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
|
|
@ -18,19 +18,19 @@
|
|||
}
|
||||
</style>
|
||||
<div>
|
||||
<form method="get" action="{{ session_sqrl.sqrl_url }}">
|
||||
<form method="get" action="{{ sqrl_session.sqrl_url }}">
|
||||
<div class="sqrl-wrap">
|
||||
SQRL Login
|
||||
<a href="{{ session_sqrl.sqrl_url }}">
|
||||
<div id="sqrl-qr" data-sqrl="{{ session_sqrl.sqrl_url }}"></div>
|
||||
<a href="{{ sqrl_session.sqrl_url }}">
|
||||
<div id="sqrl-qr" data-sqrl="{{ sqrl_session.sqrl_url }}"></div>
|
||||
</a>
|
||||
<a href="https://www.grc.com/sqrl/sqrl.htm">What is SQRL?</a>
|
||||
</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="submit" value="Authenticate using SQRL">
|
||||
</form>
|
||||
</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>
|
||||
|
|
|
@ -15,25 +15,25 @@ def sqrl(context):
|
|||
|
||||
|
||||
@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.
|
||||
Add it to your login template to make it SQRL-aware.
|
||||
|
||||
Usage:
|
||||
{% load sqrl %}
|
||||
{% sqrl as session_sqrl %}
|
||||
{% sqrl_login_dropin session_sqrl REDIR %}
|
||||
{% sqrl as sqrl_session %}
|
||||
{% sqrl_login_dropin sqrl_session REDIR %}
|
||||
|
||||
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:
|
||||
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, 'redir': reverse(redir)}
|
||||
return {'sqrl_session':sqrl_session, 'redir': reverse(redir)}
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
|
|
Loading…
Reference in a new issue