plain.oauth 0.28.0__tar.gz → 0.29.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 (40) hide show
  1. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/PKG-INFO +1 -1
  2. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/CHANGELOG.md +12 -0
  3. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/providers.py +15 -8
  4. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/views.py +2 -1
  5. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/pyproject.toml +1 -1
  6. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/settings.py +0 -1
  7. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/templates/index.html +2 -2
  8. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/urls.py +1 -0
  9. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/.gitignore +0 -0
  10. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/LICENSE +0 -0
  11. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/README.md +0 -0
  12. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/README.md +0 -0
  13. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/__init__.py +0 -0
  14. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/admin.py +0 -0
  15. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/config.py +0 -0
  16. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/default_settings.py +0 -0
  17. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/exceptions.py +0 -0
  18. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/migrations/0001_initial.py +0 -0
  19. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/migrations/__init__.py +0 -0
  20. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/models.py +0 -0
  21. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/templates/oauth/callback.html +0 -0
  22. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/plain/oauth/urls.py +0 -0
  23. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/provider_examples/__init__.py +0 -0
  24. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/provider_examples/bitbucket.py +0 -0
  25. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/provider_examples/github.py +0 -0
  26. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/provider_examples/gitlab.py +0 -0
  27. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/templates/base.html +0 -0
  28. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/templates/login.html +0 -0
  29. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/users/migrations/0001_initial.py +0 -0
  30. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/users/migrations/__init__.py +0 -0
  31. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/app/users/models.py +0 -0
  32. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/provider_tests/__init__.py +0 -0
  33. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/provider_tests/test_github.py +0 -0
  34. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/providers/__init__.py +0 -0
  35. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/providers/bitbucket.py +0 -0
  36. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/providers/github.py +0 -0
  37. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/providers/gitlab.py +0 -0
  38. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/test_backends.py +0 -0
  39. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/test_checks.py +0 -0
  40. {plain_oauth-0.28.0 → plain_oauth-0.29.0}/tests/test_providers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.oauth
3
- Version: 0.28.0
3
+ Version: 0.29.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,5 +1,17 @@
1
1
  # plain-oauth changelog
2
2
 
3
+ ## [0.29.0](https://github.com/dropseed/plain/releases/plain-oauth@0.29.0) (2025-10-02)
4
+
5
+ ### What's changed
6
+
7
+ - Removed direct access to `request.user` and `request.session` attributes in favor of using `get_request_user()` and `get_request_session()` functions ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
8
+ - Removed dependency on `AuthenticationMiddleware` from test settings ([154ee10](https://github.com/dropseed/plain/commit/154ee10375))
9
+
10
+ ### Upgrade instructions
11
+
12
+ - If you have custom OAuth providers or views that access `request.user`, update them to use `get_request_user(request)` from `plain.auth`
13
+ - If you have custom OAuth providers that access `request.session`, update them to use `get_request_session(request)` from `plain.sessions`
14
+
3
15
  ## [0.28.0](https://github.com/dropseed/plain/releases/plain-oauth@0.28.0) (2025-09-30)
4
16
 
5
17
  ### What's changed
@@ -4,8 +4,10 @@ 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.auth.requests import get_request_user
7
8
  from plain.http import Request, Response, ResponseRedirect
8
9
  from plain.runtime import settings
10
+ from plain.sessions import get_request_session
9
11
  from plain.urls import reverse
10
12
  from plain.utils.cache import add_never_cache_headers
11
13
  from plain.utils.crypto import get_random_string
@@ -111,8 +113,9 @@ class OAuthProvider:
111
113
  except KeyError as e:
112
114
  raise OAuthStateMissingError() from e
113
115
 
114
- expected_state = request.session.pop(SESSION_STATE_KEY)
115
- request.session.save() # Make sure the pop is saved (won't save on an exception)
116
+ session = get_request_session(request)
117
+ expected_state = session.pop(SESSION_STATE_KEY)
118
+ session.save() # Make sure the pop is saved (won't save on an exception)
116
119
  if not secrets.compare_digest(state, expected_state):
117
120
  raise OAuthStateMismatchError()
118
121
 
@@ -122,15 +125,17 @@ class OAuthProvider:
122
125
  authorization_url = self.get_authorization_url(request=request)
123
126
  authorization_params = self.get_authorization_url_params(request=request)
124
127
 
128
+ session = get_request_session(request)
129
+
125
130
  if "state" in authorization_params:
126
131
  # Store the state in the session so we can check on callback
127
- request.session[SESSION_STATE_KEY] = authorization_params["state"]
132
+ session[SESSION_STATE_KEY] = authorization_params["state"]
128
133
 
129
134
  # Store next url in session so we can get it on the callback request
130
135
  if redirect_to:
131
- request.session[SESSION_NEXT_KEY] = redirect_to
136
+ session[SESSION_NEXT_KEY] = redirect_to
132
137
  elif "next" in request.data:
133
- request.session[SESSION_NEXT_KEY] = request.data["next"]
138
+ session[SESSION_NEXT_KEY] = request.data["next"]
134
139
 
135
140
  # Sort authorization params for consistency
136
141
  sorted_authorization_params = sorted(authorization_params.items())
@@ -159,9 +164,10 @@ class OAuthProvider:
159
164
  )
160
165
  oauth_user = self.get_oauth_user(oauth_token=oauth_token)
161
166
 
162
- if request.user:
167
+ user = get_request_user(request)
168
+ if user:
163
169
  connection = OAuthConnection.connect(
164
- user=request.user,
170
+ user=user,
165
171
  provider_key=self.provider_key,
166
172
  oauth_token=oauth_token,
167
173
  oauth_user=oauth_user,
@@ -185,7 +191,8 @@ class OAuthProvider:
185
191
  auth_login(request=request, user=user)
186
192
 
187
193
  def get_login_redirect_url(self, *, request: Request) -> str:
188
- return request.session.pop(SESSION_NEXT_KEY, "/")
194
+ session = get_request_session(request)
195
+ return session.pop(SESSION_NEXT_KEY, "/")
189
196
 
190
197
  def get_disconnect_redirect_url(self, *, request: Request) -> str:
191
198
  return request.data.get("next", "/")
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
 
3
+ from plain.auth.requests import get_request_user
3
4
  from plain.auth.views import AuthViewMixin
4
5
  from plain.http import ResponseRedirect
5
6
  from plain.views import TemplateView, View
@@ -16,7 +17,7 @@ class OAuthLoginView(View):
16
17
  def post(self):
17
18
  request = self.request
18
19
  provider = self.url_kwargs["provider"]
19
- if request.user:
20
+ if get_request_user(request):
20
21
  return ResponseRedirect("/")
21
22
 
22
23
  provider_instance = get_oauth_provider_instance(provider_key=provider)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "plain.oauth"
3
- version = "0.28.0"
3
+ version = "0.29.0"
4
4
  description = "Let users log in with OAuth providers."
5
5
  authors = [{name = "Dave Gaeddert", email = "dave.gaeddert@dropseed.dev"}]
6
6
  license = "BSD-3-Clause"
@@ -11,7 +11,6 @@ INSTALLED_PACKAGES = [
11
11
  ]
12
12
  MIDDLEWARE = [
13
13
  "plain.sessions.middleware.SessionMiddleware",
14
- "plain.auth.middleware.AuthenticationMiddleware",
15
14
  ]
16
15
  AUTH_LOGIN_URL = "login"
17
16
  AUTH_USER_MODEL = "users.User"
@@ -1,11 +1,11 @@
1
1
  {% extends "base.html" %}
2
2
 
3
3
  {% block content %}
4
- Hello {{ request.user }}!
4
+ Hello {{ user }}!
5
5
 
6
6
  <h2>Existing connections</h2>
7
7
  <ul>
8
- {% for connection in request.user.oauth_connections.query.all() %}
8
+ {% for connection in user.oauth_connections.query.all() %}
9
9
  <li>
10
10
  {{ connection.provider_key }} [ID: {{ connection.provider_user_id }}]
11
11
  <form action="{{ url('oauth:disconnect', connection.provider_key) }}" method="post">
@@ -7,6 +7,7 @@ from plain.views import TemplateView
7
7
 
8
8
  class LoggedInView(AuthViewMixin, TemplateView):
9
9
  template_name = "index.html"
10
+ login_required = True
10
11
 
11
12
  def get_template_context(self):
12
13
  context = super().get_template_context()
File without changes
File without changes
File without changes