├── src
└── otp_yubikey
│ ├── __init__.py
│ ├── migrations
│ ├── __init__.py
│ ├── 0002_auto_20200723_1650.py
│ └── 0001_initial.py
│ ├── apps.py
│ ├── admin.py
│ ├── tests.py
│ └── models.py
├── test
└── test_project
│ ├── __init__.py
│ ├── templates
│ └── registration
│ │ └── logged_out.html
│ ├── urls.py
│ └── settings.py
├── .coveragerc
├── docs
├── source
│ ├── changes.rst
│ ├── .spell.utf-8.add
│ ├── index.rst
│ └── conf.py
├── ext
│ └── otpdocs.py
└── Makefile
├── .gitignore
├── .flake8
├── .readthedocs.yaml
├── .hgignore
├── .bumpversion.cfg
├── .github
└── workflows
│ └── test.yaml
├── LICENSE
├── README.rst
├── pyproject.toml
└── CHANGES.rst
/src/otp_yubikey/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/test_project/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/otp_yubikey/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.coveragerc:
--------------------------------------------------------------------------------
1 | [run]
2 | source = otp_yubikey
--------------------------------------------------------------------------------
/test/test_project/templates/registration/logged_out.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/source/changes.rst:
--------------------------------------------------------------------------------
1 | Change Log
2 | ==========
3 |
4 | .. include:: ../../CHANGES.rst
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python
2 | __pycache__/
3 |
4 | # setuptools
5 | /MANIFEST
6 | /build/
7 | /dist/
8 | /docs/build/
9 | *.egg-info/
10 |
11 | # Other tools
12 | /.coverage
13 | /.tox/
14 |
--------------------------------------------------------------------------------
/src/otp_yubikey/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class DefaultConfig(AppConfig):
5 | name = 'otp_yubikey'
6 | default_auto_field = 'django.db.models.AutoField'
7 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | ignore =
3 | # line break before binary operator
4 | W503
5 | # line break after binary operator
6 | W504
7 | # line too long
8 | E501
9 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | build:
4 | os: ubuntu-22.04
5 | tools:
6 | python: '3.12'
7 |
8 | sphinx:
9 | configuration: docs/source/conf.py
10 |
11 | python:
12 | install:
13 | - method: pip
14 | path: .
15 |
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | # Don't remove this file.
2 | #
3 | # When hatch builds an sdist, it includes any .gitignore and .hgignore it can
4 | # find here or in parent directories. To avoid information leakage, this file
5 | # masks any .hgignore one might have in their home directory.
6 |
--------------------------------------------------------------------------------
/docs/ext/otpdocs.py:
--------------------------------------------------------------------------------
1 | """
2 | Extra stuff for the django-otp Sphinx docs.
3 | """
4 |
5 | def setup(app):
6 | app.add_crossref_type(
7 | directivename = "setting",
8 | rolename = "setting",
9 | indextemplate = "pair: %s; setting",
10 | )
11 |
--------------------------------------------------------------------------------
/test/test_project/urls.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | import django.contrib.auth.views
3 | from django.urls import path
4 |
5 |
6 | urlpatterns = [
7 | path('login/', django.contrib.auth.views.LoginView.as_view()),
8 | path('logout/', django.contrib.auth.views.LogoutView.as_view()),
9 | path('admin/', admin.site.urls),
10 | ]
11 |
--------------------------------------------------------------------------------
/docs/source/.spell.utf-8.add:
--------------------------------------------------------------------------------
1 | django
2 | otp
3 | yubikey
4 | README
5 | #emoteYubikeDevice
6 | YubikeyDevice
7 | RemoteYubikeyDevice
8 | API
9 | Yubico
10 | Yubico's
11 | APIs
12 | SL
13 | google
14 | php
15 | wiki
16 | ValidationProtocolV20
17 | p
18 | urllib2
19 | HTTPS
20 | urls
21 | #emoteYubiKeyDevice
22 | ValidationService
23 | YubiKeys
24 | admin
25 | YubikeyDeviceAdmin
26 | RemoteYubikeyDeviceAdmin
27 | ValidationServiceAdmin
28 | contrib
29 | ModelAdmin
30 |
--------------------------------------------------------------------------------
/.bumpversion.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | current_version = 1.1.0
3 | commit = true
4 | message = Version {new_version}
5 | tag = true
6 |
7 | [bumpversion:file:CHANGES.rst]
8 | search = Unreleased
9 | replace = v{new_version} - {now:%B %d, %Y}
10 |
11 | [bumpversion:file:pyproject.toml]
12 | search = version = "{current_version}"
13 | replace = version = "{new_version}"
14 |
15 | [bumpversion:file:docs/source/conf.py]
16 | search = release = '{current_version}'
17 | replace = release = '{new_version}'
18 |
--------------------------------------------------------------------------------
/src/otp_yubikey/migrations/0002_auto_20200723_1650.py:
--------------------------------------------------------------------------------
1 | # Generated by Django 2.2.14 on 2020-07-23 16:50
2 |
3 | from django.db import migrations, models
4 |
5 |
6 | class Migration(migrations.Migration):
7 |
8 | dependencies = [
9 | ('otp_yubikey', '0001_initial'),
10 | ]
11 |
12 | operations = [
13 | migrations.AlterField(
14 | model_name='validationservice',
15 | name='use_ssl',
16 | field=models.BooleanField(default=True, help_text='Use HTTPS API URLs by default?', verbose_name='Use SSL'),
17 | ),
18 | ]
19 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | name: Run tests
2 |
3 | on:
4 | pull_request:
5 | branches: [ master ]
6 |
7 | jobs:
8 | test:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 |
13 | - uses: actions/setup-python@v4
14 | with:
15 | python-version: |
16 | 3.9
17 | 3.11
18 | 3.13
19 |
20 | - name: Install hatch
21 | run: pipx install hatch
22 |
23 | - name: Run tests
24 | run: hatch run test:run
25 |
26 | - name: Build docs
27 | run: hatch run docs:make
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
4 | software, either in source code form or as a compiled binary, for any purpose,
5 | commercial or non-commercial, and by any means.
6 |
7 | In jurisdictions that recognize copyright laws, the author or authors of this
8 | software dedicate any and all copyright interest in the software to the public
9 | domain. We make this dedication for the benefit of the public at large and to
10 | the detriment of our heirs and successors. We intend this dedication to be an
11 | overt act of relinquishment in perpetuity of all present and future rights to
12 | this software under copyright law.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
19 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 |
21 | For more information, please refer to
22 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | django-otp-yubikey
2 | ==================
3 |
4 | .. include:: ../../README.rst
5 | :end-before: .. end-of-doc-intro
6 |
7 |
8 | Installation
9 | ------------
10 |
11 | Add otp_yubikey to INSTALLED_APPS after django_otp core::
12 |
13 | INSTALLED_APPS = [
14 | ...
15 | 'django_otp',
16 | 'django_otp.plugins.otp_totp',
17 | 'django_otp.plugins.otp_hotp',
18 | 'django_otp.plugins.otp_static',
19 |
20 | 'otp_yubikey',
21 | ]
22 |
23 |
24 | Local Verification
25 | ------------------
26 |
27 | .. autoclass:: otp_yubikey.models.YubikeyDevice
28 | :members:
29 |
30 |
31 | Remote Verification
32 | -------------------
33 |
34 | .. autoclass:: otp_yubikey.models.ValidationService
35 | :members:
36 |
37 | .. autoclass:: otp_yubikey.models.RemoteYubikeyDevice
38 | :members:
39 |
40 |
41 | Admin
42 | -----
43 |
44 | The following :class:`~django.contrib.admin.ModelAdmin` subclasses are
45 | registered with the default admin site. We recommend their use with custom admin
46 | sites as well:
47 |
48 | .. autoclass:: otp_yubikey.admin.YubikeyDeviceAdmin
49 |
50 | .. autoclass:: otp_yubikey.admin.ValidationServiceAdmin
51 |
52 | .. autoclass:: otp_yubikey.admin.RemoteYubikeyDeviceAdmin
53 |
54 |
55 | Changes
56 | -------
57 |
58 | :doc:`changes`
59 |
60 |
61 | License
62 | =======
63 |
64 | .. include:: ../../LICENSE
65 |
--------------------------------------------------------------------------------
/test/test_project/settings.py:
--------------------------------------------------------------------------------
1 | # django-otp-yubikey test project
2 |
3 | from os.path import abspath, dirname, join
4 |
5 |
6 | def project_path(path):
7 | return abspath(join(dirname(__file__), path))
8 |
9 |
10 | DEBUG = True
11 |
12 | DATABASES = {
13 | 'default': {
14 | 'ENGINE': 'django.db.backends.sqlite3',
15 | 'NAME': ':memory:',
16 | }
17 | }
18 |
19 | DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
20 |
21 | INSTALLED_APPS = [
22 | 'django.contrib.admin',
23 | 'django.contrib.auth',
24 | 'django.contrib.contenttypes',
25 | 'django.contrib.sessions',
26 | 'django.contrib.messages',
27 |
28 | 'django_otp',
29 | 'otp_yubikey',
30 | ]
31 |
32 | MIDDLEWARE = [
33 | 'django.middleware.security.SecurityMiddleware',
34 | 'django.contrib.sessions.middleware.SessionMiddleware',
35 | 'django.middleware.common.CommonMiddleware',
36 | 'django.middleware.csrf.CsrfViewMiddleware',
37 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
38 | 'django_agent_trust.middleware.AgentMiddleware',
39 | 'django_otp.middleware.OTPMiddleware',
40 | 'django.contrib.messages.middleware.MessageMiddleware',
41 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
42 | ]
43 |
44 | TEMPLATES = [
45 | {
46 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
47 | 'APP_DIRS': True,
48 | 'DIRS': [
49 | project_path('templates'),
50 | ],
51 | 'OPTIONS': {
52 | 'context_processors': [
53 | 'django.template.context_processors.debug',
54 | 'django.template.context_processors.request',
55 | 'django.contrib.auth.context_processors.auth',
56 | 'django.contrib.messages.context_processors.messages',
57 | ],
58 | },
59 | },
60 | ]
61 |
62 | SECRET_KEY = 'PWuluw4x48GkT7JDPzlDQsBJC8pjIIiqodW9MuMYcU315YEkGJL41i5qooJsg3Tt'
63 |
64 | ROOT_URLCONF = 'test_project.urls'
65 |
66 | USE_TZ = True
67 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | .. image:: https://img.shields.io/pypi/v/django-otp-yubikey?color=blue
2 | :target: https://pypi.org/project/django-otp-yubikey/
3 | :alt: PyPI
4 | .. image:: https://img.shields.io/readthedocs/django-otp-yubikey
5 | :target: https://django-otp-yubikey.readthedocs.io/
6 | :alt: Documentation
7 | .. image:: https://img.shields.io/badge/github-django--agent--trust-green
8 | :target: https://github.com/django-otp/django-otp-yubikey
9 | :alt: Source
10 |
11 | This is a django-otp plugin that handles `YubiKey
12 | `_ devices using the Yubico OTP algorithm. This
13 | includes two device definitions: one to verify YubiKey tokens locally and
14 | another to verify them against a `web service
15 | `_.
16 |
17 | See `django-otp `_ for more information on
18 | the OTP framework.
19 |
20 | .. end-of-doc-intro
21 |
22 |
23 | Development
24 | -----------
25 |
26 | This project is built and managed with `hatch`_. If you don't have hatch, I
27 | recommend installing it with `pipx`_: ``pipx install hatch``.
28 |
29 | ``pyproject.toml`` defines several useful scripts for development and testing.
30 | The default environment includes all dev and test dependencies for quickly
31 | running tests. The ``test`` environment defines the test matrix for running the
32 | full validation suite. Everything is executed in the context of the Django
33 | project in test/test\_project.
34 |
35 | As a quick primer, hatch scripts can be run with ``hatch run [:]