15
15
from authlib .common .security import generate_token
16
16
from authlib .integrations .requests_client import OAuth2Session
17
17
from django .conf import settings
18
+ from django .core .exceptions import SuspiciousOperation
18
19
from django .urls import reverse
19
20
20
21
if TYPE_CHECKING :
21
22
from typing import Self
22
23
24
+ from django .http import HttpRequest
25
+
23
26
from .models import LichessAccessToken
24
27
25
28
LICHESS_OAUTH2_SCOPES = ("board:play" ,)
@@ -104,7 +107,7 @@ def get_lichess_token_retrieval_via_oauth2_process_starting_url(
104
107
) -> str :
105
108
lichess_authorization_endpoint = f"{ settings .LICHESS_HOST } /oauth"
106
109
107
- client = _get_lichess_client ()
110
+ client = _get_lichess_oauth2_client ()
108
111
uri , state = client .create_authorization_url (
109
112
lichess_authorization_endpoint ,
110
113
response_type = "code" ,
@@ -117,14 +120,27 @@ def get_lichess_token_retrieval_via_oauth2_process_starting_url(
117
120
return uri
118
121
119
122
120
- def extract_lichess_token_from_oauth2_callback_url (
123
+ def check_csrf_state_from_oauth2_callback (
124
+ * , request : "HttpRequest" , context : LichessTokenRetrievalProcessContext
125
+ ):
126
+ """
127
+ Raises a SuspiciousOperation if the state from the request's query string
128
+ doesn't match the state from the short-lived cookie.
129
+ """
130
+ csrf_state_from_request = request .GET ["state" ]
131
+ csrf_state_from_short_lived_cookie = context .csrf_state
132
+ if csrf_state_from_short_lived_cookie != csrf_state_from_request :
133
+ raise SuspiciousOperation ("OAuth2 CSRF state mismatch" )
134
+
135
+
136
+ def fetch_lichess_token_from_oauth2_callback (
121
137
* ,
122
138
authorization_callback_response_url : str ,
123
139
context : LichessTokenRetrievalProcessContext ,
124
140
) -> LichessToken :
125
141
lichess_token_endpoint = f"{ settings .LICHESS_HOST } /api/token"
126
142
127
- client = _get_lichess_client ()
143
+ client = _get_lichess_oauth2_client ()
128
144
token_as_dict = client .fetch_token (
129
145
lichess_token_endpoint ,
130
146
authorization_response = authorization_callback_response_url ,
@@ -146,7 +162,7 @@ def _get_lichess_oauth2_zakuchess_redirect_uri(
146
162
)
147
163
148
164
149
- def _get_lichess_client () -> OAuth2Session :
165
+ def _get_lichess_oauth2_client () -> OAuth2Session :
150
166
return OAuth2Session (
151
167
client_id = settings .LICHESS_CLIENT_ID ,
152
168
code_challenge_method = "S256" ,
0 commit comments