aa-srp-access 0.1.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 (32) hide show
  1. aa_srp_access-0.1.0/.github/workflows/release.yml +40 -0
  2. aa_srp_access-0.1.0/.github/workflows/tests.yml +38 -0
  3. aa_srp_access-0.1.0/.gitignore +10 -0
  4. aa_srp_access-0.1.0/CHANGELOG.md +13 -0
  5. aa_srp_access-0.1.0/LICENSE +21 -0
  6. aa_srp_access-0.1.0/PKG-INFO +214 -0
  7. aa_srp_access-0.1.0/README.md +164 -0
  8. aa_srp_access-0.1.0/pyproject.toml +58 -0
  9. aa_srp_access-0.1.0/srp_access/__init__.py +3 -0
  10. aa_srp_access-0.1.0/srp_access/access.py +79 -0
  11. aa_srp_access-0.1.0/srp_access/admin.py +39 -0
  12. aa_srp_access-0.1.0/srp_access/apps.py +8 -0
  13. aa_srp_access-0.1.0/srp_access/auth_hooks.py +33 -0
  14. aa_srp_access-0.1.0/srp_access/forms.py +5 -0
  15. aa_srp_access-0.1.0/srp_access/migrations/0001_initial.py +77 -0
  16. aa_srp_access-0.1.0/srp_access/migrations/0002_alter_exposedsrpfleet_fleet_and_more.py +37 -0
  17. aa_srp_access-0.1.0/srp_access/migrations/__init__.py +1 -0
  18. aa_srp_access-0.1.0/srp_access/models.py +56 -0
  19. aa_srp_access-0.1.0/srp_access/services.py +65 -0
  20. aa_srp_access-0.1.0/srp_access/static/srp_access/css/srp_access.css +1 -0
  21. aa_srp_access-0.1.0/srp_access/templates/srp_access/fleet_detail.html +27 -0
  22. aa_srp_access-0.1.0/srp_access/templates/srp_access/fleet_list.html +45 -0
  23. aa_srp_access-0.1.0/srp_access/templates/srp_access/request.html +20 -0
  24. aa_srp_access-0.1.0/srp_access/tests/__init__.py +1 -0
  25. aa_srp_access-0.1.0/srp_access/tests/test_access.py +68 -0
  26. aa_srp_access-0.1.0/srp_access/tests/test_views.py +150 -0
  27. aa_srp_access-0.1.0/srp_access/urls.py +11 -0
  28. aa_srp_access-0.1.0/srp_access/views.py +61 -0
  29. aa_srp_access-0.1.0/testauth/__init__.py +1 -0
  30. aa_srp_access-0.1.0/testauth/manage.py +10 -0
  31. aa_srp_access-0.1.0/testauth/settings.py +33 -0
  32. aa_srp_access-0.1.0/testauth/urls.py +5 -0
@@ -0,0 +1,40 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: "3.12"
15
+ - name: Install build tools
16
+ run: python -m pip install --upgrade build twine
17
+ - name: Build distributions
18
+ run: python -m build
19
+ - name: Validate distributions
20
+ run: python -m twine check dist/*
21
+ - uses: actions/upload-artifact@v4
22
+ with:
23
+ name: python-package-distributions
24
+ path: dist/
25
+
26
+ publish:
27
+ needs: build
28
+ runs-on: ubuntu-latest
29
+ environment:
30
+ name: pypi
31
+ url: https://pypi.org/p/aa-srp-access
32
+ permissions:
33
+ id-token: write
34
+ steps:
35
+ - uses: actions/download-artifact@v4
36
+ with:
37
+ name: python-package-distributions
38
+ path: dist/
39
+ - name: Publish to PyPI with Trusted Publishing
40
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,38 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ services:
11
+ redis:
12
+ image: redis:7
13
+ ports:
14
+ - 6379:6379
15
+ options: >-
16
+ --health-cmd "redis-cli ping"
17
+ --health-interval 10s
18
+ --health-timeout 5s
19
+ --health-retries 5
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-python@v5
23
+ with:
24
+ python-version: "3.12"
25
+ cache: pip
26
+ - name: Install package and test tools
27
+ run: python -m pip install --upgrade pip ".[test]"
28
+ - name: Django checks and tests
29
+ env:
30
+ DJANGO_SETTINGS_MODULE: testauth.settings
31
+ run: |
32
+ python -m django check
33
+ python -m django makemigrations srp_access --check --dry-run
34
+ python -m django test srp_access.tests
35
+ - name: Build distributions
36
+ run: python -m build
37
+ - name: Validate distributions
38
+ run: python -m twine check dist/*
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.sqlite3
4
+ .coverage
5
+ .pytest_cache/
6
+ .venv/
7
+ build/
8
+ dist/
9
+ *.egg-info/
10
+ *.rej
@@ -0,0 +1,13 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The project follows
4
+ Semantic Versioning.
5
+
6
+ ## 0.1.0 - 2026-09-12
7
+
8
+ - Add configurable State and Group authorization.
9
+ - Add mappings for explicitly exposed built-in SRP fleets.
10
+ - Add restricted fleet list, detail, and request submission views.
11
+ - Store submissions as normal Alliance Auth built-in `SrpUserRequest` records.
12
+ - Add server-side direct URL protection, administration, tests, packaging, and
13
+ Trusted Publishing workflow.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 aa-srp-access contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,214 @@
1
+ Metadata-Version: 2.5
2
+ Name: aa-srp-access
3
+ Version: 0.1.0
4
+ Summary: Restricted, configurable access to Alliance Auth's built-in SRP
5
+ Project-URL: Homepage, https://github.com/thegriffenkd/aa-srp-access
6
+ Project-URL: Changelog, https://github.com/thegriffenkd/aa-srp-access/blob/main/CHANGELOG.md
7
+ Project-URL: Issues, https://github.com/thegriffenkd/aa-srp-access/issues
8
+ Project-URL: Source, https://github.com/thegriffenkd/aa-srp-access
9
+ Author: aa-srp-access contributors
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 aa-srp-access contributors
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Classifier: Development Status :: 3 - Alpha
33
+ Classifier: Environment :: Web Environment
34
+ Classifier: Framework :: Django :: 5.2
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Programming Language :: Python :: 3.13
41
+ Classifier: Programming Language :: Python :: 3.14
42
+ Classifier: Topic :: Internet :: WWW/HTTP
43
+ Requires-Python: <3.15,>=3.10
44
+ Requires-Dist: allianceauth<5.3,>=5.2
45
+ Requires-Dist: django-solo<3,>=2.5
46
+ Provides-Extra: test
47
+ Requires-Dist: build>=1.2; extra == 'test'
48
+ Requires-Dist: twine>=5; extra == 'test'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # aa-srp-access
52
+
53
+ `aa-srp-access` is a standalone Alliance Auth application that provides a
54
+ restricted frontend for Alliance Auth's built-in Ship Replacement Program
55
+ (SRP). It does not replace the built-in SRP backend or administration.
56
+
57
+ Restricted users can access the frontend only when both conditions are true:
58
+
59
+ - their Alliance Auth State is eligible; and
60
+ - they belong to the configured Django/Alliance Auth Group.
61
+
62
+ They see only built-in SRP fleets explicitly exposed by an administrator.
63
+ Requests are stored as normal built-in `SrpUserRequest` records, so existing
64
+ SRP administrators continue to approve, reject, update, and pay them through
65
+ the normal Alliance Auth SRP interface.
66
+
67
+ ## Compatibility
68
+
69
+ - Alliance Auth `5.2.x`
70
+ - Python `3.10` through `3.14`, matching Alliance Auth 5.2 metadata
71
+ - Django `5.2.x`, supplied by Alliance Auth
72
+
73
+ The initial compatibility target is Alliance Auth 5.2.0. Test upgrades before
74
+ changing either the Alliance Auth or app version constraint.
75
+
76
+ ## Security model
77
+
78
+ Every plugin view performs server-side authorization. Navigation visibility is
79
+ only a convenience and is not treated as access control. A submitted fleet ID
80
+ is re-queried through the authorized fleet queryset, and an unexposed fleet
81
+ returns a safe 404. Anonymous users are redirected to login; authenticated
82
+ users who fail the State or Group check receive 403.
83
+
84
+ State, Group, and fleet names are never authorization constants. Configuration
85
+ uses database relations to `authentication.State`, `auth.Group`, and the
86
+ built-in `srp.SrpFleetMain` model.
87
+
88
+ ## Requirements
89
+
90
+ - A working Alliance Auth 5.2 installation with built-in SRP enabled
91
+ - Django admin access
92
+ - The built-in `auth.srp_management` permission for app configuration
93
+
94
+ ## Installation
95
+
96
+ Add a pinned release to the Alliance Auth requirements file:
97
+
98
+ ```text
99
+ aa-srp-access==0.1.0
100
+ ```
101
+
102
+ Add the Python module to local settings:
103
+
104
+ ```python
105
+ INSTALLED_APPS += [
106
+ "srp_access",
107
+ ]
108
+ ```
109
+
110
+ Rebuild the application image, then run:
111
+
112
+ ```bash
113
+ python manage.py migrate srp_access
114
+ python manage.py collectstatic --noinput
115
+ ```
116
+
117
+ Restart the web, worker, and scheduler processes using the deployment's normal
118
+ procedure. No Alliance Auth core files or core migrations are changed.
119
+
120
+ ## Docker installation
121
+
122
+ Service names vary between deployments. From the correct Compose project
123
+ directory, the usual sequence is:
124
+
125
+ 1. Add `aa-srp-access==0.1.0` to `conf/requirements.txt`.
126
+ 2. Add `srp_access` to `INSTALLED_APPS` in local Django settings.
127
+ 3. Rebuild the Alliance Auth image with `docker compose build`.
128
+ 4. Run `docker compose run --rm <web-service> python manage.py migrate srp_access`.
129
+ 5. Run `docker compose run --rm <web-service> python manage.py collectstatic --noinput`.
130
+ 6. Recreate the web, workers, and beat/scheduler services.
131
+ 7. Verify container health and both the standard and restricted SRP pages.
132
+
133
+ Back up the database and configuration first. Determine the correct Compose
134
+ project and service names before running commands; do not copy the examples
135
+ blindly into a production deployment.
136
+
137
+ ## Initial configuration
138
+
139
+ 1. Sign in to Django admin as a staff user with `auth.srp_management`.
140
+ 2. Open **Restricted SRP settings**.
141
+ 3. Select the required access Group.
142
+ 4. Choose State behavior:
143
+ - enable **allow any public state** to require `State.public=True`; or
144
+ - disable it and select one or more specific State objects.
145
+ 5. Add **Exposed SRP fleet** rows for existing built-in SRP fleets.
146
+ 6. Leave an exposure enabled only while that fleet should be available.
147
+
148
+ An exposed fleet must also be open in built-in SRP: it needs a non-empty SRP
149
+ code and an incomplete status. Disabling or completing it in built-in SRP
150
+ removes it from the restricted list without deleting the exposure mapping.
151
+
152
+ ## Permissions and groups
153
+
154
+ The access Group is application data selected in admin; its name is not fixed.
155
+ State eligibility and Group membership are both mandatory. Superuser or staff
156
+ status does not bypass the restricted frontend's State-and-Group rule.
157
+
158
+ Configuration in Django admin is guarded by Alliance Auth's existing
159
+ `auth.srp_management` permission. Normal built-in SRP permissions and pages are
160
+ not modified.
161
+
162
+ ## How to expose fleets
163
+
164
+ Create fleets through the normal built-in SRP interface. In Django admin, add
165
+ an **Exposed SRP fleet** mapping and select the existing fleet object. The
166
+ one-to-one relation prevents duplicate mappings. Removing a built-in fleet also
167
+ removes its exposure mapping; it does not affect unrelated SRP data.
168
+
169
+ ## Upgrading
170
+
171
+ 1. Back up the Alliance Auth database and configuration.
172
+ 2. Pin the desired `aa-srp-access` version in requirements.
173
+ 3. Rebuild the image.
174
+ 4. Run `python manage.py migrate srp_access`.
175
+ 5. Run `collectstatic` when release notes require it.
176
+ 6. Recreate services and verify both SRP frontends.
177
+
178
+ Test Alliance Auth upgrades on a test server with the currently pinned plugin
179
+ version before upgrading production.
180
+
181
+ ## Uninstall considerations
182
+
183
+ Removing the app does not remove built-in SRP fleets or requests. Plugin-owned
184
+ settings and exposure mappings remain in the database unless their tables are
185
+ explicitly removed. Back up first; do not reverse migrations casually on a
186
+ production installation. Remove `srp_access` from `INSTALLED_APPS` only after
187
+ planning whether to retain or remove those plugin tables.
188
+
189
+ ## Development and testing
190
+
191
+ Run tests against a Redis instance on localhost database 15:
192
+
193
+ ```bash
194
+ python -m django test srp_access.tests --settings=testauth.settings
195
+ ```
196
+
197
+ Build and validate distributions:
198
+
199
+ ```bash
200
+ python -m pip install --upgrade build twine
201
+ python -m build
202
+ python -m twine check dist/*
203
+ ```
204
+
205
+ The test suite uses SQLite and arbitrary fixture names. It covers anonymous,
206
+ State, Group, exposed-fleet, direct URL, submission, built-in SRP regression,
207
+ and built-in administrator behavior.
208
+
209
+ ## Release process
210
+
211
+ Update the changelog and version, merge tested changes, and create a deliberate
212
+ GitHub Release. The release workflow builds and validates wheel/sdist artifacts
213
+ before publishing through a PyPI Trusted Publisher and the protected `pypi`
214
+ GitHub environment. Ordinary pushes never publish.
@@ -0,0 +1,164 @@
1
+ # aa-srp-access
2
+
3
+ `aa-srp-access` is a standalone Alliance Auth application that provides a
4
+ restricted frontend for Alliance Auth's built-in Ship Replacement Program
5
+ (SRP). It does not replace the built-in SRP backend or administration.
6
+
7
+ Restricted users can access the frontend only when both conditions are true:
8
+
9
+ - their Alliance Auth State is eligible; and
10
+ - they belong to the configured Django/Alliance Auth Group.
11
+
12
+ They see only built-in SRP fleets explicitly exposed by an administrator.
13
+ Requests are stored as normal built-in `SrpUserRequest` records, so existing
14
+ SRP administrators continue to approve, reject, update, and pay them through
15
+ the normal Alliance Auth SRP interface.
16
+
17
+ ## Compatibility
18
+
19
+ - Alliance Auth `5.2.x`
20
+ - Python `3.10` through `3.14`, matching Alliance Auth 5.2 metadata
21
+ - Django `5.2.x`, supplied by Alliance Auth
22
+
23
+ The initial compatibility target is Alliance Auth 5.2.0. Test upgrades before
24
+ changing either the Alliance Auth or app version constraint.
25
+
26
+ ## Security model
27
+
28
+ Every plugin view performs server-side authorization. Navigation visibility is
29
+ only a convenience and is not treated as access control. A submitted fleet ID
30
+ is re-queried through the authorized fleet queryset, and an unexposed fleet
31
+ returns a safe 404. Anonymous users are redirected to login; authenticated
32
+ users who fail the State or Group check receive 403.
33
+
34
+ State, Group, and fleet names are never authorization constants. Configuration
35
+ uses database relations to `authentication.State`, `auth.Group`, and the
36
+ built-in `srp.SrpFleetMain` model.
37
+
38
+ ## Requirements
39
+
40
+ - A working Alliance Auth 5.2 installation with built-in SRP enabled
41
+ - Django admin access
42
+ - The built-in `auth.srp_management` permission for app configuration
43
+
44
+ ## Installation
45
+
46
+ Add a pinned release to the Alliance Auth requirements file:
47
+
48
+ ```text
49
+ aa-srp-access==0.1.0
50
+ ```
51
+
52
+ Add the Python module to local settings:
53
+
54
+ ```python
55
+ INSTALLED_APPS += [
56
+ "srp_access",
57
+ ]
58
+ ```
59
+
60
+ Rebuild the application image, then run:
61
+
62
+ ```bash
63
+ python manage.py migrate srp_access
64
+ python manage.py collectstatic --noinput
65
+ ```
66
+
67
+ Restart the web, worker, and scheduler processes using the deployment's normal
68
+ procedure. No Alliance Auth core files or core migrations are changed.
69
+
70
+ ## Docker installation
71
+
72
+ Service names vary between deployments. From the correct Compose project
73
+ directory, the usual sequence is:
74
+
75
+ 1. Add `aa-srp-access==0.1.0` to `conf/requirements.txt`.
76
+ 2. Add `srp_access` to `INSTALLED_APPS` in local Django settings.
77
+ 3. Rebuild the Alliance Auth image with `docker compose build`.
78
+ 4. Run `docker compose run --rm <web-service> python manage.py migrate srp_access`.
79
+ 5. Run `docker compose run --rm <web-service> python manage.py collectstatic --noinput`.
80
+ 6. Recreate the web, workers, and beat/scheduler services.
81
+ 7. Verify container health and both the standard and restricted SRP pages.
82
+
83
+ Back up the database and configuration first. Determine the correct Compose
84
+ project and service names before running commands; do not copy the examples
85
+ blindly into a production deployment.
86
+
87
+ ## Initial configuration
88
+
89
+ 1. Sign in to Django admin as a staff user with `auth.srp_management`.
90
+ 2. Open **Restricted SRP settings**.
91
+ 3. Select the required access Group.
92
+ 4. Choose State behavior:
93
+ - enable **allow any public state** to require `State.public=True`; or
94
+ - disable it and select one or more specific State objects.
95
+ 5. Add **Exposed SRP fleet** rows for existing built-in SRP fleets.
96
+ 6. Leave an exposure enabled only while that fleet should be available.
97
+
98
+ An exposed fleet must also be open in built-in SRP: it needs a non-empty SRP
99
+ code and an incomplete status. Disabling or completing it in built-in SRP
100
+ removes it from the restricted list without deleting the exposure mapping.
101
+
102
+ ## Permissions and groups
103
+
104
+ The access Group is application data selected in admin; its name is not fixed.
105
+ State eligibility and Group membership are both mandatory. Superuser or staff
106
+ status does not bypass the restricted frontend's State-and-Group rule.
107
+
108
+ Configuration in Django admin is guarded by Alliance Auth's existing
109
+ `auth.srp_management` permission. Normal built-in SRP permissions and pages are
110
+ not modified.
111
+
112
+ ## How to expose fleets
113
+
114
+ Create fleets through the normal built-in SRP interface. In Django admin, add
115
+ an **Exposed SRP fleet** mapping and select the existing fleet object. The
116
+ one-to-one relation prevents duplicate mappings. Removing a built-in fleet also
117
+ removes its exposure mapping; it does not affect unrelated SRP data.
118
+
119
+ ## Upgrading
120
+
121
+ 1. Back up the Alliance Auth database and configuration.
122
+ 2. Pin the desired `aa-srp-access` version in requirements.
123
+ 3. Rebuild the image.
124
+ 4. Run `python manage.py migrate srp_access`.
125
+ 5. Run `collectstatic` when release notes require it.
126
+ 6. Recreate services and verify both SRP frontends.
127
+
128
+ Test Alliance Auth upgrades on a test server with the currently pinned plugin
129
+ version before upgrading production.
130
+
131
+ ## Uninstall considerations
132
+
133
+ Removing the app does not remove built-in SRP fleets or requests. Plugin-owned
134
+ settings and exposure mappings remain in the database unless their tables are
135
+ explicitly removed. Back up first; do not reverse migrations casually on a
136
+ production installation. Remove `srp_access` from `INSTALLED_APPS` only after
137
+ planning whether to retain or remove those plugin tables.
138
+
139
+ ## Development and testing
140
+
141
+ Run tests against a Redis instance on localhost database 15:
142
+
143
+ ```bash
144
+ python -m django test srp_access.tests --settings=testauth.settings
145
+ ```
146
+
147
+ Build and validate distributions:
148
+
149
+ ```bash
150
+ python -m pip install --upgrade build twine
151
+ python -m build
152
+ python -m twine check dist/*
153
+ ```
154
+
155
+ The test suite uses SQLite and arbitrary fixture names. It covers anonymous,
156
+ State, Group, exposed-fleet, direct URL, submission, built-in SRP regression,
157
+ and built-in administrator behavior.
158
+
159
+ ## Release process
160
+
161
+ Update the changelog and version, merge tested changes, and create a deliberate
162
+ GitHub Release. The release workflow builds and validates wheel/sdist artifacts
163
+ before publishing through a PyPI Trusted Publisher and the protected `pypi`
164
+ GitHub environment. Ordinary pushes never publish.
@@ -0,0 +1,58 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.27"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "aa-srp-access"
7
+ dynamic = ["version"]
8
+ description = "Restricted, configurable access to Alliance Auth's built-in SRP"
9
+ readme = "README.md"
10
+ license = { file = "LICENSE" }
11
+ authors = [{ name = "aa-srp-access contributors" }]
12
+ requires-python = ">=3.10,<3.15"
13
+ dependencies = [
14
+ "allianceauth>=5.2,<5.3",
15
+ "django-solo>=2.5,<3",
16
+ ]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Environment :: Web Environment",
20
+ "Framework :: Django :: 5.2",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Programming Language :: Python :: 3.14",
28
+ "Topic :: Internet :: WWW/HTTP",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ test = [
33
+ "build>=1.2",
34
+ "twine>=5",
35
+ ]
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/thegriffenkd/aa-srp-access"
39
+ Changelog = "https://github.com/thegriffenkd/aa-srp-access/blob/main/CHANGELOG.md"
40
+ Issues = "https://github.com/thegriffenkd/aa-srp-access/issues"
41
+ Source = "https://github.com/thegriffenkd/aa-srp-access"
42
+
43
+ [tool.hatch.version]
44
+ path = "srp_access/__init__.py"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["srp_access"]
48
+
49
+ [tool.hatch.build.targets.sdist]
50
+ include = [
51
+ "/.github",
52
+ "/srp_access",
53
+ "/testauth",
54
+ "/CHANGELOG.md",
55
+ "/LICENSE",
56
+ "/README.md",
57
+ "/pyproject.toml",
58
+ ]
@@ -0,0 +1,3 @@
1
+ """Restricted frontend for Alliance Auth's built-in SRP application."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,79 @@
1
+ from django.core.exceptions import ObjectDoesNotExist
2
+
3
+ from allianceauth.srp.models import SrpFleetMain
4
+
5
+ from .models import ExposedSrpFleet, SrpAccessSettings
6
+
7
+
8
+ def get_access_settings():
9
+ """Return configured settings without creating database state during requests."""
10
+ return SrpAccessSettings.objects.first()
11
+
12
+
13
+ def user_has_eligible_state(user, settings=None):
14
+ if not getattr(user, "is_authenticated", False):
15
+ return False
16
+
17
+ try:
18
+ state = user.profile.state
19
+ except ObjectDoesNotExist:
20
+ return False
21
+
22
+ if state is None:
23
+ return False
24
+
25
+ settings = settings or get_access_settings()
26
+ if settings is None:
27
+ return False
28
+
29
+ if settings.allow_any_public_state:
30
+ return bool(state.public)
31
+
32
+ return settings.selected_states.filter(pk=state.pk).exists()
33
+
34
+
35
+ def user_in_required_group(user, settings=None):
36
+ if not getattr(user, "is_authenticated", False):
37
+ return False
38
+
39
+ settings = settings or get_access_settings()
40
+ if settings is None or settings.required_group_id is None:
41
+ return False
42
+
43
+ return user.groups.filter(pk=settings.required_group_id).exists()
44
+
45
+
46
+ def fleet_is_exposed(fleet):
47
+ fleet_id = getattr(fleet, "pk", fleet)
48
+ if fleet_id is None:
49
+ return False
50
+ return ExposedSrpFleet.objects.filter(fleet_id=fleet_id, enabled=True).exists()
51
+
52
+
53
+ def can_use_restricted_srp(user, fleet=None):
54
+ settings = get_access_settings()
55
+ if settings is None:
56
+ return False
57
+ if not user_has_eligible_state(user, settings):
58
+ return False
59
+ if not user_in_required_group(user, settings):
60
+ return False
61
+ if fleet is not None and not fleet_is_exposed(fleet):
62
+ return False
63
+ return True
64
+
65
+
66
+ def accessible_fleets_for(user):
67
+ """Return exposed built-in fleets that currently accept SRP requests."""
68
+ if not can_use_restricted_srp(user):
69
+ return SrpFleetMain.objects.none()
70
+
71
+ return (
72
+ SrpFleetMain.objects.select_related("fleet_commander")
73
+ .filter(
74
+ srp_access_exposure__enabled=True,
75
+ fleet_srp_status="",
76
+ )
77
+ .exclude(fleet_srp_code="")
78
+ .order_by("-fleet_time", "-pk")
79
+ )
@@ -0,0 +1,39 @@
1
+ from django.contrib import admin
2
+ from solo.admin import SingletonModelAdmin
3
+
4
+ from .models import ExposedSrpFleet, SrpAccessSettings
5
+
6
+
7
+ class SrpManagementPermissionMixin:
8
+ management_permission = "auth.srp_management"
9
+
10
+ def _can_manage(self, request):
11
+ return request.user.has_perm(self.management_permission)
12
+
13
+ def has_module_permission(self, request):
14
+ return self._can_manage(request)
15
+
16
+ def has_view_permission(self, request, obj=None):
17
+ return self._can_manage(request)
18
+
19
+ def has_add_permission(self, request):
20
+ return self._can_manage(request)
21
+
22
+ def has_change_permission(self, request, obj=None):
23
+ return self._can_manage(request)
24
+
25
+ def has_delete_permission(self, request, obj=None):
26
+ return self._can_manage(request)
27
+
28
+
29
+ @admin.register(SrpAccessSettings)
30
+ class SrpAccessSettingsAdmin(SrpManagementPermissionMixin, SingletonModelAdmin):
31
+ filter_horizontal = ("selected_states",)
32
+
33
+
34
+ @admin.register(ExposedSrpFleet)
35
+ class ExposedSrpFleetAdmin(SrpManagementPermissionMixin, admin.ModelAdmin):
36
+ list_display = ("fleet", "enabled")
37
+ list_filter = ("enabled",)
38
+ list_select_related = ("fleet",)
39
+ search_fields = ("fleet__fleet_name", "fleet__fleet_srp_code")