@@ -1149,7 +1149,7 @@ and it is maintained by the developer community group
11491149import logging
11501150
11511151from django.core.exceptions import ImproperlyConfigured
1152- from django.http import HttpResponseForbidden
1152+ ~~ from django.http import HttpResponseForbidden
11531153
11541154from ..exceptions import FatalClientError
11551155from ..scopes import get_scopes_backend
@@ -1161,185 +1161,7 @@ log = logging.getLogger("oauth2_provider")
11611161SAFE_HTTP_METHODS = [" GET" , " HEAD" , " OPTIONS" ]
11621162
11631163
1164- class OAuthLibMixin (object ):
1165- """
1166- This mixin decouples Django OAuth Toolkit from OAuthLib.
1167-
1168- Users can configure the Server, Validator and OAuthlibCore
1169- classes used by this mixin by setting the following class
1170- variables:
1171-
1172- * server_class
1173- * validator_class
1174- * oauthlib_backend_class
1175-
1176- """
1177- server_class = None
1178- validator_class = None
1179- oauthlib_backend_class = None
1180-
1181- @ classmethod
1182- def get_server_class (cls ):
1183- """
1184- Return the OAuthlib server class to use
1185- """
1186- if cls .server_class is None :
1187- raise ImproperlyConfigured(
1188- " OAuthLibMixin requires either a definition of 'server_class'"
1189- " or an implementation of 'get_server_class()'" )
1190- else :
1191- return cls .server_class
1192-
1193- @ classmethod
1194- def get_validator_class (cls ):
1195- """
1196- Return the RequestValidator implementation class to use
1197- """
1198- if cls .validator_class is None :
1199- raise ImproperlyConfigured(
1200- " OAuthLibMixin requires either a definition of 'validator_class'"
1201- " or an implementation of 'get_validator_class()'" )
1202- else :
1203- return cls .validator_class
1204-
1205- @ classmethod
1206- def get_oauthlib_backend_class (cls ):
1207- """
1208- Return the OAuthLibCore implementation class to use
1209- """
1210- if cls .oauthlib_backend_class is None :
1211- raise ImproperlyConfigured(
1212- " OAuthLibMixin requires either a definition of 'oauthlib_backend_class'"
1213- " or an implementation of 'get_oauthlib_backend_class()'" )
1214- else :
1215- return cls .oauthlib_backend_class
1216-
1217- @ classmethod
1218- def get_server (cls ):
1219- """
1220- Return an instance of `server_class` initialized with a `validator_class`
1221- object
1222- """
1223- server_class = cls .get_server_class()
1224- validator_class = cls .get_validator_class()
1225- return server_class(validator_class())
1226-
1227- @ classmethod
1228- def get_oauthlib_core (cls ):
1229- """
1230- Cache and return `OAuthlibCore` instance so it will be created only on first request
1231- """
1232- if not hasattr (cls , " _oauthlib_core" ):
1233- server = cls .get_server()
1234- core_class = cls .get_oauthlib_backend_class()
1235- cls ._oauthlib_core = core_class(server)
1236- return cls ._oauthlib_core
1237-
1238- def validate_authorization_request (self , request ):
1239- """
1240- A wrapper method that calls validate_authorization_request on `server_class` instance.
1241-
1242- :param request: The current django.http.HttpRequest object
1243- """
1244- core = self .get_oauthlib_core()
1245- return core.validate_authorization_request(request)
1246-
1247- def create_authorization_response (self , request , scopes , credentials , allow ):
1248- """
1249- A wrapper method that calls create_authorization_response on `server_class`
1250- instance.
1251-
1252- :param request: The current django.http.HttpRequest object
1253- :param scopes: A space-separated string of provided scopes
1254- :param credentials: Authorization credentials dictionary containing
1255- `client_id`, `state`, `redirect_uri`, `response_type`
1256- :param allow: True if the user authorize the client, otherwise False
1257- """
1258- # TODO : move this scopes conversion from and to string into a utils function
1259- scopes = scopes.split(" " ) if scopes else []
1260-
1261- core = self .get_oauthlib_core()
1262- return core.create_authorization_response(request, scopes, credentials, allow)
1263-
1264- def create_token_response (self , request ):
1265- """
1266- A wrapper method that calls create_token_response on `server_class` instance.
1267-
1268- :param request: The current django.http.HttpRequest object
1269- """
1270- core = self .get_oauthlib_core()
1271- return core.create_token_response(request)
1272-
1273- def create_revocation_response (self , request ):
1274- """
1275- A wrapper method that calls create_revocation_response on the
1276- `server_class` instance.
1277-
1278- :param request: The current django.http.HttpRequest object
1279- """
1280- core = self .get_oauthlib_core()
1281- return core.create_revocation_response(request)
1282-
1283- def verify_request (self , request ):
1284- """
1285- A wrapper method that calls verify_request on `server_class` instance.
1286-
1287- :param request: The current django.http.HttpRequest object
1288- """
1289- core = self .get_oauthlib_core()
1290- return core.verify_request(request, scopes = self .get_scopes())
1291-
1292- def get_scopes (self ):
1293- """
1294- This should return the list of scopes required to access the resources.
1295- By default it returns an empty list.
1296- """
1297- return []
1298-
1299- def error_response (self , error , ** kwargs ):
1300- """
1301- Return an error to be displayed to the resource owner if anything goes awry.
1302-
1303- :param error: :attr:`OAuthToolkitError`
1304- """
1305- oauthlib_error = error.oauthlib_error
1306-
1307- redirect_uri = oauthlib_error.redirect_uri or " "
1308- separator = " &" if " ?" in redirect_uri else " ?"
1309-
1310- error_response = {
1311- " error" : oauthlib_error,
1312- " url" : redirect_uri + separator + oauthlib_error.urlencoded,
1313- }
1314- error_response.update(kwargs)
1315-
1316- # If we got a malicious redirect_uri or client_id, we will *not* redirect back to the URL.
1317- if isinstance (error, FatalClientError):
1318- redirect = False
1319- else :
1320- redirect = True
1321-
1322- return redirect, error_response
1323-
1324-
1325- class ScopedResourceMixin (object ):
1326- """
1327- Helper mixin that implements "scopes handling" behaviour
1328- """
1329- required_scopes = None
1330-
1331- def get_scopes (self , * args , ** kwargs ):
1332- """
1333- Return the scopes needed to access the resource
1334-
1335- :param args: Support scopes injections from the outside (not yet implemented)
1336- """
1337- if self .required_scopes is None :
1338- raise ImproperlyConfigured(
1339- " ProtectedResourceMixin requires either a definition of 'required_scopes'"
1340- " or an implementation of 'get_scopes()'" )
1341- else :
1342- return self .required_scopes
1164+ # # ... source code abbreviated to get to the examples ...
13431165
13441166
13451167class ProtectedResourceMixin (OAuthLibMixin ):
@@ -1353,12 +1175,12 @@ class ProtectedResourceMixin(OAuthLibMixin):
13531175 return super ().dispatch(request, * args, ** kwargs)
13541176
13551177 # check if the request is valid and the protected resource may be accessed
1356- valid, r = self .verify_request(request)
1357- if valid:
1358- request.resource_owner = r.user
1359- return super ().dispatch(request, * args, ** kwargs)
1360- else :
1361- return HttpResponseForbidden()
1178+ ~~ valid, r = self .verify_request(request)
1179+ ~~ if valid:
1180+ ~~ request.resource_owner = r.user
1181+ ~~ return super ().dispatch(request, * args, ** kwargs)
1182+ ~~ else :
1183+ ~~ return HttpResponseForbidden()
13621184
13631185
13641186class ReadWriteScopedResourceMixin (ScopedResourceMixin , OAuthLibMixin ):
@@ -1407,22 +1229,29 @@ under the
14071229[ ** wagtail / wagtail / tests / middleware.py** ] ( https://github.com/wagtail/wagtail/blob/master/wagtail/tests/middleware.py )
14081230
14091231``` python
1410- from django.http import HttpResponseForbidden
1232+ # middleware.py
1233+ ~~ from django.http import HttpResponseForbidden
14111234from django.utils.deprecation import MiddlewareMixin
14121235
14131236
14141237class BlockDodgyUserAgentMiddleware (MiddlewareMixin ):
1415- # Used to test that we're correctly handling responses returned from middleware during page
1416- # previews. If a client with user agent "EvilHacker" calls an admin view that performs a
1417- # preview, the request to /admin/... will pass this middleware, but the fake request used for
1418- # the preview (which keeps the user agent header, but uses the URL path of the front-end page)
1419- # will trigger a Forbidden response. In this case, the expected behaviour is to return that
1420- # response back to the user.
1238+ """ Used to test that we're correctly handling responses
1239+ returned from middleware during page
1240+ previews. If a client with user agent "EvilHacker" calls
1241+ an admin view that performs a
1242+ preview, the request to /admin/... will pass this
1243+ middleware, but the fake request used for
1244+ the preview (which keeps the user agent header,
1245+ but uses the URL path of the front-end page)
1246+ will trigger a Forbidden response. In this case,
1247+ the expected behaviour is to return that
1248+ response back to the user.
1249+ """
14211250
14221251 def process_request (self , request ):
1423- if not request.path.startswith(' /admin/' ) and request.META .get(' HTTP_USER_AGENT' ) == ' EvilHacker' :
1424- return HttpResponseForbidden(" Forbidden" )
1252+ ~~ if not request.path.startswith(' /admin/' ) and \
1253+ ~~ request.META .get(' HTTP_USER_AGENT' ) == ' EvilHacker' :
1254+ ~~ return HttpResponseForbidden(" Forbidden" )
14251255
14261256```
14271257
1428-
0 commit comments