├── .bumpversion.cfg ├── .coveragerc ├── .flake8 ├── .github └── workflows │ └── test.yaml ├── .gitignore ├── .hgignore ├── .readthedocs.yaml ├── CHANGES.rst ├── LICENSE ├── README.rst ├── docs ├── Makefile ├── ext │ └── otpdocs.py └── source │ ├── changes.rst │ ├── conf.py │ └── index.rst ├── pyproject.toml ├── src └── otp_twilio │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── conf.py │ ├── migrations │ ├── 0001_initial.py │ ├── 0002_last_t.py │ ├── 0003_longer_number.py │ ├── 0004_sidechanneldevice.py │ └── __init__.py │ ├── models.py │ └── tests.py └── test └── test_project ├── __init__.py ├── settings.py ├── templates └── registration │ └── logged_out.html └── urls.py /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 1.0.5 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 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | source = otp_twilio -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | /.tox/ 13 | /.coverage 14 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /CHANGES.rst: -------------------------------------------------------------------------------- 1 | v1.0.5 - March 25, 2024 - Fix config validation 2 | -------------------------------------------------------------------------------- 3 | 4 | Fix `#10`_: Messaging Service Does Not Work Without OTP_TWILIO_FROM Setting 5 | 6 | .. _#10: https://github.com/django-otp/django-otp-twilio/pull/10 7 | 8 | 9 | v1.0.4 - July 20, 2023 - Add OTP_TWILIO_MESSAGING_SERVICE_SID setting 10 | -------------------------------------------------------------------------------- 11 | 12 | This project is now managed with `hatch`_, which replaces setuptools, pipenv, 13 | and tox. Users of the package should not be impacted. Developers can refer to 14 | the readme for details. If you're packaging this project from source, I suggest 15 | relying on pip's isolated builds rather than using hatch directly. 16 | 17 | `#9`_: OTP_TWILIO_MESSAGING_SERVICE_SID setting 18 | 19 | .. _hatch: https://hatch.pypa.io/ 20 | .. _#9: https://github.com/django-otp/django-otp-twilio/pull/9 21 | 22 | 23 | v1.0.3 - April 25, 2023 - Fix API key handling 24 | -------------------------------------------------------------------------------- 25 | 26 | Fix `#6`_: Code uses "TWILIO_API_KEY" instead of "OTP_TWILIO_API_KEY" 27 | 28 | .. _#6: https://github.com/django-otp/django-otp-twilio/pull/6 29 | 30 | 31 | v1.0.2 - April 11, 2023 - New configuration options 32 | -------------------------------------------------------------------------------- 33 | 34 | - Allow configuration of API URL and API key. 35 | 36 | 37 | v1.0.1 - November 29, 2021 - Forward compatibility 38 | -------------------------------------------------------------------------------- 39 | 40 | Default to AutoField to avoid spurious migrations. 41 | 42 | 43 | v1.0.0 - August 13, 2020 - Update test matrix 44 | -------------------------------------------------------------------------------- 45 | 46 | - Added Django 3.1 to the test environments and fixed deprecation warnings. 47 | 48 | - Version bumped to align with the core django-otp project. 49 | 50 | 51 | v0.6.0 - May 06, 2020 - ThrottlingMixin and SideChannelDevice 52 | -------------------------------------------------------------------------------- 53 | 54 | TwilioSMSDevice is now a :class:`~django_otp.models.SideChannelDevice` and 55 | implements :class:`~django_otp.models.ThrottlingMixin`. 56 | 57 | This also drops support for old versions of Python (2.7) and Django (1.11, 58 | 2.1). 59 | 60 | Note that this version includes migrations that will invalidate any in-flight 61 | tokens. 62 | 63 | 64 | v0.5.1 - August 26, 2019 - Housekeeping 65 | -------------------------------------------------------------------------------- 66 | 67 | Build, test, and documentation cleanup. 68 | 69 | 70 | v0.5.0 - August 14, 2018 - Django 2.1 support 71 | -------------------------------------------------------------------------------- 72 | 73 | - Drop support for Django < 1.11. 74 | 75 | 76 | v0.4.2 - October 18, 2017 - Fix migration 77 | -------------------------------------------------------------------------------- 78 | 79 | - Fix a spurious migration offered by makemigrations. 80 | 81 | 82 | v0.4.1 - August 29, 2017 - Default keys 83 | -------------------------------------------------------------------------------- 84 | 85 | - Fix `#25`_: make sure default keys are unicode values. 86 | 87 | .. _#25: https://bitbucket.org/psagers/django-otp/issues/25/attributeerror-bytes-object-has-no 88 | 89 | 90 | v0.4.0 - July 19, 2017 - Update support matrix 91 | -------------------------------------------------------------------------------- 92 | 93 | - Drop support for versions of Django that are past EOL. 94 | 95 | 96 | v0.3.6 - November 27, 2016 - Forward compatbility for Django 2.0 97 | -------------------------------------------------------------------------------- 98 | 99 | - Treat :attr:`~django.contrib.auth.models.User.is_authenticated` and 100 | :attr:`~django.contrib.auth.models.User.is_anonymous` as properties in Django 101 | 1.10 and later. 102 | 103 | - Add explict on_delete behavior for all foreign keys. 104 | 105 | 106 | v0.3.5 - October 9, 2016 - Longer numbers 107 | -------------------------------------------------------------------------------- 108 | 109 | - Support longer phone numbers. 110 | 111 | 112 | v0.3.4 - January 10, 2016 - Python 3 cleanup 113 | -------------------------------------------------------------------------------- 114 | 115 | - All modules include all four Python 3 __future__ imports for consistency. 116 | 117 | - Migrations no longer have byte strings in them. 118 | 119 | 120 | v0.3.3 - October 11, 2015 - Django 1.8 121 | -------------------------------------------------------------------------------- 122 | 123 | - Use ModelAdmin.raw_id_fields for foreign keys to users. 124 | 125 | - General cleanup and compatibility with Django 1.9a1. 126 | 127 | 128 | v0.3.1 - March 1, 2015 - Token validity 129 | -------------------------------------------------------------------------------- 130 | 131 | - The length of time that tokens are valid can now be configured with 132 | :setting:`OTP_TWILIO_TOKEN_VALIDITY`. 133 | 134 | - Tokens now become invalid as soon as they have been verified. 135 | 136 | 137 | v0.3.0 - February 7, 2015 - Support Django migrations 138 | -------------------------------------------------------------------------------- 139 | 140 | - otp_twilio now has both Django and South migrations. Please see the `upgrade 141 | notes`_ for details on upgrading from previous versions. 142 | 143 | .. _upgrade notes: https://pythonhosted.org/django-otp/overview.html#upgrading 144 | 145 | 146 | v0.2.2 - Aug 20, 2014 - Challenge template 147 | -------------------------------------------------------------------------------- 148 | 149 | - :setting:`OTP_TWILIO_CHALLENGE_MESSAGE` allows you to customize the string 150 | returned to the user after the SMS is sent. It also accepts the {token} 151 | placeholder as a convenience for development. 152 | 153 | - Fixes for unit tests under the latest pre-release version of Django 1.7. 154 | 155 | 156 | v0.2.1 - May 8, 2014 - Message template 157 | -------------------------------------------------------------------------------- 158 | 159 | - :setting:`OTP_TWILIO_TOKEN_TEMPLATE` allows you to customize the message that 160 | is sent by SMS. 161 | 162 | 163 | v0.2.0 - November 10, 2013 - Django 1.6 164 | -------------------------------------------------------------------------------- 165 | 166 | - Now supports Django 1.4 to 1.6 on Python 2.6, 2.7, 3.2, and 3.3. This is the 167 | first release for Python 3. 168 | 169 | 170 | v0.1.3 - May 9, 2013 - Unit test improvements 171 | -------------------------------------------------------------------------------- 172 | 173 | Major unit test cleanup. Tests should pass or be skipped under all supported 174 | versions of Django, with or without custom users and timzeone support. 175 | 176 | 177 | v0.1.2 - March 24, 2013 - Bug fix 178 | -------------------------------------------------------------------------------- 179 | 180 | - Fix for requests integration. 181 | 182 | 183 | v0.1.1 - October 8, 2012 - Bug fix 184 | -------------------------------------------------------------------------------- 185 | 186 | - Fix exception with an empty token form. 187 | 188 | 189 | v0.1.0 - August 20, 2012 - Initial Release 190 | -------------------------------------------------------------------------------- 191 | 192 | Initial release. 193 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | .. image:: https://img.shields.io/pypi/v/django-otp-twilio?color=blue 2 | :target: https://pypi.org/project/django-otp-twilio/ 3 | :alt: PyPI 4 | .. image:: https://img.shields.io/readthedocs/django-otp-twilio 5 | :target: https://django-otp-twilio.readthedocs.io/ 6 | :alt: Documentation 7 | .. image:: https://img.shields.io/badge/github-django--otp--twilio-green 8 | :target: https://github.com/django-otp/django-otp-twilio 9 | :alt: Source 10 | 11 | This is a django-otp plugin that delivers tokens via Twilio's `SMS 12 | `_ service. 13 | 14 | See `django-otp `_ for more information 15 | on the OTP framework. 16 | 17 | .. end-of-doc-intro 18 | 19 | 20 | Development 21 | ----------- 22 | 23 | This project is built and managed with `hatch`_. If you don't have hatch, I 24 | recommend installing it with `pipx`_: ``pipx install hatch``. 25 | 26 | ``pyproject.toml`` defines several useful scripts for development and testing. 27 | The default environment includes all dev and test dependencies for quickly 28 | running tests. The ``test`` environment defines the test matrix for running the 29 | full validation suite. Everything is executed in the context of the Django 30 | project in test/test\_project. 31 | 32 | As a quick primer, hatch scripts can be run with ``hatch run [:]