dbca-utils 2.1.0__tar.gz → 2.1.2__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.
- {dbca_utils-2.1.0/src/dbca_utils.egg-info → dbca_utils-2.1.2}/PKG-INFO +9 -10
- dbca_utils-2.1.2/pyproject.toml +72 -0
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/src/dbca_utils/middleware.py +37 -45
- dbca_utils-2.1.2/tests/__init__.py +0 -0
- dbca_utils-2.1.2/tests/apps.py +6 -0
- dbca_utils-2.1.2/tests/migrations/0001_initial.py +63 -0
- dbca_utils-2.1.2/tests/migrations/__init__.py +0 -0
- dbca_utils-2.1.2/tests/models.py +11 -0
- dbca_utils-2.1.2/tests/settings.py +46 -0
- dbca_utils-2.1.2/tests/templates/tests/test_model_list.html +12 -0
- dbca_utils-2.1.2/tests/urls.py +7 -0
- dbca_utils-2.1.2/tests/views.py +16 -0
- dbca_utils-2.1.0/PKG-INFO +0 -111
- dbca_utils-2.1.0/pyproject.toml +0 -52
- dbca_utils-2.1.0/setup.cfg +0 -4
- dbca_utils-2.1.0/src/dbca_utils.egg-info/SOURCES.txt +0 -13
- dbca_utils-2.1.0/src/dbca_utils.egg-info/dependency_links.txt +0 -1
- dbca_utils-2.1.0/src/dbca_utils.egg-info/requires.txt +0 -1
- dbca_utils-2.1.0/src/dbca_utils.egg-info/top_level.txt +0 -1
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/LICENSE +0 -0
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/README.md +0 -0
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/src/dbca_utils/__init__.py +0 -0
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/src/dbca_utils/models.py +0 -0
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/src/dbca_utils/utils.py +0 -0
- {dbca_utils-2.1.0 → dbca_utils-2.1.2}/tests/tests.py +0 -0
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbca-utils
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.2
|
|
4
4
|
Summary: Utilities for DBCA Django apps
|
|
5
|
-
Author-
|
|
6
|
-
|
|
7
|
-
Project-URL: Repository, https://github.com/dbca-wa/dbca-utils.git
|
|
8
|
-
Project-URL: Changelog, https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md
|
|
9
|
-
Project-URL: GitHub, https://github.com/dbca-wa/dbca-utils
|
|
5
|
+
Author-Email: Rocky Chen <rocky.chen@dbca.wa.gov.au>, Ashley Felton <ashley.felton@dbca.wa.gov.au>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
10
7
|
Classifier: Framework :: Django
|
|
11
8
|
Classifier: Framework :: Django :: 4.0
|
|
12
9
|
Classifier: Framework :: Django :: 4.2
|
|
@@ -15,7 +12,6 @@ Classifier: Framework :: Django :: 5.2
|
|
|
15
12
|
Classifier: Environment :: Web Environment
|
|
16
13
|
Classifier: Intended Audience :: Developers
|
|
17
14
|
Classifier: Development Status :: 5 - Production/Stable
|
|
18
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
19
15
|
Classifier: Programming Language :: Python
|
|
20
16
|
Classifier: Programming Language :: Python :: 3
|
|
21
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -24,11 +20,14 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
24
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
21
|
Classifier: Topic :: Software Development :: Libraries
|
|
26
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Project-URL: Homepage, https://github.com/dbca-wa/dbca-utils
|
|
24
|
+
Project-URL: Repository, https://github.com/dbca-wa/dbca-utils.git
|
|
25
|
+
Project-URL: Changelog, https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md
|
|
26
|
+
Project-URL: GitHub, https://github.com/dbca-wa/dbca-utils
|
|
27
27
|
Requires-Python: <4.0,>=3.10
|
|
28
|
-
Description-Content-Type: text/markdown
|
|
29
|
-
License-File: LICENSE
|
|
30
28
|
Requires-Dist: django<6,>=4
|
|
31
|
-
|
|
29
|
+
Requires-Dist: markupsafe==3.0.2
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
32
31
|
|
|
33
32
|
# Overview
|
|
34
33
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "dbca-utils"
|
|
3
|
+
version = "2.1.2"
|
|
4
|
+
description = "Utilities for DBCA Django apps"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "Rocky Chen", email = "rocky.chen@dbca.wa.gov.au" },
|
|
7
|
+
{ name = "Ashley Felton", email = "ashley.felton@dbca.wa.gov.au" },
|
|
8
|
+
]
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Framework :: Django",
|
|
13
|
+
"Framework :: Django :: 4.0",
|
|
14
|
+
"Framework :: Django :: 4.2",
|
|
15
|
+
"Framework :: Django :: 5.0",
|
|
16
|
+
"Framework :: Django :: 5.2",
|
|
17
|
+
"Environment :: Web Environment",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Development Status :: 5 - Production/Stable",
|
|
20
|
+
"Programming Language :: Python",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Software Development :: Libraries",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
]
|
|
29
|
+
requires-python = ">=3.10,<4.0"
|
|
30
|
+
dependencies = [
|
|
31
|
+
"django>=4,<6",
|
|
32
|
+
"markupsafe==3.0.2",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.urls]
|
|
36
|
+
Homepage = "https://github.com/dbca-wa/dbca-utils"
|
|
37
|
+
Repository = "https://github.com/dbca-wa/dbca-utils.git"
|
|
38
|
+
Changelog = "https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md"
|
|
39
|
+
GitHub = "https://github.com/dbca-wa/dbca-utils"
|
|
40
|
+
|
|
41
|
+
[dependency-groups]
|
|
42
|
+
dev = [
|
|
43
|
+
"pytest-django>=4.11.0",
|
|
44
|
+
"pytest-sugar>=1.0.0",
|
|
45
|
+
"tox>=4.25.0",
|
|
46
|
+
"tox-uv>=1.25.0",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[build-system]
|
|
50
|
+
requires = [
|
|
51
|
+
"pdm-backend",
|
|
52
|
+
]
|
|
53
|
+
build-backend = "pdm.backend"
|
|
54
|
+
|
|
55
|
+
[tool.uv]
|
|
56
|
+
package = true
|
|
57
|
+
|
|
58
|
+
[tool.pytest.ini_options]
|
|
59
|
+
DJANGO_SETTINGS_MODULE = "tests.settings"
|
|
60
|
+
pythonpath = ". src"
|
|
61
|
+
python_files = "tests.py test_*.py"
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
line-length = 140
|
|
65
|
+
indent-width = 4
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
ignore = [
|
|
69
|
+
"E265",
|
|
70
|
+
"E501",
|
|
71
|
+
"E722",
|
|
72
|
+
]
|
|
@@ -5,6 +5,7 @@ from django.contrib.auth.middleware import AuthenticationMiddleware, get_user
|
|
|
5
5
|
from django.utils import timezone
|
|
6
6
|
from django.utils.deprecation import MiddlewareMixin
|
|
7
7
|
from django.utils.functional import SimpleLazyObject
|
|
8
|
+
from markupsafe import escape
|
|
8
9
|
|
|
9
10
|
from dbca_utils.utils import env
|
|
10
11
|
|
|
@@ -13,18 +14,16 @@ LOCAL_USERGROUPS = env("LOCAL_USERGROUPS", default=[])
|
|
|
13
14
|
User = get_user_model()
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
def sync_usergroups(user, groups):
|
|
17
|
+
def sync_usergroups(user, groups=None):
|
|
17
18
|
from django.contrib.auth.models import Group
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
[Group.objects.get_or_create(name=name)[0] for name in groups.split(",")]
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
if groups:
|
|
21
|
+
usergroups = [Group.objects.get_or_create(name=name)[0] for name in groups.split(",")]
|
|
22
|
+
else:
|
|
23
|
+
usergroups = []
|
|
24
|
+
|
|
24
25
|
usergroups.sort(key=lambda o: o.id)
|
|
25
|
-
existing_usergroups = list(
|
|
26
|
-
user.groups.exclude(name__in=LOCAL_USERGROUPS).order_by("id")
|
|
27
|
-
)
|
|
26
|
+
existing_usergroups = list(user.groups.exclude(name__in=LOCAL_USERGROUPS).order_by("id"))
|
|
28
27
|
index1 = 0
|
|
29
28
|
index2 = 0
|
|
30
29
|
len1 = len(usergroups)
|
|
@@ -76,9 +75,7 @@ if ENABLE_AUTH2_GROUPS:
|
|
|
76
75
|
existing_groups = request.session.get("usergroups")
|
|
77
76
|
if groups != existing_groups:
|
|
78
77
|
# User group is changed.
|
|
79
|
-
request.user = SimpleLazyUser(
|
|
80
|
-
lambda: get_user(request), request, groups
|
|
81
|
-
)
|
|
78
|
+
request.user = SimpleLazyUser(lambda: get_user(request), request, groups)
|
|
82
79
|
return
|
|
83
80
|
original_process_request(self, request)
|
|
84
81
|
|
|
@@ -102,11 +99,7 @@ class SSOLoginMiddleware(MiddlewareMixin):
|
|
|
102
99
|
def process_request(self, request):
|
|
103
100
|
# Logout headers included with request.
|
|
104
101
|
if (
|
|
105
|
-
(
|
|
106
|
-
request.path.startswith("/logout")
|
|
107
|
-
or request.path.startswith("/admin/logout")
|
|
108
|
-
or request.path.startswith("/ledger/logout")
|
|
109
|
-
)
|
|
102
|
+
(request.path.startswith("/logout") or request.path.startswith("/admin/logout") or request.path.startswith("/ledger/logout"))
|
|
110
103
|
and "HTTP_X_LOGOUT_URL" in request.META
|
|
111
104
|
and request.META["HTTP_X_LOGOUT_URL"]
|
|
112
105
|
):
|
|
@@ -114,18 +107,20 @@ class SSOLoginMiddleware(MiddlewareMixin):
|
|
|
114
107
|
return http.HttpResponseRedirect(request.META["HTTP_X_LOGOUT_URL"])
|
|
115
108
|
|
|
116
109
|
# Auth2 is not enabled, skip further processing.
|
|
117
|
-
if
|
|
118
|
-
"HTTP_REMOTE_USER" not in request.META
|
|
119
|
-
or not request.META["HTTP_REMOTE_USER"]
|
|
120
|
-
):
|
|
110
|
+
if "HTTP_REMOTE_USER" not in request.META or not request.META["HTTP_REMOTE_USER"]:
|
|
121
111
|
# auth2 not enabled
|
|
122
112
|
return
|
|
123
113
|
|
|
124
|
-
user_authenticated = request.user.is_authenticated
|
|
125
|
-
|
|
126
114
|
# Auth2 is enabled.
|
|
127
|
-
#
|
|
128
|
-
|
|
115
|
+
# Security check: if the logged-in request user's email does not match the email
|
|
116
|
+
# returned from Auth2, invalidate the current request session and force a new session
|
|
117
|
+
# using the returned SSO values.
|
|
118
|
+
if request.user.is_authenticated and request.user.email != request.META["HTTP_X_EMAIL"]:
|
|
119
|
+
logout(request)
|
|
120
|
+
|
|
121
|
+
# Request user is not authenticated locally: obtain user attributes from the request.META dict
|
|
122
|
+
# returned by SSO.
|
|
123
|
+
if not request.user.is_authenticated:
|
|
129
124
|
attributemap = {
|
|
130
125
|
"username": "HTTP_REMOTE_USER",
|
|
131
126
|
"last_name": "HTTP_X_LAST_NAME",
|
|
@@ -137,31 +132,28 @@ class SSOLoginMiddleware(MiddlewareMixin):
|
|
|
137
132
|
if value in request.META:
|
|
138
133
|
attributemap[key] = request.META[value]
|
|
139
134
|
|
|
135
|
+
# Sanitise first_name and last_name values, because end-users have control over these
|
|
136
|
+
# values and could conceivably inject malicious values into them (e.g. a XSS attack).
|
|
137
|
+
if "first_name" in attributemap:
|
|
138
|
+
attributemap["first_name"] = str(escape(attributemap["first_name"]))
|
|
139
|
+
if "last_name" in attributemap:
|
|
140
|
+
attributemap["last_name"] = str(escape(attributemap["last_name"]))
|
|
141
|
+
|
|
140
142
|
# Optional setting: projects may define accepted user email domains either as
|
|
141
143
|
# a list of strings, or a single string.
|
|
142
|
-
if (
|
|
143
|
-
hasattr(settings, "ALLOWED_EMAIL_SUFFIXES")
|
|
144
|
-
and settings.ALLOWED_EMAIL_SUFFIXES
|
|
145
|
-
):
|
|
146
|
-
allowed = settings.ALLOWED_EMAIL_SUFFIXES
|
|
144
|
+
if hasattr(settings, "ALLOWED_EMAIL_SUFFIXES") and settings.ALLOWED_EMAIL_SUFFIXES:
|
|
147
145
|
if isinstance(settings.ALLOWED_EMAIL_SUFFIXES, str):
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
146
|
+
allowed_email_suffixes = list(settings.ALLOWED_EMAIL_SUFFIXES)
|
|
147
|
+
else:
|
|
148
|
+
allowed_email_suffixes = settings.ALLOWED_EMAIL_SUFFIXES
|
|
149
|
+
# If the user email suffix is not in the allowed list, return a 404 response.
|
|
150
|
+
if not any([attributemap["email"].lower().endswith(suffix) for suffix in allowed_email_suffixes]):
|
|
152
151
|
return http.HttpResponseForbidden()
|
|
153
152
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
and User.objects.filter(email__iexact=attributemap["email"]).exists()
|
|
157
|
-
):
|
|
153
|
+
# Check for an existing User instance.
|
|
154
|
+
if attributemap["email"] and User.objects.filter(email__iexact=attributemap["email"]).exists():
|
|
158
155
|
user = User.objects.filter(email__iexact=attributemap["email"])[0]
|
|
159
|
-
elif (
|
|
160
|
-
User.__name__ != "EmailUser"
|
|
161
|
-
and User.objects.filter(
|
|
162
|
-
username__iexact=attributemap["username"]
|
|
163
|
-
).exists()
|
|
164
|
-
):
|
|
156
|
+
elif User.__name__ != "EmailUser" and User.objects.filter(username__iexact=attributemap["username"]).exists():
|
|
165
157
|
user = User.objects.filter(username__iexact=attributemap["username"])[0]
|
|
166
158
|
else:
|
|
167
159
|
user = User(last_login=timezone.localtime())
|
|
@@ -174,7 +166,7 @@ class SSOLoginMiddleware(MiddlewareMixin):
|
|
|
174
166
|
# Log the user in.
|
|
175
167
|
login(request, user)
|
|
176
168
|
|
|
177
|
-
# Synchronize the user groups
|
|
169
|
+
# Synchronize the user groups.
|
|
178
170
|
if ENABLE_AUTH2_GROUPS and "HTTP_X_GROUPS" in request.META:
|
|
179
171
|
groups = request.META["HTTP_X_GROUPS"] or None
|
|
180
172
|
sync_usergroups(user, groups)
|
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import django.db.models.deletion
|
|
2
|
+
import django.utils.timezone
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
initial = True
|
|
9
|
+
|
|
10
|
+
dependencies = [
|
|
11
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.CreateModel(
|
|
16
|
+
name="TestModel",
|
|
17
|
+
fields=[
|
|
18
|
+
(
|
|
19
|
+
"id",
|
|
20
|
+
models.AutoField(
|
|
21
|
+
auto_created=True,
|
|
22
|
+
primary_key=True,
|
|
23
|
+
serialize=False,
|
|
24
|
+
verbose_name="ID",
|
|
25
|
+
),
|
|
26
|
+
),
|
|
27
|
+
("effective_to", models.DateTimeField(blank=True, null=True)),
|
|
28
|
+
(
|
|
29
|
+
"created",
|
|
30
|
+
models.DateTimeField(
|
|
31
|
+
default=django.utils.timezone.now, editable=False
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
("modified", models.DateTimeField(auto_now=True)),
|
|
35
|
+
("name", models.CharField(max_length=64)),
|
|
36
|
+
(
|
|
37
|
+
"creator",
|
|
38
|
+
models.ForeignKey(
|
|
39
|
+
blank=True,
|
|
40
|
+
editable=False,
|
|
41
|
+
null=True,
|
|
42
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
43
|
+
related_name="%(app_label)s_%(class)s_created",
|
|
44
|
+
to=settings.AUTH_USER_MODEL,
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
(
|
|
48
|
+
"modifier",
|
|
49
|
+
models.ForeignKey(
|
|
50
|
+
blank=True,
|
|
51
|
+
editable=False,
|
|
52
|
+
null=True,
|
|
53
|
+
on_delete=django.db.models.deletion.PROTECT,
|
|
54
|
+
related_name="%(app_label)s_%(class)s_modified",
|
|
55
|
+
to=settings.AUTH_USER_MODEL,
|
|
56
|
+
),
|
|
57
|
+
),
|
|
58
|
+
],
|
|
59
|
+
options={
|
|
60
|
+
"abstract": False,
|
|
61
|
+
},
|
|
62
|
+
),
|
|
63
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
from dbca_utils.models import ActiveMixin, ActiveMixinManager, AuditMixin
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestModel(ActiveMixin, AuditMixin):
|
|
7
|
+
name = models.CharField(max_length=64)
|
|
8
|
+
objects = ActiveMixinManager()
|
|
9
|
+
|
|
10
|
+
def __str__(self):
|
|
11
|
+
return self.name
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
SECRET_KEY = "secretkey"
|
|
2
|
+
|
|
3
|
+
INSTALLED_APPS = [
|
|
4
|
+
"django.contrib.auth",
|
|
5
|
+
"django.contrib.contenttypes",
|
|
6
|
+
"django.contrib.sessions",
|
|
7
|
+
"django.contrib.messages",
|
|
8
|
+
"django.contrib.staticfiles",
|
|
9
|
+
"tests",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
MIDDLEWARE = [
|
|
13
|
+
"django.middleware.security.SecurityMiddleware",
|
|
14
|
+
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
15
|
+
"django.middleware.common.CommonMiddleware",
|
|
16
|
+
"django.middleware.csrf.CsrfViewMiddleware",
|
|
17
|
+
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
18
|
+
"django.contrib.messages.middleware.MessageMiddleware",
|
|
19
|
+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
20
|
+
"dbca_utils.middleware.SSOLoginMiddleware",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
ROOT_URLCONF = "tests.urls"
|
|
24
|
+
|
|
25
|
+
TEMPLATES = [
|
|
26
|
+
{
|
|
27
|
+
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
28
|
+
"APP_DIRS": True,
|
|
29
|
+
"OPTIONS": {
|
|
30
|
+
"context_processors": [
|
|
31
|
+
"django.template.context_processors.debug",
|
|
32
|
+
"django.template.context_processors.request",
|
|
33
|
+
"django.contrib.auth.context_processors.auth",
|
|
34
|
+
"django.contrib.messages.context_processors.messages",
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
|
|
41
|
+
|
|
42
|
+
STATIC_URL = "/static/"
|
|
43
|
+
|
|
44
|
+
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
|
45
|
+
|
|
46
|
+
USE_TZ = True
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>{{ TITLE }}</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<ul>
|
|
9
|
+
{% for object in object_list %}<li>{{ object.name }}, {{ object.created|date:"r" }}</li>{% endfor %}
|
|
10
|
+
</ul>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
2
|
+
from django.views.generic.list import ListView
|
|
3
|
+
|
|
4
|
+
from dbca_utils.utils import env
|
|
5
|
+
|
|
6
|
+
from .models import TestModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestModelListView(LoginRequiredMixin, ListView):
|
|
10
|
+
model = TestModel
|
|
11
|
+
template_name = "tests/test_model_list.html"
|
|
12
|
+
|
|
13
|
+
def get_context_data(self, **kwargs):
|
|
14
|
+
context = super().get_context_data(**kwargs)
|
|
15
|
+
context["TITLE"] = env("TEST_ENVIRONMENT_VAR")
|
|
16
|
+
return context
|
dbca_utils-2.1.0/PKG-INFO
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: dbca-utils
|
|
3
|
-
Version: 2.1.0
|
|
4
|
-
Summary: Utilities for DBCA Django apps
|
|
5
|
-
Author-email: Rocky Chen <rocky.chen@dbca.wa.gov.au>, Ashley Felton <ashley.felton@dbca.wa.gov.au>
|
|
6
|
-
Project-URL: Homepage, https://github.com/dbca-wa/dbca-utils
|
|
7
|
-
Project-URL: Repository, https://github.com/dbca-wa/dbca-utils.git
|
|
8
|
-
Project-URL: Changelog, https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md
|
|
9
|
-
Project-URL: GitHub, https://github.com/dbca-wa/dbca-utils
|
|
10
|
-
Classifier: Framework :: Django
|
|
11
|
-
Classifier: Framework :: Django :: 4.0
|
|
12
|
-
Classifier: Framework :: Django :: 4.2
|
|
13
|
-
Classifier: Framework :: Django :: 5.0
|
|
14
|
-
Classifier: Framework :: Django :: 5.2
|
|
15
|
-
Classifier: Environment :: Web Environment
|
|
16
|
-
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
18
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
19
|
-
Classifier: Programming Language :: Python
|
|
20
|
-
Classifier: Programming Language :: Python :: 3
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
26
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
|
-
Requires-Python: <4.0,>=3.10
|
|
28
|
-
Description-Content-Type: text/markdown
|
|
29
|
-
License-File: LICENSE
|
|
30
|
-
Requires-Dist: django<6,>=4
|
|
31
|
-
Dynamic: license-file
|
|
32
|
-
|
|
33
|
-
# Overview
|
|
34
|
-
|
|
35
|
-
DBCA Django utility classes and functions.
|
|
36
|
-
|
|
37
|
-
## Development
|
|
38
|
-
|
|
39
|
-
The recommended way to set up this project for development is using
|
|
40
|
-
[uv](https://docs.astral.sh/uv/)
|
|
41
|
-
to install and manage a Python virtual environment.
|
|
42
|
-
With uv installed, install the required Python version (see `pyproject.toml`). Example:
|
|
43
|
-
|
|
44
|
-
uv python install 3.12
|
|
45
|
-
|
|
46
|
-
Change into the project directory and run:
|
|
47
|
-
|
|
48
|
-
uv python pin 3.12
|
|
49
|
-
uv sync
|
|
50
|
-
|
|
51
|
-
Activate the virtualenv like so:
|
|
52
|
-
|
|
53
|
-
source .venv/bin/activate
|
|
54
|
-
|
|
55
|
-
Run unit tests using `pytest` (or `tox`, to test against multiple Python versions):
|
|
56
|
-
|
|
57
|
-
pytest -sv
|
|
58
|
-
tox -v
|
|
59
|
-
|
|
60
|
-
## Releases
|
|
61
|
-
|
|
62
|
-
Tagged releases are built and pushed to PyPI automatically using a GitHub
|
|
63
|
-
workflow in the project. Update the project version in `pyproject.toml` and
|
|
64
|
-
tag the required commit with the same value to trigger a release. Packages
|
|
65
|
-
can also be built and uploaded manually, if desired.
|
|
66
|
-
|
|
67
|
-
Build the project locally using uv, [publish to the PyPI registry](https://docs.astral.sh/uv/guides/publish/#publishing-your-package)
|
|
68
|
-
using the same tool if you require:
|
|
69
|
-
|
|
70
|
-
uv build
|
|
71
|
-
uv publish
|
|
72
|
-
|
|
73
|
-
## Installation
|
|
74
|
-
|
|
75
|
-
1. Install via pip/etc.: `pip install dbca-utils`
|
|
76
|
-
|
|
77
|
-
## SSO Login Middleware
|
|
78
|
-
|
|
79
|
-
This will automatically login and create users using headers from an upstream proxy (REMOTE_USER and some others).
|
|
80
|
-
The logout view will redirect to a separate logout page which clears the SSO session.
|
|
81
|
-
|
|
82
|
-
### Usage
|
|
83
|
-
|
|
84
|
-
Add `dbca_utils.middleware.SSOLoginMiddleware` to `settings.MIDDLEWARE` (after both of
|
|
85
|
-
`django.contrib.sessions.middleware.SessionMiddleware` and
|
|
86
|
-
`django.contrib.auth.middleware.AuthenticationMiddleware`.
|
|
87
|
-
Ensure that `AUTHENTICATION_BACKENDS` contains `django.contrib.auth.backends.ModelBackend`,
|
|
88
|
-
as this middleware depends on it for retrieving the logged in user for a session.
|
|
89
|
-
Note that the middleware will still work without it, but will reauthenticate the session
|
|
90
|
-
on every request, and `request.user.is_authenticated` won't work properly/will be false.
|
|
91
|
-
|
|
92
|
-
Example:
|
|
93
|
-
|
|
94
|
-
```python
|
|
95
|
-
MIDDLEWARE = [
|
|
96
|
-
...,
|
|
97
|
-
'django.contrib.sessions.middleware.SessionMiddleware',
|
|
98
|
-
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
|
99
|
-
'dbca_utils.middleware.SSOLoginMiddleware'
|
|
100
|
-
...,
|
|
101
|
-
]
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Audit model mixin
|
|
105
|
-
|
|
106
|
-
`AuditMixin` is an extension of `Django.db.model.Model` that adds a number of additional fields:
|
|
107
|
-
|
|
108
|
-
- `creator` - FK to `AUTH_USER_MODEL`, used to record the object creator
|
|
109
|
-
- `modifier` - FK to `AUTH_USER_MODEL`, used to record who the object was last modified by
|
|
110
|
-
- `created` - a timestamp that is set on initial object save
|
|
111
|
-
- `modified` - an auto-updating timestamp (on each object save)
|
dbca_utils-2.1.0/pyproject.toml
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "dbca-utils"
|
|
3
|
-
version = "2.1.0"
|
|
4
|
-
description = "Utilities for DBCA Django apps"
|
|
5
|
-
authors = [
|
|
6
|
-
{ name = "Rocky Chen", email = "rocky.chen@dbca.wa.gov.au" },
|
|
7
|
-
{ name = "Ashley Felton", email = "ashley.felton@dbca.wa.gov.au" },
|
|
8
|
-
]
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
classifiers = [
|
|
11
|
-
"Framework :: Django",
|
|
12
|
-
"Framework :: Django :: 4.0",
|
|
13
|
-
"Framework :: Django :: 4.2",
|
|
14
|
-
"Framework :: Django :: 5.0",
|
|
15
|
-
"Framework :: Django :: 5.2",
|
|
16
|
-
"Environment :: Web Environment",
|
|
17
|
-
"Intended Audience :: Developers",
|
|
18
|
-
"Development Status :: 5 - Production/Stable",
|
|
19
|
-
"License :: OSI Approved :: Apache Software License",
|
|
20
|
-
"Programming Language :: Python",
|
|
21
|
-
"Programming Language :: Python :: 3",
|
|
22
|
-
"Programming Language :: Python :: 3.10",
|
|
23
|
-
"Programming Language :: Python :: 3.11",
|
|
24
|
-
"Programming Language :: Python :: 3.12",
|
|
25
|
-
"Programming Language :: Python :: 3.13",
|
|
26
|
-
"Topic :: Software Development :: Libraries",
|
|
27
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
-
]
|
|
29
|
-
requires-python = ">=3.10,<4.0"
|
|
30
|
-
dependencies = ["django>=4,<6"]
|
|
31
|
-
|
|
32
|
-
[project.urls]
|
|
33
|
-
Homepage = "https://github.com/dbca-wa/dbca-utils"
|
|
34
|
-
Repository = "https://github.com/dbca-wa/dbca-utils.git"
|
|
35
|
-
Changelog = "https://github.com/dbca-wa/dbca-utils/blob/master/CHANGELOG.md"
|
|
36
|
-
GitHub = "https://github.com/dbca-wa/dbca-utils"
|
|
37
|
-
|
|
38
|
-
[dependency-groups]
|
|
39
|
-
dev = [
|
|
40
|
-
"pytest-django>=4.11.0",
|
|
41
|
-
"pytest-sugar>=1.0.0",
|
|
42
|
-
"tox>=4.25.0",
|
|
43
|
-
"tox-uv>=1.25.0",
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
[tool.pytest.ini_options]
|
|
47
|
-
# https://pytest-django.readthedocs.io/en/latest/configuring_django.html#pyproject-toml-settings
|
|
48
|
-
DJANGO_SETTINGS_MODULE = "tests.settings"
|
|
49
|
-
# https://pytest-django.readthedocs.io/en/latest/managing_python_path.html#using-pytest-s-pythonpath-option
|
|
50
|
-
pythonpath = ". src"
|
|
51
|
-
# https://pytest-django.readthedocs.io/en/latest/faq.html#my-tests-are-not-being-found-why
|
|
52
|
-
python_files = "tests.py test_*.py"
|
dbca_utils-2.1.0/setup.cfg
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
pyproject.toml
|
|
4
|
-
src/dbca_utils/__init__.py
|
|
5
|
-
src/dbca_utils/middleware.py
|
|
6
|
-
src/dbca_utils/models.py
|
|
7
|
-
src/dbca_utils/utils.py
|
|
8
|
-
src/dbca_utils.egg-info/PKG-INFO
|
|
9
|
-
src/dbca_utils.egg-info/SOURCES.txt
|
|
10
|
-
src/dbca_utils.egg-info/dependency_links.txt
|
|
11
|
-
src/dbca_utils.egg-info/requires.txt
|
|
12
|
-
src/dbca_utils.egg-info/top_level.txt
|
|
13
|
-
tests/tests.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
django<6,>=4
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
dbca_utils
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|