Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / oauthlib / oauth2 / rfc6749 / request_validator.py @ 564

History | View | Annotate | Download (19.2 KB)

1
# -*- coding: utf-8 -*-
2
"""
3
oauthlib.oauth2.rfc6749.grant_types
4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
"""
6
from __future__ import unicode_literals, absolute_import
7

    
8
import logging
9

    
10
log = logging.getLogger(__name__)
11

    
12

    
13
class RequestValidator(object):
14

    
15
    def client_authentication_required(self, request, *args, **kwargs):
16
        """Determine if client authentication is required for current request.
17

18
        According to the rfc6749, client authentication is required in the following cases:
19
            - Resource Owner Password Credentials Grant, when Client type is Confidential or when
20
              Client was issued client credentials or whenever Client provided client
21
              authentication, see `Section 4.3.2`_.
22
            - Authorization Code Grant, when Client type is Confidential or when Client was issued
23
              client credentials or whenever Client provided client authentication,
24
              see `Section 4.1.3`_.
25
            - Refresh Token Grant, when Client type is Confidential or when Client was issued
26
              client credentials or whenever Client provided client authentication, see
27
              `Section 6`_
28

29
        :param request: oauthlib.common.Request
30
        :rtype: True or False
31

32
        Method is used by:
33
            - Authorization Code Grant
34
            - Resource Owner Password Credentials Grant
35
            - Refresh Token Grant
36

37
        .. _`Section 4.3.2`: http://tools.ietf.org/html/rfc6749#section-4.3.2
38
        .. _`Section 4.1.3`: http://tools.ietf.org/html/rfc6749#section-4.1.3
39
        .. _`Section 6`: http://tools.ietf.org/html/rfc6749#section-6
40
        """
41
        return True
42

    
43
    def authenticate_client(self, request, *args, **kwargs):
44
        """Authenticate client through means outside the OAuth 2 spec.
45

46
        Means of authentication is negotiated beforehand and may for example
47
        be `HTTP Basic Authentication Scheme`_ which utilizes the Authorization
48
        header.
49

50
        Headers may be accesses through request.headers and parameters found in
51
        both body and query can be obtained by direct attribute access, i.e.
52
        request.client_id for client_id in the URL query.
53

54
        :param request: oauthlib.common.Request
55
        :rtype: True or False
56

57
        Method is used by:
58
            - Authorization Code Grant
59
            - Resource Owner Password Credentials Grant (may be disabled)
60
            - Client Credentials Grant
61
            - Refresh Token Grant
62

63
        .. _`HTTP Basic Authentication Scheme`: http://tools.ietf.org/html/rfc1945#section-11.1
64
        """
65
        raise NotImplementedError('Subclasses must implement this method.')
66

    
67
    def authenticate_client_id(self, client_id, request, *args, **kwargs):
68
        """Ensure client_id belong to a non-confidential client.
69

70
        A non-confidential client is one that is not required to authenticate
71
        through other means, such as using HTTP Basic.
72

73
        Note, while not strictly necessary it can often be very convenient
74
        to set request.client to the client object associated with the
75
        given client_id.
76

77
        :param request: oauthlib.common.Request
78
        :rtype: True or False
79

80
        Method is used by:
81
            - Authorization Code Grant
82
        """
83
        raise NotImplementedError('Subclasses must implement this method.')
84

    
85
    def confirm_redirect_uri(self, client_id, code, redirect_uri, client,
86
                             *args, **kwargs):
87
        """Ensure that the authorization process represented by this authorization
88
        code began with this 'redirect_uri'.
89

90
        If the client specifies a redirect_uri when obtaining code then that
91
        redirect URI must be bound to the code and verified equal in this
92
        method, according to RFC 6749 section 4.1.3.  Do not compare against
93
        the client's allowed redirect URIs, but against the URI used when the
94
        code was saved.
95

96
        :param client_id: Unicode client identifier
97
        :param code: Unicode authorization_code.
98
        :param redirect_uri: Unicode absolute URI
99
        :param client: Client object set by you, see authenticate_client.
100
        :param request: The HTTP Request (oauthlib.common.Request)
101
        :rtype: True or False
102

103
        Method is used by:
104
            - Authorization Code Grant (during token request)
105
        """
106
        raise NotImplementedError('Subclasses must implement this method.')
107

    
108
    def get_default_redirect_uri(self, client_id, request, *args, **kwargs):
109
        """Get the default redirect URI for the client.
110

111
        :param client_id: Unicode client identifier
112
        :param request: The HTTP Request (oauthlib.common.Request)
113
        :rtype: The default redirect URI for the client
114

115
        Method is used by:
116
            - Authorization Code Grant
117
            - Implicit Grant
118
        """
119
        raise NotImplementedError('Subclasses must implement this method.')
120

    
121
    def get_default_scopes(self, client_id, request, *args, **kwargs):
122
        """Get the default scopes for the client.
123

124
        :param client_id: Unicode client identifier
125
        :param request: The HTTP Request (oauthlib.common.Request)
126
        :rtype: List of default scopes
127

128
        Method is used by all core grant types:
129
            - Authorization Code Grant
130
            - Implicit Grant
131
            - Resource Owner Password Credentials Grant
132
            - Client Credentials grant
133
        """
134
        raise NotImplementedError('Subclasses must implement this method.')
135

    
136
    def get_original_scopes(self, refresh_token, request, *args, **kwargs):
137
        """Get the list of scopes associated with the refresh token.
138

139
        :param refresh_token: Unicode refresh token
140
        :param request: The HTTP Request (oauthlib.common.Request)
141
        :rtype: List of scopes.
142

143
        Method is used by:
144
            - Refresh token grant
145
        """
146
        raise NotImplementedError('Subclasses must implement this method.')
147

    
148
    def is_within_original_scope(self, request_scopes, refresh_token, request, *args, **kwargs):
149
        """Check if requested scopes are within a scope of the refresh token.
150

151
        When access tokens are refreshed the scope of the new token
152
        needs to be within the scope of the original token. This is
153
        ensured by checking that all requested scopes strings are on
154
        the list returned by the get_original_scopes. If this check
155
        fails, is_within_original_scope is called. The method can be
156
        used in situations where returning all valid scopes from the
157
        get_original_scopes is not practical.
158

159
        :param request_scopes: A list of scopes that were requested by client
160
        :param refresh_token: Unicode refresh_token
161
        :param request: The HTTP Request (oauthlib.common.Request)
162
        :rtype: True or False
163

164
        Method is used by:
165
            - Refresh token grant
166
        """
167
        return False
168

    
169
    def invalidate_authorization_code(self, client_id, code, request, *args, **kwargs):
170
        """Invalidate an authorization code after use.
171

172
        :param client_id: Unicode client identifier
173
        :param code: The authorization code grant (request.code).
174
        :param request: The HTTP Request (oauthlib.common.Request)
175

176
        Method is used by:
177
            - Authorization Code Grant
178
        """
179
        raise NotImplementedError('Subclasses must implement this method.')
180

    
181
    def revoke_token(self, token, token_type_hint, request, *args, **kwargs):
182
        """Revoke an access or refresh token.
183

184
        :param token: The token string.
185
        :param token_type_hint: access_token or refresh_token.
186
        :param request: The HTTP Request (oauthlib.common.Request)
187

188
        Method is used by:
189
            - Revocation Endpoint
190
        """
191
        raise NotImplementedError('Subclasses must implement this method.')
192

    
193
    def rotate_refresh_token(self, request):
194
        """Determine whether to rotate the refresh token. Default, yes.
195

196
        When access tokens are refreshed the old refresh token can be kept
197
        or replaced with a new one (rotated). Return True to rotate and
198
        and False for keeping original.
199

200
        :param request: oauthlib.common.Request
201
        :rtype: True or False
202

203
        Method is used by:
204
            - Refresh Token Grant
205
        """
206
        return True
207

    
208
    def save_authorization_code(self, client_id, code, request, *args, **kwargs):
209
        """Persist the authorization_code.
210

211
        The code should at minimum be stored with:
212
            - the client_id (client_id)
213
            - the redirect URI used (request.redirect_uri)
214
            - a resource owner / user (request.user)
215
            - the authorized scopes (request.scopes)
216
            - the client state, if given (code.get('state'))
217

218
        The 'code' argument is actually a dictionary, containing at least a
219
        'code' key with the actual authorization code:
220

221
            {'code': 'sdf345jsdf0934f'}
222

223
        It may also have a 'state' key containing a nonce for the client, if it
224
        chose to send one.  That value should be saved and used in
225
        'validate_code'.
226

227
        :param client_id: Unicode client identifier
228
        :param code: A dict of the authorization code grant and, optionally, state.
229
        :param request: The HTTP Request (oauthlib.common.Request)
230

231
        Method is used by:
232
            - Authorization Code Grant
233
        """
234
        raise NotImplementedError('Subclasses must implement this method.')
235

    
236
    def save_bearer_token(self, token, request, *args, **kwargs):
237
        """Persist the Bearer token.
238

239
        The Bearer token should at minimum be associated with:
240
            - a client and it's client_id, if available
241
            - a resource owner / user (request.user)
242
            - authorized scopes (request.scopes)
243
            - an expiration time
244
            - a refresh token, if issued
245

246
        The Bearer token dict may hold a number of items::
247

248
            {
249
                'token_type': 'Bearer',
250
                'access_token': 'askfjh234as9sd8',
251
                'expires_in': 3600,
252
                'scope': 'string of space separated authorized scopes',
253
                'refresh_token': '23sdf876234',  # if issued
254
                'state': 'given_by_client',  # if supplied by client
255
            }
256

257
        Note that while "scope" is a string-separated list of authorized scopes,
258
        the original list is still available in request.scopes
259

260
        :param client_id: Unicode client identifier
261
        :param token: A Bearer token dict
262
        :param request: The HTTP Request (oauthlib.common.Request)
263
        :rtype: The default redirect URI for the client
264

265
        Method is used by all core grant types issuing Bearer tokens:
266
            - Authorization Code Grant
267
            - Implicit Grant
268
            - Resource Owner Password Credentials Grant (might not associate a client)
269
            - Client Credentials grant
270
        """
271
        raise NotImplementedError('Subclasses must implement this method.')
272

    
273
    def validate_bearer_token(self, token, scopes, request):
274
        """Ensure the Bearer token is valid and authorized access to scopes.
275

276
        :param token: A string of random characters.
277
        :param scopes: A list of scopes associated with the protected resource.
278
        :param request: The HTTP Request (oauthlib.common.Request)
279

280
        A key to OAuth 2 security and restricting impact of leaked tokens is
281
        the short expiration time of tokens, *always ensure the token has not
282
        expired!*.
283

284
        Two different approaches to scope validation:
285

286
            1) all(scopes). The token must be authorized access to all scopes
287
                            associated with the resource. For example, the
288
                            token has access to ``read-only`` and ``images``,
289
                            thus the client can view images but not upload new.
290
                            Allows for fine grained access control through
291
                            combining various scopes.
292

293
            2) any(scopes). The token must be authorized access to one of the
294
                            scopes associated with the resource. For example,
295
                            token has access to ``read-only-images``.
296
                            Allows for fine grained, although arguably less
297
                            convenient, access control.
298

299
        A powerful way to use scopes would mimic UNIX ACLs and see a scope
300
        as a group with certain privileges. For a restful API these might
301
        map to HTTP verbs instead of read, write and execute.
302

303
        Note, the request.user attribute can be set to the resource owner
304
        associated with this token. Similarly the request.client and
305
        request.scopes attribute can be set to associated client object
306
        and authorized scopes. If you then use a decorator such as the
307
        one provided for django these attributes will be made available
308
        in all protected views as keyword arguments.
309

310
        :param token: Unicode Bearer token
311
        :param scopes: List of scopes (defined by you)
312
        :param request: The HTTP Request (oauthlib.common.Request)
313
        :rtype: True or False
314

315
        Method is indirectly used by all core Bearer token issuing grant types:
316
            - Authorization Code Grant
317
            - Implicit Grant
318
            - Resource Owner Password Credentials Grant
319
            - Client Credentials Grant
320
        """
321
        raise NotImplementedError('Subclasses must implement this method.')
322

    
323
    def validate_client_id(self, client_id, request, *args, **kwargs):
324
        """Ensure client_id belong to a valid and active client.
325

326
        Note, while not strictly necessary it can often be very convenient
327
        to set request.client to the client object associated with the
328
        given client_id.
329

330
        :param request: oauthlib.common.Request
331
        :rtype: True or False
332

333
        Method is used by:
334
            - Authorization Code Grant
335
            - Implicit Grant
336
        """
337
        raise NotImplementedError('Subclasses must implement this method.')
338

    
339
    def validate_code(self, client_id, code, client, request, *args, **kwargs):
340
        """Verify that the authorization_code is valid and assigned to the given
341
        client.
342

343
        Before returning true, set the following based on the information stored
344
        with the code in 'save_authorization_code':
345

346
            - request.user
347
            - request.state (if given)
348
            - request.scopes
349
        OBS! The request.user attribute should be set to the resource owner
350
        associated with this authorization code. Similarly request.scopes
351
        must also be set.
352

353
        :param client_id: Unicode client identifier
354
        :param code: Unicode authorization code
355
        :param client: Client object set by you, see authenticate_client.
356
        :param request: The HTTP Request (oauthlib.common.Request)
357
        :rtype: True or False
358

359
        Method is used by:
360
            - Authorization Code Grant
361
        """
362
        raise NotImplementedError('Subclasses must implement this method.')
363

    
364
    def validate_grant_type(self, client_id, grant_type, client, request, *args, **kwargs):
365
        """Ensure client is authorized to use the grant_type requested.
366

367
        :param client_id: Unicode client identifier
368
        :param grant_type: Unicode grant type, i.e. authorization_code, password.
369
        :param client: Client object set by you, see authenticate_client.
370
        :param request: The HTTP Request (oauthlib.common.Request)
371
        :rtype: True or False
372

373
        Method is used by:
374
            - Authorization Code Grant
375
            - Resource Owner Password Credentials Grant
376
            - Client Credentials Grant
377
            - Refresh Token Grant
378
        """
379
        raise NotImplementedError('Subclasses must implement this method.')
380

    
381
    def validate_redirect_uri(self, client_id, redirect_uri, request, *args, **kwargs):
382
        """Ensure client is authorized to redirect to the redirect_uri requested.
383

384
        All clients should register the absolute URIs of all URIs they intend
385
        to redirect to. The registration is outside of the scope of oauthlib.
386

387
        :param client_id: Unicode client identifier
388
        :param redirect_uri: Unicode absolute URI
389
        :param request: The HTTP Request (oauthlib.common.Request)
390
        :rtype: True or False
391

392
        Method is used by:
393
            - Authorization Code Grant
394
            - Implicit Grant
395
        """
396
        raise NotImplementedError('Subclasses must implement this method.')
397

    
398
    def validate_refresh_token(self, refresh_token, client, request, *args, **kwargs):
399
        """Ensure the Bearer token is valid and authorized access to scopes.
400

401
        OBS! The request.user attribute should be set to the resource owner
402
        associated with this refresh token.
403

404
        :param refresh_token: Unicode refresh token
405
        :param client: Client object set by you, see authenticate_client.
406
        :param request: The HTTP Request (oauthlib.common.Request)
407
        :rtype: True or False
408

409
        Method is used by:
410
            - Authorization Code Grant (indirectly by issuing refresh tokens)
411
            - Resource Owner Password Credentials Grant (also indirectly)
412
            - Refresh Token Grant
413
        """
414
        raise NotImplementedError('Subclasses must implement this method.')
415

    
416
    def validate_response_type(self, client_id, response_type, client, request, *args, **kwargs):
417
        """Ensure client is authorized to use the response_type requested.
418

419
        :param client_id: Unicode client identifier
420
        :param response_type: Unicode response type, i.e. code, token.
421
        :param client: Client object set by you, see authenticate_client.
422
        :param request: The HTTP Request (oauthlib.common.Request)
423
        :rtype: True or False
424

425
        Method is used by:
426
            - Authorization Code Grant
427
            - Implicit Grant
428
        """
429
        raise NotImplementedError('Subclasses must implement this method.')
430

    
431
    def validate_scopes(self, client_id, scopes, client, request, *args, **kwargs):
432
        """Ensure the client is authorized access to requested scopes.
433

434
        :param client_id: Unicode client identifier
435
        :param scopes: List of scopes (defined by you)
436
        :param client: Client object set by you, see authenticate_client.
437
        :param request: The HTTP Request (oauthlib.common.Request)
438
        :rtype: True or False
439

440
        Method is used by all core grant types:
441
            - Authorization Code Grant
442
            - Implicit Grant
443
            - Resource Owner Password Credentials Grant
444
            - Client Credentials Grant
445
        """
446
        raise NotImplementedError('Subclasses must implement this method.')
447

    
448
    def validate_user(self, username, password, client, request, *args, **kwargs):
449
        """Ensure the username and password is valid.
450

451
        OBS! The validation should also set the user attribute of the request
452
        to a valid resource owner, i.e. request.user = username or similar. If
453
        not set you will be unable to associate a token with a user in the
454
        persistance method used (commonly, save_bearer_token).
455

456
        :param username: Unicode username
457
        :param password: Unicode password
458
        :param client: Client object set by you, see authenticate_client.
459
        :param request: The HTTP Request (oauthlib.common.Request)
460
        :rtype: True or False
461

462
        Method is used by:
463
            - Resource Owner Password Credentials Grant
464
        """
465
        raise NotImplementedError('Subclasses must implement this method.')