plain.oauth 0.26.0__py3-none-any.whl → 0.28.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/oauth/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # plain-oauth changelog
2
2
 
3
+ ## [0.28.0](https://github.com/dropseed/plain/releases/plain-oauth@0.28.0) (2025-09-30)
4
+
5
+ ### What's changed
6
+
7
+ - `HttpRequest` has been renamed to `Request` throughout the OAuth provider classes ([cd46ff2](https://github.com/dropseed/plain/commit/cd46ff2003))
8
+
9
+ ### Upgrade instructions
10
+
11
+ - If you have custom OAuth providers that override methods like `get_authorization_url_params`, `get_oauth_token`, `get_callback_url`, or any other methods that accept a request parameter, update the type hint from `HttpRequest` to `Request`
12
+ - Update any imports of `HttpRequest` in custom OAuth provider code to import `Request` instead from `plain.http`
13
+
14
+ ## [0.27.0](https://github.com/dropseed/plain/releases/plain-oauth@0.27.0) (2025-09-25)
15
+
16
+ ### What's changed
17
+
18
+ - The `OAuthConnection.check()` method has been replaced with `OAuthConnection.preflight()` as part of the new preflight system ([b0b610d](https://github.com/dropseed/plain/commit/b0b610d461))
19
+ - Preflight check IDs have been renamed from numeric format (e.g., `plain.oauth.E001`) to descriptive names (e.g., `oauth.provider_in_db_not_in_settings`) ([cd96c97](https://github.com/dropseed/plain/commit/cd96c97b25))
20
+ - Preflight messages now provide clearer fix instructions directly in the `fix` attribute ([c7cde12](https://github.com/dropseed/plain/commit/c7cde12149))
21
+
22
+ ### Upgrade instructions
23
+
24
+ - If you have custom code that calls `OAuthConnection.check()`, update it to use `OAuthConnection.preflight()` instead
25
+ - If you have code that references specific preflight check IDs (e.g., `plain.oauth.E001`), update them to use the new descriptive format (e.g., `oauth.provider_in_db_not_in_settings`)
26
+
3
27
  ## [0.26.0](https://github.com/dropseed/plain/releases/plain-oauth@0.26.0) (2025-09-12)
4
28
 
5
29
  ### What's changed
plain/oauth/models.py CHANGED
@@ -5,7 +5,7 @@ from plain.auth import get_user_model
5
5
  from plain.exceptions import ValidationError
6
6
  from plain.models import transaction
7
7
  from plain.models.db import IntegrityError, OperationalError, ProgrammingError
8
- from plain.preflight import Error
8
+ from plain.preflight import PreflightResult
9
9
  from plain.runtime import SettingsReference
10
10
  from plain.utils import timezone
11
11
 
@@ -155,18 +155,11 @@ class OAuthConnection(models.Model):
155
155
  return connection
156
156
 
157
157
  @classmethod
158
- def check(cls, **kwargs):
158
+ def preflight(cls):
159
159
  """
160
160
  A system check for ensuring that provider_keys in the database are also present in settings.
161
-
162
- Note that the --database flag is required for this to work:
163
- plain check --database default
164
161
  """
165
- errors = super().check(**kwargs)
166
-
167
- database = kwargs.get("database", False)
168
- if not database:
169
- return errors
162
+ errors = super().preflight()
170
163
 
171
164
  from .providers import get_provider_keys
172
165
 
@@ -183,11 +176,11 @@ class OAuthConnection(models.Model):
183
176
 
184
177
  if keys_in_db - keys_in_settings:
185
178
  errors.append(
186
- Error(
187
- "The following OAuth providers are in the database but not in the settings: {}".format(
179
+ PreflightResult(
180
+ fix="The following OAuth providers are in the database but not in the settings: {}. Add these providers to your OAUTH_LOGIN_PROVIDERS setting or remove the corresponding OAuthConnection records.".format(
188
181
  ", ".join(keys_in_db - keys_in_settings)
189
182
  ),
190
- id="plain.oauth.E001",
183
+ id="oauth.provider_in_db_not_in_settings",
191
184
  )
192
185
  )
193
186
 
plain/oauth/providers.py CHANGED
@@ -4,7 +4,7 @@ from typing import Any
4
4
  from urllib.parse import urlencode
5
5
 
6
6
  from plain.auth import login as auth_login
7
- from plain.http import HttpRequest, Response, ResponseRedirect
7
+ from plain.http import Request, Response, ResponseRedirect
8
8
  from plain.runtime import settings
9
9
  from plain.urls import reverse
10
10
  from plain.utils.cache import add_never_cache_headers
@@ -65,7 +65,7 @@ class OAuthProvider:
65
65
  self.client_secret = client_secret
66
66
  self.scope = scope
67
67
 
68
- def get_authorization_url_params(self, *, request: HttpRequest) -> dict:
68
+ def get_authorization_url_params(self, *, request: Request) -> dict:
69
69
  return {
70
70
  "redirect_uri": self.get_callback_url(request=request),
71
71
  "client_id": self.get_client_id(),
@@ -77,13 +77,13 @@ class OAuthProvider:
77
77
  def refresh_oauth_token(self, *, oauth_token: OAuthToken) -> OAuthToken:
78
78
  raise NotImplementedError()
79
79
 
80
- def get_oauth_token(self, *, code: str, request: HttpRequest) -> OAuthToken:
80
+ def get_oauth_token(self, *, code: str, request: Request) -> OAuthToken:
81
81
  raise NotImplementedError()
82
82
 
83
83
  def get_oauth_user(self, *, oauth_token: OAuthToken) -> OAuthUser:
84
84
  raise NotImplementedError()
85
85
 
86
- def get_authorization_url(self, *, request: HttpRequest) -> str:
86
+ def get_authorization_url(self, *, request: Request) -> str:
87
87
  return self.authorization_url
88
88
 
89
89
  def get_client_id(self) -> str:
@@ -95,14 +95,14 @@ class OAuthProvider:
95
95
  def get_scope(self) -> str:
96
96
  return self.scope
97
97
 
98
- def get_callback_url(self, *, request: HttpRequest) -> str:
98
+ def get_callback_url(self, *, request: Request) -> str:
99
99
  url = reverse("oauth:callback", provider=self.provider_key)
100
100
  return request.build_absolute_uri(url)
101
101
 
102
102
  def generate_state(self) -> str:
103
103
  return get_random_string(length=32)
104
104
 
105
- def check_request_state(self, *, request: HttpRequest) -> None:
105
+ def check_request_state(self, *, request: Request) -> None:
106
106
  if error := request.query_params.get("error"):
107
107
  raise OAuthError(error)
108
108
 
@@ -117,7 +117,7 @@ class OAuthProvider:
117
117
  raise OAuthStateMismatchError()
118
118
 
119
119
  def handle_login_request(
120
- self, *, request: HttpRequest, redirect_to: str = ""
120
+ self, *, request: Request, redirect_to: str = ""
121
121
  ) -> Response:
122
122
  authorization_url = self.get_authorization_url(request=request)
123
123
  authorization_params = self.get_authorization_url_params(request=request)
@@ -138,11 +138,11 @@ class OAuthProvider:
138
138
  return self.get_redirect_response(redirect_url)
139
139
 
140
140
  def handle_connect_request(
141
- self, *, request: HttpRequest, redirect_to: str = ""
141
+ self, *, request: Request, redirect_to: str = ""
142
142
  ) -> Response:
143
143
  return self.handle_login_request(request=request, redirect_to=redirect_to)
144
144
 
145
- def handle_disconnect_request(self, *, request: HttpRequest) -> Response:
145
+ def handle_disconnect_request(self, *, request: Request) -> Response:
146
146
  provider_user_id = request.data["provider_user_id"]
147
147
  connection = OAuthConnection.query.get(
148
148
  provider_key=self.provider_key, provider_user_id=provider_user_id
@@ -151,7 +151,7 @@ class OAuthProvider:
151
151
  redirect_url = self.get_disconnect_redirect_url(request=request)
152
152
  return self.get_redirect_response(redirect_url)
153
153
 
154
- def handle_callback_request(self, *, request: HttpRequest) -> Response:
154
+ def handle_callback_request(self, *, request: Request) -> Response:
155
155
  self.check_request_state(request=request)
156
156
 
157
157
  oauth_token = self.get_oauth_token(
@@ -181,13 +181,13 @@ class OAuthProvider:
181
181
  redirect_url = self.get_login_redirect_url(request=request)
182
182
  return self.get_redirect_response(redirect_url)
183
183
 
184
- def login(self, *, request: HttpRequest, user: Any) -> None:
184
+ def login(self, *, request: Request, user: Any) -> None:
185
185
  auth_login(request=request, user=user)
186
186
 
187
- def get_login_redirect_url(self, *, request: HttpRequest) -> str:
187
+ def get_login_redirect_url(self, *, request: Request) -> str:
188
188
  return request.session.pop(SESSION_NEXT_KEY, "/")
189
189
 
190
- def get_disconnect_redirect_url(self, *, request: HttpRequest) -> str:
190
+ def get_disconnect_redirect_url(self, *, request: Request) -> str:
191
191
  return request.data.get("next", "/")
192
192
 
193
193
  def get_redirect_response(self, redirect_url: str) -> Response:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.oauth
3
- Version: 0.26.0
3
+ Version: 0.28.0
4
4
  Summary: Let users log in with OAuth providers.
5
5
  Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
6
6
  License-Expression: BSD-3-Clause
@@ -1,18 +1,18 @@
1
- plain/oauth/CHANGELOG.md,sha256=8n2YLJ2UJAucV_A52-_bSgugvQiydzYMM-oggPSvI_I,3248
1
+ plain/oauth/CHANGELOG.md,sha256=8tZG0u5Zk-TZHni3MjRSLBgIgWhkB_-aARlyL_OqQnI,4899
2
2
  plain/oauth/README.md,sha256=m3RRb01DLnoxBtzuYzESSe49OmsZ8P1R5_QsfCSRQgo,11077
3
3
  plain/oauth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  plain/oauth/admin.py,sha256=s259OnTWGeOv3nVl4hAV-lNAIE4d2ObbG_97ENC6TuY,1308
5
5
  plain/oauth/config.py,sha256=0Q4IILBKQbIaxqeL9WRTH5Cka-BO3c3SOj1AdQIAJgc,167
6
6
  plain/oauth/default_settings.py,sha256=dlN1J9vSOjjxPNLp-0qe-cLTqwM4E69ZAx_8lpxMhaM,28
7
7
  plain/oauth/exceptions.py,sha256=yoZsq8XgzstuwbE2ihoet0nzpw_sVZgDrwUauh6hhUs,546
8
- plain/oauth/models.py,sha256=4CMjpXOIie6mqqPLcneM1ZTNokd3d90lFNnaxcoI80g,6733
9
- plain/oauth/providers.py,sha256=hk4e-7WKZcou0-OWPV1x07JB4duef9hRFGeA9fANCoU,7791
8
+ plain/oauth/models.py,sha256=BKeJrfm93E1W5Zzf7z41hk0WvJe6p-EjZcZavmkGkRs,6668
9
+ plain/oauth/providers.py,sha256=LZ1k2VWbdcHtd_Etsdc6BH0qHWFZXsxZKNUPBxrr-xQ,7739
10
10
  plain/oauth/urls.py,sha256=FYzpQwhvZdcat8n3f7RyA-1Q21finKb8JEyakSOjXXg,696
11
11
  plain/oauth/views.py,sha256=J2NCa37YediBTi82CfRlmsb45hFT6gWN6zMaFHhsDMM,2410
12
12
  plain/oauth/migrations/0001_initial.py,sha256=0NjfF7F3szhUXkpK3JvN10Xkat1QR-VvnX6Oed9iFmo,1940
13
13
  plain/oauth/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  plain/oauth/templates/oauth/callback.html,sha256=4CJG0oAN0xYjw2IPkjaL7B4hwlf9um9LI4CTu50E-yE,173
15
- plain_oauth-0.26.0.dist-info/METADATA,sha256=pa7yWU-69bbXL19aWqr5BYmJdCWxNN04VKQfjiY9FnU,11482
16
- plain_oauth-0.26.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
- plain_oauth-0.26.0.dist-info/licenses/LICENSE,sha256=cvKM3OlqHx3ijD6e34zsSUkPvzl-ya3Dd63A6EHL94U,1500
18
- plain_oauth-0.26.0.dist-info/RECORD,,
15
+ plain_oauth-0.28.0.dist-info/METADATA,sha256=rV67ktS1nXSd5RfWQqjWs_mKYDVV67tNVeIUZcIpNxs,11482
16
+ plain_oauth-0.28.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
17
+ plain_oauth-0.28.0.dist-info/licenses/LICENSE,sha256=cvKM3OlqHx3ijD6e34zsSUkPvzl-ya3Dd63A6EHL94U,1500
18
+ plain_oauth-0.28.0.dist-info/RECORD,,