diff --git a/CHANGELOG b/CHANGELOG index bf12dbc..ea5a6c5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,13 @@ +Wed, 04 Sep 2019 21:08:57 -0500 +Keaton +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 Fixing functionality diff --git a/docs/example_dropin.png b/docs/example_dropin.png new file mode 100644 index 0000000..4f158d4 Binary files /dev/null and b/docs/example_dropin.png differ diff --git a/readme.md b/readme.md index e64cd6a..fb93d6e 100644 --- a/readme.md +++ b/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 %} + +
+
+ + + +## 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 diff --git a/sqrl/static/sqrl/sqrl.js b/sqrl/static/sqrl/sqrl.js index a41e330..b57429b 100644 --- a/sqrl/static/sqrl/sqrl.js +++ b/sqrl/static/sqrl/sqrl.js @@ -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; }, diff --git a/sqrl/templates/admin/auth/user/sqrl_manage.html b/sqrl/templates/admin/auth/user/sqrl_manage.html index bfe943a..2ea7b6e 100644 --- a/sqrl/templates/admin/auth/user/sqrl_manage.html +++ b/sqrl/templates/admin/auth/user/sqrl_manage.html @@ -60,13 +60,13 @@

{% endif %} - {% sqrl as session_sqrl %} + {% sqrl as sqrl_session %}
SQRL Login - -
+
+
What is SQRL? {# redirect to manage page after successful SQRL transaction #} @@ -74,9 +74,9 @@
-
+
- +
diff --git a/sqrl/templates/admin/login.html b/sqrl/templates/admin/login.html index 83b4e38..ca11e50 100644 --- a/sqrl/templates/admin/login.html +++ b/sqrl/templates/admin/login.html @@ -57,9 +57,9 @@ - {% sqrl as session_sqrl %} + {% sqrl as sqrl_session %} -
+

or

@@ -69,21 +69,21 @@
- +
diff --git a/sqrl/templates/sqrl/login.html b/sqrl/templates/sqrl/login.html index 19b8cf1..d8694fa 100644 --- a/sqrl/templates/sqrl/login.html +++ b/sqrl/templates/sqrl/login.html @@ -11,8 +11,8 @@ Please use via SQRL using the information below.

- {% sqrl as session_sqrl %} - {% sqrl_login_dropin session_sqrl login %} + {% sqrl as sqrl_session %} + {% sqrl_login_dropin sqrl_session login %} {% endblock %} {% comment %} diff --git a/sqrl/templates/sqrl/manage.html b/sqrl/templates/sqrl/manage.html index eca65ac..2853fd8 100644 --- a/sqrl/templates/sqrl/manage.html +++ b/sqrl/templates/sqrl/manage.html @@ -32,8 +32,8 @@

{% 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 %} diff --git a/sqrl/templates/sqrl/sqrl-dropin.html b/sqrl/templates/sqrl/sqrl-dropin.html index 2d864dd..d8955ee 100644 --- a/sqrl/templates/sqrl/sqrl-dropin.html +++ b/sqrl/templates/sqrl/sqrl-dropin.html @@ -18,19 +18,19 @@ }
-
+ - +
- + diff --git a/sqrl/templatetags/sqrl.py b/sqrl/templatetags/sqrl.py index 2d596db..69daf2d 100644 --- a/sqrl/templatetags/sqrl.py +++ b/sqrl/templatetags/sqrl.py @@ -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