1import logging
2
3log = logging.getLogger(__name__)
4
5
6class Dispatcher:
7 default_grant = None
8 oidc_grant = None
9
10
11class AuthorizationCodeGrantDispatcher(Dispatcher):
12 """
13 This is an adapter class that will route simple Authorization Code
14 requests, those that have `response_type=code` and a scope including
15 `openid` to either the `default_grant` or the `oidc_grant` based on
16 the scopes requested.
17 """
18 def __init__(self, default_grant=None, oidc_grant=None):
19 self.default_grant = default_grant
20 self.oidc_grant = oidc_grant
21
22 def _handler_for_request(self, request):
23 handler = self.default_grant
24
25 if request.scopes and "openid" in request.scopes:
26 handler = self.oidc_grant
27
28 log.debug('Selecting handler for request %r.', handler)
29 return handler
30
31 def create_authorization_response(self, request, token_handler):
32 """Read scope and route to the designated handler."""
33 return self._handler_for_request(request).create_authorization_response(request, token_handler)
34
35 def validate_authorization_request(self, request):
36 """Read scope and route to the designated handler."""
37 return self._handler_for_request(request).validate_authorization_request(request)
38
39
40class ImplicitTokenGrantDispatcher(Dispatcher):
41 """
42 This is an adapter class that will route simple Authorization
43 requests, those that have `id_token` in `response_type` and a scope
44 including `openid` to either the `default_grant` or the `oidc_grant`
45 based on the scopes requested.
46 """
47 def __init__(self, default_grant=None, oidc_grant=None):
48 self.default_grant = default_grant
49 self.oidc_grant = oidc_grant
50
51 def _handler_for_request(self, request):
52 handler = self.default_grant
53
54 if request.scopes and "openid" in request.scopes and 'id_token' in request.response_type:
55 handler = self.oidc_grant
56
57 log.debug('Selecting handler for request %r.', handler)
58 return handler
59
60 def create_authorization_response(self, request, token_handler):
61 """Read scope and route to the designated handler."""
62 return self._handler_for_request(request).create_authorization_response(request, token_handler)
63
64 def validate_authorization_request(self, request):
65 """Read scope and route to the designated handler."""
66 return self._handler_for_request(request).validate_authorization_request(request)
67
68
69class AuthorizationTokenGrantDispatcher(Dispatcher):
70 """
71 This is an adapter class that will route simple Token requests, those that authorization_code have a scope
72 including 'openid' to either the default_grant or the oidc_grant based on the scopes requested.
73 """
74 def __init__(self, request_validator, default_grant=None, oidc_grant=None):
75 self.default_grant = default_grant
76 self.oidc_grant = oidc_grant
77 self.request_validator = request_validator
78
79 def _handler_for_request(self, request):
80 handler = self.default_grant
81 scopes = ()
82 parameters = dict(request.decoded_body)
83 client_id = parameters.get('client_id')
84 code = parameters.get('code')
85 redirect_uri = parameters.get('redirect_uri')
86
87 # If code is not present fallback to `default_grant` which will
88 # raise an error for the missing `code` in `create_token_response` step.
89 if code:
90 scopes = self.request_validator.get_authorization_code_scopes(client_id, code, redirect_uri, request)
91
92 if 'openid' in scopes:
93 handler = self.oidc_grant
94
95 log.debug('Selecting handler for request %r.', handler)
96 return handler
97
98 def create_token_response(self, request, token_handler):
99 """Read scope and route to the designated handler."""
100 handler = self._handler_for_request(request)
101 return handler.create_token_response(request, token_handler)