django-solomon 0.1.3__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. django_solomon-0.2.0/CHANGELOG.md +43 -0
  2. {django_solomon-0.1.3 → django_solomon-0.2.0}/PKG-INFO +12 -4
  3. {django_solomon-0.1.3 → django_solomon-0.2.0}/README.md +11 -3
  4. django_solomon-0.2.0/docs/contributing.md +138 -0
  5. django_solomon-0.2.0/docs/installation.md +174 -0
  6. django_solomon-0.2.0/docs/settings.md +180 -0
  7. django_solomon-0.2.0/docs/templates.md +256 -0
  8. {django_solomon-0.1.3 → django_solomon-0.2.0}/justfile +3 -3
  9. {django_solomon-0.1.3 → django_solomon-0.2.0}/mkdocs.yml +4 -0
  10. {django_solomon-0.1.3 → django_solomon-0.2.0}/pyproject.toml +1 -0
  11. {django_solomon-0.1.3 → django_solomon-0.2.0}/tox.ini +2 -1
  12. {django_solomon-0.1.3 → django_solomon-0.2.0}/uv.lock +24 -0
  13. django_solomon-0.1.3/CHANGELOG.md +0 -1
  14. {django_solomon-0.1.3 → django_solomon-0.2.0}/.forgejo/workflows/release.yml +0 -0
  15. {django_solomon-0.1.3 → django_solomon-0.2.0}/.forgejo/workflows/tests.yml +0 -0
  16. {django_solomon-0.1.3 → django_solomon-0.2.0}/.gitignore +0 -0
  17. {django_solomon-0.1.3 → django_solomon-0.2.0}/.pre-commit-config.yaml +0 -0
  18. {django_solomon-0.1.3 → django_solomon-0.2.0}/.readthedocs.yml +0 -0
  19. {django_solomon-0.1.3 → django_solomon-0.2.0}/LICENSE +0 -0
  20. {django_solomon-0.1.3 → django_solomon-0.2.0}/docs/changelog.md +0 -0
  21. {django_solomon-0.1.3 → django_solomon-0.2.0}/docs/index.md +0 -0
  22. {django_solomon-0.1.3 → django_solomon-0.2.0}/docs/requirements.txt +0 -0
  23. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/__init__.py +0 -0
  24. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/admin.py +0 -0
  25. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/apps.py +0 -0
  26. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/backends.py +0 -0
  27. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/config.py +0 -0
  28. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/forms.py +0 -0
  29. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/locale/de/LC_MESSAGES/django.po +0 -0
  30. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/locale/en/LC_MESSAGES/django.po +0 -0
  31. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/management/__init__.py +0 -0
  32. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/management/commands/__init__.py +0 -0
  33. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/migrations/0001_initial.py +0 -0
  34. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/migrations/__init__.py +0 -0
  35. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/models.py +0 -0
  36. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/py.typed +0 -0
  37. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/templates/django_solomon/base/invalid_magic_link.html +0 -0
  38. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/templates/django_solomon/base/login_form.html +0 -0
  39. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/templates/django_solomon/base/magic_link_sent.html +0 -0
  40. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/templates/django_solomon/email/magic_link.mjml +0 -0
  41. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/templates/django_solomon/email/magic_link.txt +0 -0
  42. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/urls.py +0 -0
  43. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/utilities.py +0 -0
  44. {django_solomon-0.1.3 → django_solomon-0.2.0}/src/django_solomon/views.py +0 -0
  45. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/.gitignore +0 -0
  46. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/__init__.py +0 -0
  47. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/conftest.py +0 -0
  48. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/settings.py +0 -0
  49. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/templates/base.html +0 -0
  50. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_admin.py +0 -0
  51. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_backends.py +0 -0
  52. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_config.py +0 -0
  53. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_forms.py +0 -0
  54. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_models.py +0 -0
  55. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_urls.py +0 -0
  56. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_utilities.py +0 -0
  57. {django_solomon-0.1.3 → django_solomon-0.2.0}/tests/test_views.py +0 -0
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to django-solomon will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0] - 2025-04-19
9
+
10
+ ### Added
11
+
12
+ - Comprehensive guides for usage and contribution
13
+ - Parallel test execution with pytest-xdist
14
+ - Link to official documentation in README
15
+ - New badges to README
16
+ - Initial changelog structure
17
+
18
+ ### Changed
19
+
20
+ - Improved documentation organization
21
+
22
+ ## [0.1.3] - 2025-04-19
23
+
24
+ ### Added
25
+
26
+ - Initial public release of django-solomon
27
+ - Passwordless authentication using magic links sent via email
28
+ - Configurable link expiration time (default: 300 seconds)
29
+ - Blacklist functionality to block specific email addresses
30
+ - Support for auto-creating users when they request a magic link
31
+ - Customizable templates for emails and pages
32
+ - MJML support for HTML emails
33
+ - Compatible with Django's authentication system
34
+ - Support for Django 4.2, 5.0, 5.1, and 5.2
35
+ - Support for Python 3.10, 3.11, 3.12, and 3.13
36
+ - Comprehensive test suite with high code coverage
37
+ - Full documentation
38
+
39
+ ### Security
40
+
41
+ - One-time use magic links
42
+ - Option to allow only one active magic link per user
43
+ - Configurable permissions for admin and staff users
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-solomon
3
- Version: 0.1.3
3
+ Version: 0.2.0
4
4
  Summary: A Django app for passwordless authentication using magic links.
5
5
  Project-URL: Home, https://django-solomon.rtfd.io/
6
6
  Project-URL: Documentation, https://django-solomon.rtfd.io/
@@ -55,6 +55,10 @@ Description-Content-Type: text/markdown
55
55
  [![Python versions](https://img.shields.io/pypi/pyversions/django-solomon.svg)](https://pypi.org/project/django-solomon/)
56
56
  [![Django versions](https://img.shields.io/pypi/djversions/django-solomon.svg)](https://pypi.org/project/django-solomon/)
57
57
  [![Documentation Status](https://readthedocs.org/projects/django-solomon/badge/?version=latest)](https://django-solomon.rtfd.io/en/latest/?badge=latest)
58
+ [![Downloads](https://static.pepy.tech/badge/django-solomon)](https://pepy.tech/project/django-solomon)
59
+ [![Downloads / Month](https://pepy.tech/badge/django-solomon/month)](https://pepy.tech/project/django-solomon)
60
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
61
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
58
62
 
59
63
  A Django app for passwordless authentication using magic links.
60
64
 
@@ -138,8 +142,8 @@ django-solomon provides several settings that you can customize in your Django s
138
142
  | `SOLOMON_LOGIN_REDIRECT_URL` | `settings.LOGIN_REDIRECT_URL` | The URL to redirect to after successful authentication |
139
143
  | `SOLOMON_ALLOW_ADMIN_LOGIN` | `True` | If enabled, allows superusers to log in using magic links |
140
144
  | `SOLOMON_ALLOW_STAFF_LOGIN` | `True` | If enabled, allows staff users to log in using magic links |
141
- | `SOLOMON_MAIL_TEXT_TEMPLATE` | `"django_solomon/email/magic_link.txt"` | The template to use for plain text magic link emails |
142
- | `SOLOMON_MAIL_MJML_TEMPLATE` | `"django_solomon/email/magic_link.mjml"` | The template to use for HTML magic link emails (MJML format) |
145
+ | `SOLOMON_MAIL_TEXT_TEMPLATE` | `"django_solomon/email/magic_link.txt"` | The template to use for plain text magic link emails |
146
+ | `SOLOMON_MAIL_MJML_TEMPLATE` | `"django_solomon/email/magic_link.mjml"` | The template to use for HTML magic link emails (MJML format) |
143
147
  | `SOLOMON_LOGIN_FORM_TEMPLATE` | `"django_solomon/base/login_form.html"` | The template to use for the login form page |
144
148
  | `SOLOMON_INVALID_MAGIC_LINK_TEMPLATE` | `"django_solomon/base/invalid_magic_link.html"` | The template to use for the invalid magic link page |
145
149
  | `SOLOMON_MAGIC_LINK_SENT_TEMPLATE` | `"django_solomon/base/magic_link_sent.html"` | The template to use for the magic link sent confirmation page |
@@ -189,9 +193,13 @@ if user:
189
193
  login(request, user)
190
194
  ```
191
195
 
196
+ ## Documentation
197
+
198
+ For more detailed information, tutorials, and advanced usage examples, please visit the [official documentation](https://django-solomon.rtfd.io/).
199
+
192
200
  ## License
193
201
 
194
- This software is licensed under [MIT license](./LICENSE).
202
+ This software is licensed under [MIT license](https://codeberg.org/oliverandrich/django-solomon/src/branch/main/LICENSE).
195
203
 
196
204
  ## Contributing
197
205
 
@@ -4,6 +4,10 @@
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/django-solomon.svg)](https://pypi.org/project/django-solomon/)
5
5
  [![Django versions](https://img.shields.io/pypi/djversions/django-solomon.svg)](https://pypi.org/project/django-solomon/)
6
6
  [![Documentation Status](https://readthedocs.org/projects/django-solomon/badge/?version=latest)](https://django-solomon.rtfd.io/en/latest/?badge=latest)
7
+ [![Downloads](https://static.pepy.tech/badge/django-solomon)](https://pepy.tech/project/django-solomon)
8
+ [![Downloads / Month](https://pepy.tech/badge/django-solomon/month)](https://pepy.tech/project/django-solomon)
9
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
10
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
7
11
 
8
12
  A Django app for passwordless authentication using magic links.
9
13
 
@@ -87,8 +91,8 @@ django-solomon provides several settings that you can customize in your Django s
87
91
  | `SOLOMON_LOGIN_REDIRECT_URL` | `settings.LOGIN_REDIRECT_URL` | The URL to redirect to after successful authentication |
88
92
  | `SOLOMON_ALLOW_ADMIN_LOGIN` | `True` | If enabled, allows superusers to log in using magic links |
89
93
  | `SOLOMON_ALLOW_STAFF_LOGIN` | `True` | If enabled, allows staff users to log in using magic links |
90
- | `SOLOMON_MAIL_TEXT_TEMPLATE` | `"django_solomon/email/magic_link.txt"` | The template to use for plain text magic link emails |
91
- | `SOLOMON_MAIL_MJML_TEMPLATE` | `"django_solomon/email/magic_link.mjml"` | The template to use for HTML magic link emails (MJML format) |
94
+ | `SOLOMON_MAIL_TEXT_TEMPLATE` | `"django_solomon/email/magic_link.txt"` | The template to use for plain text magic link emails |
95
+ | `SOLOMON_MAIL_MJML_TEMPLATE` | `"django_solomon/email/magic_link.mjml"` | The template to use for HTML magic link emails (MJML format) |
92
96
  | `SOLOMON_LOGIN_FORM_TEMPLATE` | `"django_solomon/base/login_form.html"` | The template to use for the login form page |
93
97
  | `SOLOMON_INVALID_MAGIC_LINK_TEMPLATE` | `"django_solomon/base/invalid_magic_link.html"` | The template to use for the invalid magic link page |
94
98
  | `SOLOMON_MAGIC_LINK_SENT_TEMPLATE` | `"django_solomon/base/magic_link_sent.html"` | The template to use for the magic link sent confirmation page |
@@ -138,9 +142,13 @@ if user:
138
142
  login(request, user)
139
143
  ```
140
144
 
145
+ ## Documentation
146
+
147
+ For more detailed information, tutorials, and advanced usage examples, please visit the [official documentation](https://django-solomon.rtfd.io/).
148
+
141
149
  ## License
142
150
 
143
- This software is licensed under [MIT license](./LICENSE).
151
+ This software is licensed under [MIT license](https://codeberg.org/oliverandrich/django-solomon/src/branch/main/LICENSE).
144
152
 
145
153
  ## Contributing
146
154
 
@@ -0,0 +1,138 @@
1
+ ---
2
+ hide:
3
+ - navigation
4
+ ---
5
+
6
+ # Contributing to django-solomon
7
+
8
+ Thank you for your interest in contributing to django-solomon! This guide will help you get started with the development process.
9
+
10
+ ## Development Environment Setup
11
+
12
+ ### Prerequisites
13
+
14
+ Before setting up the development environment, ensure you have:
15
+
16
+ - Python 3.10 or higher
17
+ - Git
18
+ - [uv](https://github.com/astral-sh/uv) for dependency management
19
+ - [just](https://github.com/casey/just) for running commands
20
+
21
+ ### Setting Up the Development Environment
22
+
23
+ 1. Clone the repository:
24
+
25
+ ```bash
26
+ git clone https://codeberg.org/oliverandrich/django-solomon.git
27
+ cd django-solomon
28
+ ```
29
+
30
+ 2. Set up the development environment using the bootstrap command:
31
+
32
+ ```bash
33
+ just bootstrap
34
+ ```
35
+
36
+ This command will:
37
+ - Initialize a git repository
38
+ - Install all dependencies
39
+ - Set up pre-commit hooks
40
+
41
+ If you already have a cloned repository, you can install dependencies with:
42
+
43
+ ```bash
44
+ just upgrade
45
+ ```
46
+
47
+ ## Development Workflow
48
+
49
+ ### Running Tests
50
+
51
+ To run the test suite with coverage reporting:
52
+
53
+ ```bash
54
+ just test
55
+ ```
56
+
57
+ To run the full test suite across all supported Python and Django versions:
58
+
59
+ ```bash
60
+ just test-all
61
+ ```
62
+
63
+ ### Linting and Code Quality
64
+
65
+ The project uses Ruff for linting and formatting. To run the linters:
66
+
67
+ ```bash
68
+ just lint
69
+ ```
70
+
71
+ This will run all pre-commit hooks, including Ruff linting and formatting.
72
+
73
+ ### Documentation
74
+
75
+ To serve the documentation locally:
76
+
77
+ ```bash
78
+ just serve-docs
79
+ ```
80
+
81
+ This will start a local server at http://127.0.0.1:8000/ where you can preview the documentation.
82
+
83
+ ## Coding Standards
84
+
85
+ ### Python Style Guide
86
+
87
+ The project follows the PEP 8 style guide with some modifications:
88
+
89
+ - Maximum line length is 120 characters
90
+ - Uses double quotes for strings
91
+ - Does NOT use relative imports for internal modules
92
+
93
+ Ruff is configured to enforce these standards. The configuration can be found in `pyproject.toml`.
94
+
95
+ ### Type Annotations
96
+
97
+ The project uses type annotations and mypy for type checking. Please add type annotations to all new code.
98
+
99
+ ### Testing
100
+
101
+ All new features and bug fixes should include tests. The project uses pytest for testing.
102
+
103
+ - Place tests in the `tests/` directory
104
+ - Ensure tests are isolated and don't depend on external services
105
+ - Aim for high test coverage
106
+
107
+ ## Pull Request Process
108
+
109
+ 1. Fork the repository on [Codeberg](https://codeberg.org/oliverandrich/django-solomon)
110
+ 2. Create a new branch for your feature or bug fix
111
+ 3. Make your changes, following the coding standards
112
+ 4. Add tests for your changes
113
+ 5. Run the test suite to ensure all tests pass
114
+ 6. Update the documentation if necessary
115
+ 7. Submit a pull request to the main repository
116
+
117
+ ### Pull Request Guidelines
118
+
119
+ - Keep pull requests focused on a single feature or bug fix
120
+ - Include a clear description of the changes
121
+ - Reference any related issues
122
+ - Ensure all tests pass and code quality checks succeed
123
+ - Update the CHANGELOG.md file if your changes are user-facing
124
+
125
+ ## Release Process
126
+
127
+ The project follows [Semantic Versioning](https://semver.org/). The release process is handled by the maintainers.
128
+
129
+ ## Getting Help
130
+
131
+ If you have questions or need help with the development process, you can:
132
+
133
+ - Open an issue on [Codeberg](https://codeberg.org/oliverandrich/django-solomon/issues)
134
+ - Contact the maintainers directly
135
+
136
+ ## Code of Conduct
137
+
138
+ Please be respectful and considerate of others when contributing to the project. We aim to foster an inclusive and welcoming community.
@@ -0,0 +1,174 @@
1
+ ---
2
+ hide:
3
+ - navigation
4
+ ---
5
+
6
+ # Installation and Setup
7
+
8
+ This guide will walk you through the process of installing and setting up django-solomon in your Django project.
9
+
10
+ ## Prerequisites
11
+
12
+ Before installing django-solomon, ensure you have:
13
+
14
+ - Python 3.10 or higher
15
+ - Django 4.2 or higher
16
+ - A working email configuration for sending magic links
17
+
18
+ ## Installation Methods
19
+
20
+ ### Using pip (Recommended)
21
+
22
+ The simplest way to install django-solomon is using pip:
23
+
24
+ ```bash
25
+ pip install django-solomon
26
+ ```
27
+
28
+ ### Using a Virtual Environment
29
+
30
+ It's recommended to install django-solomon in a virtual environment:
31
+
32
+ ```bash
33
+ # Create a virtual environment
34
+ python -m venv venv
35
+
36
+ # Activate the virtual environment
37
+ # On Windows
38
+ venv\Scripts\activate
39
+ # On macOS/Linux
40
+ source venv/bin/activate
41
+
42
+ # Install django-solomon
43
+ pip install django-solomon
44
+ ```
45
+
46
+ ### From Source
47
+
48
+ You can also install django-solomon directly from the source code:
49
+
50
+ ```bash
51
+ git clone https://codeberg.org/oliverandrich/django-solomon.git
52
+ cd django-solomon
53
+ pip install -e .
54
+ ```
55
+
56
+ ## Configuration Steps
57
+
58
+ After installing django-solomon, you need to configure your Django project to use it:
59
+
60
+ ### 1. Add to INSTALLED_APPS
61
+
62
+ Add `django_solomon` to your `INSTALLED_APPS` in your Django settings:
63
+
64
+ ```python
65
+ INSTALLED_APPS = [
66
+ # ...
67
+ 'django_solomon',
68
+ # ...
69
+ ]
70
+ ```
71
+
72
+ ### 2. Configure Authentication Backend
73
+
74
+ Add the authentication backend to your settings:
75
+
76
+ ```python
77
+ AUTHENTICATION_BACKENDS = [
78
+ 'django_solomon.backends.MagicLinkBackend',
79
+ 'django.contrib.auth.backends.ModelBackend', # Keep the default backend
80
+ ]
81
+ ```
82
+
83
+ ### 3. Include URLs
84
+
85
+ Include the django-solomon URLs in your project's `urls.py`:
86
+
87
+ ```python
88
+ from django.urls import include, path
89
+
90
+ urlpatterns = [
91
+ # ...
92
+ path('auth/', include('django_solomon.urls')),
93
+ # ...
94
+ ]
95
+ ```
96
+
97
+ ### 4. Set Login URL
98
+
99
+ Set the login URL in your settings to use django-solomon's login view:
100
+
101
+ ```python
102
+ LOGIN_URL = 'django_solomon:login'
103
+ ```
104
+
105
+ This ensures that when users need to authenticate, they'll be redirected to the magic link login page.
106
+
107
+ ### 5. Configure Email Settings
108
+
109
+ Configure your email settings to ensure magic link emails can be sent:
110
+
111
+ ```python
112
+ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
113
+ EMAIL_HOST = 'smtp.example.com'
114
+ EMAIL_PORT = 587
115
+ EMAIL_USE_TLS = True
116
+ EMAIL_HOST_USER = 'your-email@example.com'
117
+ EMAIL_HOST_PASSWORD = 'your-password'
118
+ DEFAULT_FROM_EMAIL = 'your-email@example.com'
119
+ ```
120
+
121
+ For development, you can use Django's console email backend to display emails in the console:
122
+
123
+ ```python
124
+ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
125
+ ```
126
+
127
+ ## Customizing Settings
128
+
129
+ django-solomon provides several settings that you can customize in your Django settings file. For a comprehensive list of all available settings and their detailed descriptions, please refer to the [Settings documentation](settings.md).
130
+
131
+ ## Verifying Installation
132
+
133
+ To verify that django-solomon is correctly installed and configured:
134
+
135
+ 1. Start your Django development server:
136
+ ```bash
137
+ python manage.py runserver
138
+ ```
139
+
140
+ 2. Navigate to the login URL (e.g., `http://localhost:8000/auth/magic-link/`)
141
+
142
+ 3. Enter an email address and request a magic link
143
+
144
+ 4. Check that the magic link is sent (in the console if using the console email backend)
145
+
146
+ 5. Click the magic link to authenticate
147
+
148
+ ## Troubleshooting
149
+
150
+ ### Magic Links Not Being Sent
151
+
152
+ - Check your email configuration settings
153
+ - Ensure your SMTP server is accessible
154
+ - Try using the console email backend for testing
155
+
156
+ ### Authentication Not Working
157
+
158
+ - Verify that the MagicLinkBackend is in your AUTHENTICATION_BACKENDS
159
+ - Check that the URLs are correctly included in your urls.py
160
+ - Ensure the magic link hasn't expired or been used already
161
+
162
+ ### Template Errors
163
+
164
+ - Make sure django_solomon is in your INSTALLED_APPS
165
+ - Check that you're not overriding templates incorrectly
166
+ - Verify that your custom templates extend the correct base templates
167
+
168
+ ## Next Steps
169
+
170
+ Now that you have django-solomon installed and configured, you can:
171
+
172
+ - Customize the templates to match your site's design
173
+ - Integrate the magic link login with your existing authentication flow
174
+ - Explore the programmatic API for advanced usage
@@ -0,0 +1,180 @@
1
+ ---
2
+ hide:
3
+ - navigation
4
+ ---
5
+
6
+ # Settings
7
+
8
+ This guide provides detailed information about all the configurable settings in django-solomon.
9
+
10
+ ## Overview
11
+
12
+ django-solomon provides several settings that you can customize in your Django settings file. These settings control various aspects of the magic link authentication system, including link expiration, user creation, templates, and more.
13
+
14
+ ## Core Settings
15
+
16
+ ### SOLOMON_LINK_EXPIRATION
17
+
18
+ **Default:** `300` (seconds)
19
+
20
+ The expiration time for magic links in seconds. After this time has elapsed, the link will no longer be valid.
21
+
22
+ ```python
23
+ # Set magic links to expire after 10 minutes (600 seconds)
24
+ SOLOMON_LINK_EXPIRATION = 600
25
+ ```
26
+
27
+ ### SOLOMON_ONLY_ONE_LINK_ALLOWED
28
+
29
+ **Default:** `True`
30
+
31
+ If enabled, only one active magic link is allowed per user. When a new magic link is requested, any existing active links for the same user will be marked as used.
32
+
33
+ ```python
34
+ # Allow multiple active magic links per user
35
+ SOLOMON_ONLY_ONE_LINK_ALLOWED = False
36
+ ```
37
+
38
+ ### SOLOMON_CREATE_USER_IF_NOT_FOUND
39
+
40
+ **Default:** `False`
41
+
42
+ If enabled, creates a new user when a magic link is requested for a non-existent email address.
43
+
44
+ ```python
45
+ # Automatically create new users when they request a magic link
46
+ SOLOMON_CREATE_USER_IF_NOT_FOUND = True
47
+ ```
48
+
49
+ ### SOLOMON_LOGIN_REDIRECT_URL
50
+
51
+ **Default:** `settings.LOGIN_REDIRECT_URL`
52
+
53
+ The URL to redirect to after successful authentication with a magic link.
54
+
55
+ ```python
56
+ # Redirect to the dashboard after successful authentication
57
+ SOLOMON_LOGIN_REDIRECT_URL = '/dashboard/'
58
+ ```
59
+
60
+ ## Permission Settings
61
+
62
+ ### SOLOMON_ALLOW_ADMIN_LOGIN
63
+
64
+ **Default:** `True`
65
+
66
+ If enabled, allows superusers (admin users) to log in using magic links. If disabled, superusers will need to use the standard Django admin login.
67
+
68
+ ```python
69
+ # Disable magic link authentication for superusers
70
+ SOLOMON_ALLOW_ADMIN_LOGIN = False
71
+ ```
72
+
73
+ ### SOLOMON_ALLOW_STAFF_LOGIN
74
+
75
+ **Default:** `True`
76
+
77
+ If enabled, allows staff users to log in using magic links. If disabled, staff users will need to use the standard Django admin login.
78
+
79
+ ```python
80
+ # Disable magic link authentication for staff users
81
+ SOLOMON_ALLOW_STAFF_LOGIN = False
82
+ ```
83
+
84
+ ## Template Settings
85
+
86
+ django-solomon uses several templates for rendering emails and pages. You can customize these templates by providing your own versions.
87
+
88
+ ### SOLOMON_MAIL_TEXT_TEMPLATE
89
+
90
+ **Default:** `"django_solomon/email/magic_link.txt"`
91
+
92
+ The template to use for plain text magic link emails.
93
+
94
+ ```python
95
+ # Use a custom plain text email template
96
+ SOLOMON_MAIL_TEXT_TEMPLATE = "myapp/emails/magic_link.txt"
97
+ ```
98
+
99
+ ### SOLOMON_MAIL_MJML_TEMPLATE
100
+
101
+ **Default:** `"django_solomon/email/magic_link.mjml"`
102
+
103
+ The template to use for HTML magic link emails (MJML format). django-solomon uses MJML for creating responsive HTML emails.
104
+
105
+ ```python
106
+ # Use a custom MJML email template
107
+ SOLOMON_MAIL_MJML_TEMPLATE = "myapp/emails/magic_link.mjml"
108
+ ```
109
+
110
+ ### SOLOMON_LOGIN_FORM_TEMPLATE
111
+
112
+ **Default:** `"django_solomon/base/login_form.html"`
113
+
114
+ The template to use for the login form page.
115
+
116
+ ```python
117
+ # Use a custom login form template
118
+ SOLOMON_LOGIN_FORM_TEMPLATE = "myapp/auth/login_form.html"
119
+ ```
120
+
121
+ ### SOLOMON_INVALID_MAGIC_LINK_TEMPLATE
122
+
123
+ **Default:** `"django_solomon/base/invalid_magic_link.html"`
124
+
125
+ The template to use for the invalid magic link page, which is shown when a user tries to use an expired or already used magic link.
126
+
127
+ ```python
128
+ # Use a custom invalid magic link template
129
+ SOLOMON_INVALID_MAGIC_LINK_TEMPLATE = "myapp/auth/invalid_link.html"
130
+ ```
131
+
132
+ ### SOLOMON_MAGIC_LINK_SENT_TEMPLATE
133
+
134
+ **Default:** `"django_solomon/base/magic_link_sent.html"`
135
+
136
+ The template to use for the magic link sent confirmation page, which is shown after a user requests a magic link.
137
+
138
+ ```python
139
+ # Use a custom magic link sent template
140
+ SOLOMON_MAGIC_LINK_SENT_TEMPLATE = "myapp/auth/link_sent.html"
141
+ ```
142
+
143
+ ## Email Settings
144
+
145
+ django-solomon uses Django's email system to send magic links. You should configure Django's email settings in your settings file:
146
+
147
+ ```python
148
+ # Example email configuration for Gmail
149
+ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
150
+ EMAIL_HOST = 'smtp.gmail.com'
151
+ EMAIL_PORT = 587
152
+ EMAIL_USE_TLS = True
153
+ EMAIL_HOST_USER = 'your-email@gmail.com'
154
+ EMAIL_HOST_PASSWORD = 'your-app-password'
155
+ DEFAULT_FROM_EMAIL = 'your-email@gmail.com'
156
+ ```
157
+
158
+ For development, you can use Django's console email backend to display emails in the console:
159
+
160
+ ```python
161
+ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
162
+ ```
163
+
164
+ ## Settings Summary
165
+
166
+ Here's a summary of all available settings:
167
+
168
+ | Setting | Default | Description |
169
+ |---------------------------------------|-------------------------------------------------|----------------------------------------------------------------------------------------|
170
+ | `SOLOMON_LINK_EXPIRATION` | `300` | The expiration time for magic links in seconds |
171
+ | `SOLOMON_ONLY_ONE_LINK_ALLOWED` | `True` | If enabled, only one active magic link is allowed per user |
172
+ | `SOLOMON_CREATE_USER_IF_NOT_FOUND` | `False` | If enabled, creates a new user when a magic link is requested for a non-existent email |
173
+ | `SOLOMON_LOGIN_REDIRECT_URL` | `settings.LOGIN_REDIRECT_URL` | The URL to redirect to after successful authentication |
174
+ | `SOLOMON_ALLOW_ADMIN_LOGIN` | `True` | If enabled, allows superusers to log in using magic links |
175
+ | `SOLOMON_ALLOW_STAFF_LOGIN` | `True` | If enabled, allows staff users to log in using magic links |
176
+ | `SOLOMON_MAIL_TEXT_TEMPLATE` | `"django_solomon/email/magic_link.txt"` | The template to use for plain text magic link emails |
177
+ | `SOLOMON_MAIL_MJML_TEMPLATE` | `"django_solomon/email/magic_link.mjml"` | The template to use for HTML magic link emails (MJML format) |
178
+ | `SOLOMON_LOGIN_FORM_TEMPLATE` | `"django_solomon/base/login_form.html"` | The template to use for the login form page |
179
+ | `SOLOMON_INVALID_MAGIC_LINK_TEMPLATE` | `"django_solomon/base/invalid_magic_link.html"` | The template to use for the invalid magic link page |
180
+ | `SOLOMON_MAGIC_LINK_SENT_TEMPLATE` | `"django_solomon/base/magic_link_sent.html"` | The template to use for the magic link sent confirmation page |
@@ -0,0 +1,256 @@
1
+ ---
2
+ hide:
3
+ - navigation
4
+ ---
5
+
6
+ # Templates
7
+
8
+ This guide provides detailed information about all the templates used in django-solomon and the context variables
9
+ available in each template.
10
+
11
+ ## Overview
12
+
13
+ django-solomon uses several templates for rendering emails and pages. You can customize these templates by providing
14
+ your own versions or by specifying custom templates using the settings variables.
15
+
16
+ ## HTML Templates
17
+
18
+ ### Login Form Template
19
+
20
+ **Default Path:** `django_solomon/base/login_form.html`
21
+
22
+ **Settings Variable:** `SOLOMON_LOGIN_FORM_TEMPLATE`
23
+
24
+ **Description:** This template renders the form for requesting a magic link.
25
+
26
+ **Context Variables:**
27
+
28
+ - `form`: The MagicLinkForm instance that contains the email field.
29
+
30
+ **Example Usage:**
31
+
32
+ ```html
33
+ {% extends "base.html" %}
34
+ {% load i18n %}
35
+
36
+ {% block title %}{% translate "Magic Link Login" %}{% endblock %}
37
+
38
+ {% block content %}
39
+ <div class="container">
40
+ <h1>{% translate "Magic Link Login" %}</h1>
41
+ <p>{% translate "Enter your email address to receive a magic link for logging in." %}</p>
42
+
43
+ <form method="post">
44
+ {% csrf_token %}
45
+ {{ form.as_p }}
46
+ <button type="submit" class="btn btn-primary">{% translate "Send Magic Link" %}</button>
47
+ </form>
48
+ </div>
49
+ {% endblock content %}
50
+ ```
51
+
52
+ ### Magic Link Sent Template
53
+
54
+ **Default Path:** `django_solomon/base/magic_link_sent.html`
55
+
56
+ **Settings Variable:** `SOLOMON_MAGIC_LINK_SENT_TEMPLATE`
57
+
58
+ **Description:** This template is displayed after a user requests a magic link, confirming that the link has been sent.
59
+
60
+ **Context Variables:**
61
+
62
+ - No specific context variables are passed to this template.
63
+
64
+ **Example Usage:**
65
+
66
+ ```html
67
+ {% extends "base.html" %}
68
+ {% load i18n %}
69
+
70
+ {% block title %}{% translate "Magic Link Sent" %}{% endblock %}
71
+
72
+ {% block content %}
73
+ <div class="container">
74
+ <h1>{% translate "Magic Link Sent" %}</h1>
75
+ <p>{% translate "If an account exists with the email address you provided, we've sent a magic link to that address."
76
+ %}</p>
77
+ <p>{% translate "Please check your email and click the link to log in." %}</p>
78
+ </div>
79
+ {% endblock content %}
80
+ ```
81
+
82
+ ### Invalid Magic Link Template
83
+
84
+ **Default Path:** `django_solomon/base/invalid_magic_link.html`
85
+
86
+ **Settings Variable:** `SOLOMON_INVALID_MAGIC_LINK_TEMPLATE`
87
+
88
+ **Description:** This template is displayed when a user clicks on an invalid or expired magic link.
89
+
90
+ **Context Variables:**
91
+
92
+ - `error`: A string containing the error message explaining why the magic link is invalid.
93
+
94
+ **Example Usage:**
95
+
96
+ ```html
97
+ {% extends "base.html" %}
98
+ {% load i18n %}
99
+
100
+ {% block title %}{% translate "Invalid Magic Link" %}{% endblock %}
101
+
102
+ {% block content %}
103
+ <div class="container">
104
+ <h1>{% translate "Invalid Magic Link" %}</h1>
105
+ <p>{{ error }}</p>
106
+ <p>{% translate "Please request a new magic link to log in." %}</p>
107
+
108
+ <a href="{% url 'django_solomon:login' %}" class="btn btn-primary">
109
+ {% translate "Request New Magic Link" %}
110
+ </a>
111
+ </div>
112
+ {% endblock content %}
113
+ ```
114
+
115
+ ## Email Templates
116
+
117
+ django-solomon uses two types of email templates: a plain text template and an MJML template for HTML emails.
118
+
119
+ ### Plain Text Email Template
120
+
121
+ **Default Path:** `django_solomon/email/magic_link.txt`
122
+
123
+ **Settings Variable:** `SOLOMON_MAIL_TEXT_TEMPLATE`
124
+
125
+ **Description:** This template is used to generate the plain text version of the magic link email.
126
+
127
+ **Context Variables:**
128
+
129
+ - `magic_link_url`: The absolute URL of the magic link that the user needs to click.
130
+ - `expiry_time`: The expiration time of the magic link in minutes.
131
+
132
+ **Example Usage:**
133
+
134
+ ```
135
+ {% load i18n %}
136
+ {% translate "Hello," %}
137
+
138
+ {% translate "You requested a magic link to log in to your account. Please click the link below to log in:" %}
139
+
140
+ {{ magic_link_url }}
141
+
142
+ {% blocktranslate with expiry_time=expiry_time %}This link will expire in {{ expiry_time }} minutes. If you did not request this link, you can safely ignore this email.{% endblocktranslate %}
143
+
144
+ {% translate "Thank you," %}
145
+ {% translate "The Django Solomon Team" %}
146
+
147
+ ---
148
+ {% translate "This email was sent by Django Solomon." %}
149
+ ```
150
+
151
+ ### MJML Email Template
152
+
153
+ **Default Path:** `django_solomon/email/magic_link.mjml`
154
+
155
+ **Settings Variable:** `SOLOMON_MAIL_MJML_TEMPLATE`
156
+
157
+ **Description:** This template is used to generate the HTML version of the magic link email using MJML, which ensures
158
+ responsive emails across different email clients. For more information about MJML syntax and components, see the [MJML documentation](https://mjml.io/documentation/).
159
+
160
+ **Context Variables:**
161
+
162
+ - `magic_link_url`: The absolute URL of the magic link that the user needs to click.
163
+ - `expiry_time`: The expiration time of the magic link in minutes.
164
+
165
+ **Example Usage:**
166
+
167
+ ```html
168
+ {% load i18n %}
169
+ <mjml>
170
+ <mj-body>
171
+ <mj-section>
172
+ <mj-column>
173
+ <mj-text>
174
+ <p>{% translate "Hello," %}</p>
175
+
176
+ <p>
177
+ {% blocktranslate %}
178
+ You requested a magic link to log in to your account. Please click the link below
179
+ to log in:
180
+ {% endblocktranslate %}
181
+ </p>
182
+ </mj-text>
183
+
184
+ <mj-button href="{{ magic_link_url }}">{% translate "Click here to log in" %}</mj-button>
185
+
186
+ <mj-text>
187
+ <p>
188
+ {% blocktranslate with expiry_time=expiry_time %}
189
+ This link will expire in {{ expiry_time }} minutes. If you did not
190
+ request this link, you can safely ignore this email.
191
+ {% endblocktranslate %}
192
+ </p>
193
+
194
+ <p>
195
+ {% translate "Thank you," %}
196
+ <br>
197
+ {% translate "The Django Solomon Team" %}
198
+ </p>
199
+
200
+ <p>
201
+ ---
202
+ <br>
203
+ {% translate "This email was sent by Django Solomon." %}
204
+ </p>
205
+ </mj-text>
206
+ </mj-column>
207
+ </mj-section>
208
+ </mj-body>
209
+ </mjml>
210
+ ```
211
+
212
+ ## Customizing Templates
213
+
214
+ You can customize the templates in two ways:
215
+
216
+ 1. **Override the default templates**: Create your own templates with the same paths in your project's templates
217
+ directory.
218
+
219
+ 2. **Specify custom templates in settings**: Use the settings variables to specify the paths to your custom templates.
220
+
221
+ ### Example: Overriding the Default Templates
222
+
223
+ Create the following directory structure in your project:
224
+
225
+ ```
226
+ templates/
227
+ └── django_solomon/
228
+ ├── base/
229
+ │ ├── login_form.html
230
+ │ ├── magic_link_sent.html
231
+ │ └── invalid_magic_link.html
232
+ └── email/
233
+ ├── magic_link.txt
234
+ └── magic_link.mjml
235
+ ```
236
+
237
+ ### Example: Specifying Custom Templates in Settings
238
+
239
+ ```python
240
+ # In your settings.py file
241
+ SOLOMON_LOGIN_FORM_TEMPLATE = "myapp/auth/login_form.html"
242
+ SOLOMON_MAGIC_LINK_SENT_TEMPLATE = "myapp/auth/link_sent.html"
243
+ SOLOMON_INVALID_MAGIC_LINK_TEMPLATE = "myapp/auth/invalid_link.html"
244
+ SOLOMON_MAIL_TEXT_TEMPLATE = "myapp/emails/magic_link.txt"
245
+ SOLOMON_MAIL_MJML_TEMPLATE = "myapp/emails/magic_link.mjml"
246
+ ```
247
+
248
+ ## Base Template Requirements
249
+
250
+ All the HTML templates extend a `base.html` template, which should be provided by your project. The base template should
251
+ define at least the following blocks:
252
+
253
+ - `title`: Used for the page title
254
+ - `content`: Used for the main content of the page
255
+
256
+ If your base template uses different block names, you'll need to modify the django-solomon templates accordingly.
@@ -1,5 +1,5 @@
1
- set export
2
- set dotenv-load
1
+ set export := true
2
+ set dotenv-load := true
3
3
 
4
4
  VENV_DIRNAME := ".venv"
5
5
 
@@ -46,7 +46,7 @@ VENV_DIRNAME := ".venv"
46
46
 
47
47
  # run test suite
48
48
  @test: check_uv
49
- uv run pytest --cov --cov-report=html --cov-report=term
49
+ uv run pytest --cov --cov-report=html --cov-report=term -n auto
50
50
 
51
51
  # run test suite
52
52
  @test-all: check_uv
@@ -26,6 +26,10 @@ theme:
26
26
  - content.code.copy
27
27
  nav:
28
28
  - Home: "index.md"
29
+ - Installation: "installation.md"
30
+ - Settings: "settings.md"
31
+ - Templates: "templates.md"
32
+ - Contributing: "contributing.md"
29
33
  - Changelog: "changelog.md"
30
34
  markdown_extensions:
31
35
  - def_list
@@ -42,6 +42,7 @@ dev = [
42
42
  "pytest-randomly>=3.15.0",
43
43
  "pytest>=8.3.3",
44
44
  "django-stubs[compatible-mypy]>=5.1.1",
45
+ "pytest-xdist>=3.6.1",
45
46
  ]
46
47
 
47
48
  [build-system]
@@ -15,6 +15,7 @@ deps =
15
15
  pytest
16
16
  pytest-mock
17
17
  pytest-django
18
+ pytest-xdist
18
19
  django40: Django>=4.0,<4.1
19
20
  django41: Django>=4.1,<4.2
20
21
  django42: Django>=4.2,<5.0
@@ -22,4 +23,4 @@ deps =
22
23
  django51: Django>=5.1,<5.2
23
24
  django52: Django>=5.2,<5.3
24
25
  commands =
25
- pytest
26
+ pytest -n auto
@@ -118,6 +118,7 @@ dev = [
118
118
  { name = "pytest-django" },
119
119
  { name = "pytest-mock" },
120
120
  { name = "pytest-randomly" },
121
+ { name = "pytest-xdist" },
121
122
  ]
122
123
 
123
124
  [package.metadata]
@@ -134,6 +135,7 @@ dev = [
134
135
  { name = "pytest-django", specifier = ">=4.9.0" },
135
136
  { name = "pytest-mock", specifier = ">=3.14.0" },
136
137
  { name = "pytest-randomly", specifier = ">=3.15.0" },
138
+ { name = "pytest-xdist", specifier = ">=3.6.1" },
137
139
  ]
138
140
 
139
141
  [[package]]
@@ -180,6 +182,15 @@ wheels = [
180
182
  { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
181
183
  ]
182
184
 
185
+ [[package]]
186
+ name = "execnet"
187
+ version = "2.1.1"
188
+ source = { registry = "https://pypi.org/simple" }
189
+ sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524 }
190
+ wheels = [
191
+ { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612 },
192
+ ]
193
+
183
194
  [[package]]
184
195
  name = "iniconfig"
185
196
  version = "2.1.0"
@@ -334,6 +345,19 @@ wheels = [
334
345
  { url = "https://files.pythonhosted.org/packages/22/70/b31577d7c46d8e2f9baccfed5067dd8475262a2331ffb0bfdf19361c9bde/pytest_randomly-3.16.0-py3-none-any.whl", hash = "sha256:8633d332635a1a0983d3bba19342196807f6afb17c3eef78e02c2f85dade45d6", size = 8396 },
335
346
  ]
336
347
 
348
+ [[package]]
349
+ name = "pytest-xdist"
350
+ version = "3.6.1"
351
+ source = { registry = "https://pypi.org/simple" }
352
+ dependencies = [
353
+ { name = "execnet" },
354
+ { name = "pytest" },
355
+ ]
356
+ sdist = { url = "https://files.pythonhosted.org/packages/41/c4/3c310a19bc1f1e9ef50075582652673ef2bfc8cd62afef9585683821902f/pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d", size = 84060 }
357
+ wheels = [
358
+ { url = "https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", size = 46108 },
359
+ ]
360
+
337
361
  [[package]]
338
362
  name = "sqlparse"
339
363
  version = "0.5.3"
@@ -1 +0,0 @@
1
- # Changelog
File without changes