plain.oauth 0.24.1__tar.gz → 0.25.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.24.1 → plain_oauth-0.25.0}/PKG-INFO +56 -27
  2. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/CHANGELOG.md +22 -0
  3. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/README.md +54 -25
  4. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/models.py +2 -2
  5. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/pyproject.toml +2 -2
  6. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/templates/index.html +0 -2
  7. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/templates/login.html +0 -3
  8. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/.gitignore +0 -0
  9. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/LICENSE +0 -0
  10. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/README.md +0 -0
  11. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/__init__.py +0 -0
  12. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/admin.py +0 -0
  13. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/config.py +0 -0
  14. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/default_settings.py +0 -0
  15. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/exceptions.py +0 -0
  16. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/migrations/0001_initial.py +0 -0
  17. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/migrations/__init__.py +0 -0
  18. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/providers.py +0 -0
  19. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/templates/oauth/callback.html +0 -0
  20. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/urls.py +0 -0
  21. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/plain/oauth/views.py +0 -0
  22. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/provider_examples/__init__.py +0 -0
  23. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/provider_examples/bitbucket.py +0 -0
  24. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/provider_examples/github.py +0 -0
  25. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/provider_examples/gitlab.py +0 -0
  26. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/settings.py +0 -0
  27. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/templates/base.html +0 -0
  28. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/urls.py +0 -0
  29. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/users/migrations/0001_initial.py +0 -0
  30. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/users/migrations/__init__.py +0 -0
  31. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/app/users/models.py +0 -0
  32. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/provider_tests/__init__.py +0 -0
  33. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/provider_tests/test_github.py +0 -0
  34. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/providers/__init__.py +0 -0
  35. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/providers/bitbucket.py +0 -0
  36. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/providers/github.py +0 -0
  37. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/providers/gitlab.py +0 -0
  38. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/test_backends.py +0 -0
  39. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/test_checks.py +0 -0
  40. {plain_oauth-0.24.1 → plain_oauth-0.25.0}/tests/test_providers.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plain.oauth
3
- Version: 0.24.1
4
- Summary: OAuth login and API access for Plain.
3
+ Version: 0.25.0
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
7
7
  License-File: LICENSE
@@ -14,7 +14,19 @@ Description-Content-Type: text/markdown
14
14
 
15
15
  # plain.oauth
16
16
 
17
- Let users log in with OAuth providers.
17
+ **Let users log in with OAuth providers.**
18
+
19
+ - [Overview](#overview)
20
+ - [Usage](#usage)
21
+ - [Basic setup example](#basic-setup-example)
22
+ - [Handling OAuth errors](#handling-oauth-errors)
23
+ - [Connecting and disconnecting OAuth accounts](#connecting-and-disconnecting-oauth-accounts)
24
+ - [Using a saved access token](#using-a-saved-access-token)
25
+ - [Using the Django system check](#using-the-django-system-check)
26
+ - [FAQs](#faqs)
27
+ - [Installation](#installation)
28
+
29
+ ## Overview
18
30
 
19
31
  [Watch on YouTube (3 mins) →](https://www.youtube.com/watch?v=UxbxBa6AFsU)
20
32
 
@@ -31,11 +43,9 @@ There are three OAuth flows that it makes possible:
31
43
 
32
44
  ## Usage
33
45
 
34
- Install the package from PyPi:
46
+ ### Basic setup example
35
47
 
36
- ```sh
37
- pip install plain-oauth
38
- ```
48
+ Here's a complete example showing how to set up OAuth login with GitHub:
39
49
 
40
50
  Add `plain.oauth` to your `INSTALLED_PACKAGES` in `settings.py`:
41
51
 
@@ -46,19 +56,24 @@ INSTALLED_PACKAGES = [
46
56
  ]
47
57
  ```
48
58
 
49
- In your `urls.py`, include `plain.oauth.urls`:
59
+ In your `urls.py`, include the [`OAuthRouter`](./urls.py#OAuthRouter):
50
60
 
51
61
  ```python
52
- urlpatterns = [
53
- path("oauth/", include("plain.oauth.urls")),
54
- ...
55
- ]
62
+ from plain.oauth.urls import OAuthRouter
63
+ from plain.urls import Router, include
64
+
65
+ class AppRouter(Router):
66
+ namespace = ""
67
+ urls = [
68
+ include("oauth/", OAuthRouter),
69
+ # ...
70
+ ]
56
71
  ```
57
72
 
58
73
  Then run migrations:
59
74
 
60
75
  ```sh
61
- python manage.py migrate plain.oauth
76
+ plain migrate plain.oauth
62
77
  ```
63
78
 
64
79
  Create a new OAuth provider ([or copy one from our examples](https://github.com/forgepackages/plain-oauth/tree/master/provider_examples)):
@@ -70,12 +85,12 @@ import requests
70
85
  from plain.oauth.providers import OAuthProvider, OAuthToken, OAuthUser
71
86
 
72
87
 
73
- class ExampleOAuthProvider(OAuthProvider):
74
- authorization_url = "https://example.com/login/oauth/authorize"
88
+ class GitHubOAuthProvider(OAuthProvider):
89
+ authorization_url = "https://github.com/login/oauth/authorize"
75
90
 
76
91
  def get_oauth_token(self, *, code, request):
77
92
  response = requests.post(
78
- "https://example.com/login/oauth/token",
93
+ "https://github.com/login/oauth/access_token",
79
94
  headers={
80
95
  "Accept": "application/json",
81
96
  },
@@ -93,7 +108,7 @@ class ExampleOAuthProvider(OAuthProvider):
93
108
 
94
109
  def get_oauth_user(self, *, oauth_token):
95
110
  response = requests.get(
96
- "https://example.com/api/user",
111
+ "https://api.github.com/user",
97
112
  headers={
98
113
  "Accept": "application/json",
99
114
  "Authorization": f"token {oauth_token.access_token}",
@@ -140,7 +155,6 @@ Then add a login button (which is a form using POST rather than a basic link, fo
140
155
  ```html
141
156
  <h1>Login</h1>
142
157
  <form action="{% url 'oauth:login' 'github' %}" method="post">
143
- {{ csrf_input }}
144
158
  <button type="submit">Login with GitHub</button>
145
159
  </form>
146
160
  ```
@@ -150,8 +164,6 @@ your OAuth callback will be something like `https://example.com/oauth/{provider}
150
164
 
151
165
  That's pretty much it!
152
166
 
153
- ## Advanced usage
154
-
155
167
  ### Handling OAuth errors
156
168
 
157
169
  The most common error you'll run into is if an existing user clicks a login button,
@@ -192,7 +204,6 @@ Hello {{ request.user }}!
192
204
  <li>
193
205
  {{ connection.provider_key }} [ID: {{ connection.provider_user_id }}]
194
206
  <form action="{% url 'oauth:disconnect' connection.provider_key %}" method="post">
195
- {{ csrf_input }}
196
207
  <input type="hidden" name="provider_user_id" value="{{ connection.provider_user_id }}">
197
208
  <button type="submit">Disconnect</button>
198
209
  </form>
@@ -206,7 +217,6 @@ Hello {{ request.user }}!
206
217
  <li>
207
218
  {{ provider_key}}
208
219
  <form action="{% url 'oauth:connect' provider_key %}" method="post">
209
- {{ csrf_input }}
210
220
  <button type="submit">Connect</button>
211
221
  </form>
212
222
  </li>
@@ -216,7 +226,7 @@ Hello {{ request.user }}!
216
226
  {% endblock %}
217
227
  ```
218
228
 
219
- The `get_provider_keys` function can help populate the list of options:
229
+ The [`get_provider_keys`](./providers.py#get_provider_keys) function can help populate the list of options:
220
230
 
221
231
  ```python
222
232
  from plain.oauth.providers import get_provider_keys
@@ -255,12 +265,12 @@ This library comes with a Django system check to ensure you don't _remove_ a pro
255
265
  You do need to specify the `--database` for this to run when using the check command by itself:
256
266
 
257
267
  ```sh
258
- python manage.py check --database default
268
+ plain check --database default
259
269
  ```
260
270
 
261
271
  ## FAQs
262
272
 
263
- ### How is this different from [Django OAuth libraries](https://djangopackages.org/grids/g/oauth/)?
273
+ #### How is this different from [Django OAuth libraries](https://djangopackages.org/grids/g/oauth/)?
264
274
 
265
275
  The short answer is that _it does less_.
266
276
 
@@ -279,7 +289,7 @@ and the implications for doing it one way or another.
279
289
  The other popular OAuth libraries have similar issues,
280
290
  and I think their _weight_ outweighs their usefulness for 80% of the use cases.
281
291
 
282
- ### Why aren't providers included in the library itself?
292
+ #### Why aren't providers included in the library itself?
283
293
 
284
294
  One thing you'll notice is that we don't have a long list of pre-configured providers in this library.
285
295
  Instead, we have some examples (which you can usually just copy, paste, and use) and otherwise encourage you to wire up the provider yourself.
@@ -302,7 +312,7 @@ You don't need to try to run changes through us or wait for an upstream update.
302
312
  You're welcome to contribute an example to this repo,
303
313
  and there won't be an expectation that it "works perfectly for every use case until the end of time".
304
314
 
305
- ### Redirect/callback URL mismatch in local development?
315
+ #### Redirect/callback URL mismatch in local development?
306
316
 
307
317
  If you're doing local development through a proxy/tunnel like [ngrok](https://ngrok.com/),
308
318
  then the callback URL might be automatically built as `http` instead of `https`.
@@ -312,3 +322,22 @@ This is the Django setting you're probably looking for:
312
322
  ```python
313
323
  HTTPS_PROXY_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
314
324
  ```
325
+
326
+ ## Installation
327
+
328
+ Install the `plain.oauth` package from [PyPI](https://pypi.org/project/plain.oauth/):
329
+
330
+ ```bash
331
+ uv add plain.oauth
332
+ ```
333
+
334
+ After installation, follow the basic setup example in the [Usage](#usage) section above to:
335
+
336
+ 1. Add `plain.oauth` to your `INSTALLED_PACKAGES`
337
+ 2. Include the OAuth router in your URLs
338
+ 3. Run migrations
339
+ 4. Create an OAuth provider class
340
+ 5. Configure OAuth settings
341
+ 6. Add login buttons to your templates
342
+
343
+ For a complete working example, see the [Basic setup example](#basic-setup-example) which shows how to set up GitHub OAuth login.
@@ -1,5 +1,27 @@
1
1
  # plain-oauth changelog
2
2
 
3
+ ## [0.25.0](https://github.com/dropseed/plain/releases/plain-oauth@0.25.0) (2025-08-19)
4
+
5
+ ### What's changed
6
+
7
+ - Removed requirement for manual `{{ csrf_input }}` in OAuth forms - CSRF protection now uses `Sec-Fetch-Site` headers automatically ([9551508](https://github.com/dropseed/plain/commit/955150800c))
8
+
9
+ ### Upgrade instructions
10
+
11
+ - Remove `{{ csrf_input }}` from any OAuth forms in your templates (login, connect, disconnect forms) - CSRF protection is now handled automatically
12
+
13
+ ## [0.24.2](https://github.com/dropseed/plain/releases/plain-oauth@0.24.2) (2025-08-05)
14
+
15
+ ### What's changed
16
+
17
+ - Updated documentation to use `plain` commands instead of `python manage.py` references ([8071854](https://github.com/dropseed/plain/commit/8071854d61))
18
+ - Improved README with better structure, table of contents, and more comprehensive examples ([4ebecd1](https://github.com/dropseed/plain/commit/4ebecd1856))
19
+ - Fixed router setup documentation in URLs section ([48caf10](https://github.com/dropseed/plain/commit/48caf105da))
20
+
21
+ ### Upgrade instructions
22
+
23
+ - No changes required
24
+
3
25
  ## [0.24.1](https://github.com/dropseed/plain/releases/plain-oauth@0.24.1) (2025-07-23)
4
26
 
5
27
  ### What's changed
@@ -1,6 +1,18 @@
1
1
  # plain.oauth
2
2
 
3
- Let users log in with OAuth providers.
3
+ **Let users log in with OAuth providers.**
4
+
5
+ - [Overview](#overview)
6
+ - [Usage](#usage)
7
+ - [Basic setup example](#basic-setup-example)
8
+ - [Handling OAuth errors](#handling-oauth-errors)
9
+ - [Connecting and disconnecting OAuth accounts](#connecting-and-disconnecting-oauth-accounts)
10
+ - [Using a saved access token](#using-a-saved-access-token)
11
+ - [Using the Django system check](#using-the-django-system-check)
12
+ - [FAQs](#faqs)
13
+ - [Installation](#installation)
14
+
15
+ ## Overview
4
16
 
5
17
  [Watch on YouTube (3 mins) →](https://www.youtube.com/watch?v=UxbxBa6AFsU)
6
18
 
@@ -17,11 +29,9 @@ There are three OAuth flows that it makes possible:
17
29
 
18
30
  ## Usage
19
31
 
20
- Install the package from PyPi:
32
+ ### Basic setup example
21
33
 
22
- ```sh
23
- pip install plain-oauth
24
- ```
34
+ Here's a complete example showing how to set up OAuth login with GitHub:
25
35
 
26
36
  Add `plain.oauth` to your `INSTALLED_PACKAGES` in `settings.py`:
27
37
 
@@ -32,19 +42,24 @@ INSTALLED_PACKAGES = [
32
42
  ]
33
43
  ```
34
44
 
35
- In your `urls.py`, include `plain.oauth.urls`:
45
+ In your `urls.py`, include the [`OAuthRouter`](./urls.py#OAuthRouter):
36
46
 
37
47
  ```python
38
- urlpatterns = [
39
- path("oauth/", include("plain.oauth.urls")),
40
- ...
41
- ]
48
+ from plain.oauth.urls import OAuthRouter
49
+ from plain.urls import Router, include
50
+
51
+ class AppRouter(Router):
52
+ namespace = ""
53
+ urls = [
54
+ include("oauth/", OAuthRouter),
55
+ # ...
56
+ ]
42
57
  ```
43
58
 
44
59
  Then run migrations:
45
60
 
46
61
  ```sh
47
- python manage.py migrate plain.oauth
62
+ plain migrate plain.oauth
48
63
  ```
49
64
 
50
65
  Create a new OAuth provider ([or copy one from our examples](https://github.com/forgepackages/plain-oauth/tree/master/provider_examples)):
@@ -56,12 +71,12 @@ import requests
56
71
  from plain.oauth.providers import OAuthProvider, OAuthToken, OAuthUser
57
72
 
58
73
 
59
- class ExampleOAuthProvider(OAuthProvider):
60
- authorization_url = "https://example.com/login/oauth/authorize"
74
+ class GitHubOAuthProvider(OAuthProvider):
75
+ authorization_url = "https://github.com/login/oauth/authorize"
61
76
 
62
77
  def get_oauth_token(self, *, code, request):
63
78
  response = requests.post(
64
- "https://example.com/login/oauth/token",
79
+ "https://github.com/login/oauth/access_token",
65
80
  headers={
66
81
  "Accept": "application/json",
67
82
  },
@@ -79,7 +94,7 @@ class ExampleOAuthProvider(OAuthProvider):
79
94
 
80
95
  def get_oauth_user(self, *, oauth_token):
81
96
  response = requests.get(
82
- "https://example.com/api/user",
97
+ "https://api.github.com/user",
83
98
  headers={
84
99
  "Accept": "application/json",
85
100
  "Authorization": f"token {oauth_token.access_token}",
@@ -126,7 +141,6 @@ Then add a login button (which is a form using POST rather than a basic link, fo
126
141
  ```html
127
142
  <h1>Login</h1>
128
143
  <form action="{% url 'oauth:login' 'github' %}" method="post">
129
- {{ csrf_input }}
130
144
  <button type="submit">Login with GitHub</button>
131
145
  </form>
132
146
  ```
@@ -136,8 +150,6 @@ your OAuth callback will be something like `https://example.com/oauth/{provider}
136
150
 
137
151
  That's pretty much it!
138
152
 
139
- ## Advanced usage
140
-
141
153
  ### Handling OAuth errors
142
154
 
143
155
  The most common error you'll run into is if an existing user clicks a login button,
@@ -178,7 +190,6 @@ Hello {{ request.user }}!
178
190
  <li>
179
191
  {{ connection.provider_key }} [ID: {{ connection.provider_user_id }}]
180
192
  <form action="{% url 'oauth:disconnect' connection.provider_key %}" method="post">
181
- {{ csrf_input }}
182
193
  <input type="hidden" name="provider_user_id" value="{{ connection.provider_user_id }}">
183
194
  <button type="submit">Disconnect</button>
184
195
  </form>
@@ -192,7 +203,6 @@ Hello {{ request.user }}!
192
203
  <li>
193
204
  {{ provider_key}}
194
205
  <form action="{% url 'oauth:connect' provider_key %}" method="post">
195
- {{ csrf_input }}
196
206
  <button type="submit">Connect</button>
197
207
  </form>
198
208
  </li>
@@ -202,7 +212,7 @@ Hello {{ request.user }}!
202
212
  {% endblock %}
203
213
  ```
204
214
 
205
- The `get_provider_keys` function can help populate the list of options:
215
+ The [`get_provider_keys`](./providers.py#get_provider_keys) function can help populate the list of options:
206
216
 
207
217
  ```python
208
218
  from plain.oauth.providers import get_provider_keys
@@ -241,12 +251,12 @@ This library comes with a Django system check to ensure you don't _remove_ a pro
241
251
  You do need to specify the `--database` for this to run when using the check command by itself:
242
252
 
243
253
  ```sh
244
- python manage.py check --database default
254
+ plain check --database default
245
255
  ```
246
256
 
247
257
  ## FAQs
248
258
 
249
- ### How is this different from [Django OAuth libraries](https://djangopackages.org/grids/g/oauth/)?
259
+ #### How is this different from [Django OAuth libraries](https://djangopackages.org/grids/g/oauth/)?
250
260
 
251
261
  The short answer is that _it does less_.
252
262
 
@@ -265,7 +275,7 @@ and the implications for doing it one way or another.
265
275
  The other popular OAuth libraries have similar issues,
266
276
  and I think their _weight_ outweighs their usefulness for 80% of the use cases.
267
277
 
268
- ### Why aren't providers included in the library itself?
278
+ #### Why aren't providers included in the library itself?
269
279
 
270
280
  One thing you'll notice is that we don't have a long list of pre-configured providers in this library.
271
281
  Instead, we have some examples (which you can usually just copy, paste, and use) and otherwise encourage you to wire up the provider yourself.
@@ -288,7 +298,7 @@ You don't need to try to run changes through us or wait for an upstream update.
288
298
  You're welcome to contribute an example to this repo,
289
299
  and there won't be an expectation that it "works perfectly for every use case until the end of time".
290
300
 
291
- ### Redirect/callback URL mismatch in local development?
301
+ #### Redirect/callback URL mismatch in local development?
292
302
 
293
303
  If you're doing local development through a proxy/tunnel like [ngrok](https://ngrok.com/),
294
304
  then the callback URL might be automatically built as `http` instead of `https`.
@@ -298,3 +308,22 @@ This is the Django setting you're probably looking for:
298
308
  ```python
299
309
  HTTPS_PROXY_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
300
310
  ```
311
+
312
+ ## Installation
313
+
314
+ Install the `plain.oauth` package from [PyPI](https://pypi.org/project/plain.oauth/):
315
+
316
+ ```bash
317
+ uv add plain.oauth
318
+ ```
319
+
320
+ After installation, follow the basic setup example in the [Usage](#usage) section above to:
321
+
322
+ 1. Add `plain.oauth` to your `INSTALLED_PACKAGES`
323
+ 2. Include the OAuth router in your URLs
324
+ 3. Run migrations
325
+ 4. Create an OAuth provider class
326
+ 5. Configure OAuth settings
327
+ 6. Add login buttons to your templates
328
+
329
+ For a complete working example, see the [Basic setup example](#basic-setup-example) which shows how to set up GitHub OAuth login.
@@ -160,7 +160,7 @@ class OAuthConnection(models.Model):
160
160
  A system check for ensuring that provider_keys in the database are also present in settings.
161
161
 
162
162
  Note that the --database flag is required for this to work:
163
- python manage.py check --database default
163
+ plain check --database default
164
164
  """
165
165
  errors = super().check(**kwargs)
166
166
 
@@ -175,7 +175,7 @@ class OAuthConnection(models.Model):
175
175
  cls.objects.values_list("provider_key", flat=True).distinct()
176
176
  )
177
177
  except (OperationalError, ProgrammingError):
178
- # Check runs on manage.py migrate, and the table may not exist yet
178
+ # Check runs on plain migrate, and the table may not exist yet
179
179
  # or it may not be installed on the particular database intentionally
180
180
  return errors
181
181
 
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "plain.oauth"
3
- version = "0.24.1"
4
- description = "OAuth login and API access for Plain."
3
+ version = "0.25.0"
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"
7
7
  readme = "README.md"
@@ -9,7 +9,6 @@ Hello {{ request.user }}!
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">
12
- {{ csrf_input }}
13
12
  <input type="hidden" name="provider_user_id" value="{{ connection.provider_user_id }}">
14
13
  <button type="submit">Disconnect</button>
15
14
  </form>
@@ -23,7 +22,6 @@ Hello {{ request.user }}!
23
22
  <li>
24
23
  {{ provider_key}}
25
24
  <form action="{{ url('oauth:connect', provider_key) }}" method="post">
26
- {{ csrf_input }}
27
25
  <button type="submit">Connect</button>
28
26
  </form>
29
27
  </li>
@@ -3,15 +3,12 @@
3
3
  {% block content %}
4
4
  <h1>Login</h1>
5
5
  <form action="{% url 'oauth:login' 'github' %}" method="post">
6
- {{ csrf_input }}
7
6
  <button type="submit">Login with GitHub</button>
8
7
  </form>
9
8
  <form action="{% url 'oauth:login' 'gitlab' %}" method="post">
10
- {{ csrf_input }}
11
9
  <button type="submit">Login with GitLab</button>
12
10
  </form>
13
11
  <form action="{% url 'oauth:login' 'bitbucket' %}" method="post">
14
- {{ csrf_input }}
15
12
  <button type="submit">Login with Bitbucket</button>
16
13
  </form>
17
14
  {% endblock %}
File without changes
File without changes
File without changes