plain.auth 0.22.0__py3-none-any.whl → 0.23.0__py3-none-any.whl

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.
plain/auth/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # plain-auth changelog
2
2
 
3
+ ## [0.23.0](https://github.com/dropseed/plain/releases/plain-auth@0.23.0) (2026-01-13)
4
+
5
+ ### What's changed
6
+
7
+ - HTTP exception classes renamed to include `Error` suffix and status code: `PermissionDenied` → `ForbiddenError403`, `Http404` → `NotFoundError404` ([5a1f020](https://github.com/dropseed/plain/commit/5a1f020f52))
8
+ - Response classes renamed: `ResponseRedirect` → `RedirectResponse` ([fad5bf2](https://github.com/dropseed/plain/commit/fad5bf28b0))
9
+
10
+ ### Upgrade instructions
11
+
12
+ - Replace `PermissionDenied` with `ForbiddenError403` in any custom auth logic (e.g., `raise PermissionDenied("message")` becomes `raise ForbiddenError403("message")`)
13
+ - Replace `Http404` with `NotFoundError404` if used in auth-related code
14
+ - Replace `ResponseRedirect` with `RedirectResponse` if imported from `plain.http`
15
+
3
16
  ## [0.22.0](https://github.com/dropseed/plain/releases/plain-auth@0.22.0) (2025-11-24)
4
17
 
5
18
  ### What's changed
plain/auth/README.md CHANGED
@@ -139,7 +139,7 @@ Use the [`AuthViewMixin`](./views.py#AuthViewMixin) to restrict views to logged-
139
139
 
140
140
  ```python
141
141
  from plain.auth.views import AuthViewMixin
142
- from plain.exceptions import PermissionDenied
142
+ from plain.exceptions import ForbiddenError403
143
143
  from plain.views import View
144
144
 
145
145
 
@@ -156,7 +156,7 @@ class CustomPermissionView(AuthViewMixin, View):
156
156
  def check_auth(self):
157
157
  super().check_auth()
158
158
  if not self.user.is_special:
159
- raise PermissionDenied("You're not special!")
159
+ raise ForbiddenError403("You're not special!")
160
160
  ```
161
161
 
162
162
  The [`AuthViewMixin`](./views.py#AuthViewMixin) provides:
plain/auth/views.py CHANGED
@@ -4,12 +4,11 @@ from functools import cached_property
4
4
  from typing import Any
5
5
  from urllib.parse import urlparse, urlunparse
6
6
 
7
- from plain.exceptions import PermissionDenied
7
+ from plain.exceptions import ForbiddenError403, NotFoundError404
8
8
  from plain.http import (
9
- Http404,
10
9
  QueryDict,
10
+ RedirectResponse,
11
11
  ResponseBase,
12
- ResponseRedirect,
13
12
  )
14
13
  from plain.runtime import settings
15
14
  from plain.sessions.views import SessionView
@@ -52,9 +51,9 @@ class AuthView(SessionView):
52
51
 
53
52
  def check_auth(self) -> None:
54
53
  """
55
- Raises either LoginRequired or PermissionDenied.
54
+ Raises either LoginRequired or ForbiddenError403.
56
55
  - LoginRequired can specify a login_url and redirect_field_name
57
- - PermissionDenied can specify a message
56
+ - ForbiddenError403 can specify a message
58
57
  """
59
58
  if not self.login_required and not self.admin_required:
60
59
  return None
@@ -70,14 +69,14 @@ class AuthView(SessionView):
70
69
  # Impersonators should be able to view admin pages while impersonating.
71
70
  # There's probably never a case where an impersonator isn't admin, but it can be configured.
72
71
  if not impersonator.is_admin:
73
- raise PermissionDenied(
72
+ raise ForbiddenError403(
74
73
  "You do not have permission to access this page."
75
74
  )
76
75
  return
77
76
 
78
77
  if not self.user.is_admin:
79
78
  # Show a 404 so we don't expose admin urls to non-admin users
80
- raise Http404()
79
+ raise NotFoundError404()
81
80
 
82
81
  def get_response(self) -> ResponseBase:
83
82
  try:
@@ -103,7 +102,7 @@ class AuthView(SessionView):
103
102
  e.redirect_field_name,
104
103
  )
105
104
  else:
106
- raise PermissionDenied("Login required")
105
+ raise ForbiddenError403("Login required")
107
106
 
108
107
  response = super().get_response()
109
108
 
@@ -115,14 +114,14 @@ class AuthView(SessionView):
115
114
 
116
115
 
117
116
  class LogoutView(View):
118
- def post(self) -> ResponseRedirect:
117
+ def post(self) -> RedirectResponse:
119
118
  logout(self.request)
120
- return ResponseRedirect("/")
119
+ return RedirectResponse("/")
121
120
 
122
121
 
123
122
  def redirect_to_login(
124
123
  next: str, login_url: str | None = None, redirect_field_name: str = "next"
125
- ) -> ResponseRedirect:
124
+ ) -> RedirectResponse:
126
125
  """
127
126
  Redirect the user to the login page, passing the given 'next' page.
128
127
  """
@@ -134,4 +133,4 @@ def redirect_to_login(
134
133
  querystring[redirect_field_name] = next
135
134
  login_url_parts[4] = querystring.urlencode(safe="/")
136
135
 
137
- return ResponseRedirect(str(urlunparse(login_url_parts)))
136
+ return RedirectResponse(str(urlunparse(login_url_parts)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.auth
3
- Version: 0.22.0
3
+ Version: 0.23.0
4
4
  Summary: Add users to your app and decide what they can access.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-Expression: BSD-3-Clause
@@ -152,7 +152,7 @@ Use the [`AuthViewMixin`](./views.py#AuthViewMixin) to restrict views to logged-
152
152
 
153
153
  ```python
154
154
  from plain.auth.views import AuthViewMixin
155
- from plain.exceptions import PermissionDenied
155
+ from plain.exceptions import ForbiddenError403
156
156
  from plain.views import View
157
157
 
158
158
 
@@ -169,7 +169,7 @@ class CustomPermissionView(AuthViewMixin, View):
169
169
  def check_auth(self):
170
170
  super().check_auth()
171
171
  if not self.user.is_special:
172
- raise PermissionDenied("You're not special!")
172
+ raise ForbiddenError403("You're not special!")
173
173
  ```
174
174
 
175
175
  The [`AuthViewMixin`](./views.py#AuthViewMixin) provides:
@@ -1,5 +1,5 @@
1
- plain/auth/CHANGELOG.md,sha256=exRD-vtzfuTTesjNgJuLkh0RO6XtDV1pMv-To_f_Yas,7600
2
- plain/auth/README.md,sha256=I1SeOyrBnF0GAjD7T0k5OlZ2bSHz9---nElinaobewc,4030
1
+ plain/auth/CHANGELOG.md,sha256=5Qmh-kOTzUDAuT7ncQs2L6PGsmGh7ToBlwZQE1ZBlUg,8413
2
+ plain/auth/README.md,sha256=397DaiamLW8JHoVwNrrIO8NAgRS9jWOdeAZB_Oq135A,4032
3
3
  plain/auth/__init__.py,sha256=CrOsS74CPGN1nPTTfie13mPgdyVLRyZ1YwDPIA77uaA,179
4
4
  plain/auth/default_settings.py,sha256=65VzDn3j61OMn78Lg6Zuds4A8QKzJJ_0G9KoFqAOIRo,466
5
5
  plain/auth/requests.py,sha256=jUlMTOWFt0qfDF_uVkOqaP9rZiCLrAofsmirCwyRGEE,880
@@ -7,8 +7,8 @@ plain/auth/sessions.py,sha256=xDp1EiB0cV5w3L5XioqO8vs77wnF8cvreExms3-e744,6015
7
7
  plain/auth/templates.py,sha256=CVtuIdBgOgYB2o61zpOPJb6nMx_gU61i_3PDQx8FjVs,770
8
8
  plain/auth/test.py,sha256=SHawhwarJEMVfaLkjpiuFVSWZoGIMwhzXreU_T1zvCE,1599
9
9
  plain/auth/utils.py,sha256=9kKWh1QqxA8Esct-jBvTCdjBYOHpO_Tg1YeV9WxYmxg,1362
10
- plain/auth/views.py,sha256=5R3DxMil3j7iStomFH4GcJNG-m-YZzYgCS6UMdi2YjY,4924
11
- plain_auth-0.22.0.dist-info/METADATA,sha256=j3q9wOhxWj9yxMk4qTHOv18HtYRN97lOIJngoq-dy74,4423
12
- plain_auth-0.22.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
- plain_auth-0.22.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
14
- plain_auth-0.22.0.dist-info/RECORD,,
10
+ plain/auth/views.py,sha256=zQO0LFioYIv35xXe1RBx77MLIJjog1neuX7aIT0wLhE,4943
11
+ plain_auth-0.23.0.dist-info/METADATA,sha256=8CCcWoKfBjxlFTsykBTgexSgSqDSvoUR8ZnHONQBdwg,4425
12
+ plain_auth-0.23.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
+ plain_auth-0.23.0.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
14
+ plain_auth-0.23.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any