1
- import json
2
1
import logging
3
2
from datetime import timedelta
4
3
from urllib .parse import parse_qsl , urlparse
10
9
from django .urls import reverse
11
10
from django .utils import timezone
12
11
from django .utils .translation import gettext_lazy as _
13
- from jwcrypto import jwk , jwt
14
12
15
13
from .generators import generate_client_id , generate_client_secret
16
14
from .scopes import get_scopes_backend
@@ -52,20 +50,11 @@ class AbstractApplication(models.Model):
52
50
GRANT_IMPLICIT = "implicit"
53
51
GRANT_PASSWORD = "password"
54
52
GRANT_CLIENT_CREDENTIALS = "client-credentials"
55
- GRANT_OPENID_HYBRID = "openid-hybrid"
56
53
GRANT_TYPES = (
57
54
(GRANT_AUTHORIZATION_CODE , _ ("Authorization code" )),
58
55
(GRANT_IMPLICIT , _ ("Implicit" )),
59
56
(GRANT_PASSWORD , _ ("Resource owner password-based" )),
60
57
(GRANT_CLIENT_CREDENTIALS , _ ("Client credentials" )),
61
- (GRANT_OPENID_HYBRID , _ ("OpenID connect hybrid" )),
62
- )
63
-
64
- RS256_ALGORITHM = "RS256"
65
- HS256_ALGORITHM = "HS256"
66
- ALGORITHM_TYPES = (
67
- (RS256_ALGORITHM , _ ("RSA with SHA-2 256" )),
68
- (HS256_ALGORITHM , _ ("HMAC with SHA-2 256" )),
69
58
)
70
59
71
60
id = models .BigAutoField (primary_key = True )
@@ -93,7 +82,6 @@ class AbstractApplication(models.Model):
93
82
94
83
created = models .DateTimeField (auto_now_add = True )
95
84
updated = models .DateTimeField (auto_now = True )
96
- algorithm = models .CharField (max_length = 5 , choices = ALGORITHM_TYPES , default = RS256_ALGORITHM )
97
85
98
86
class Meta :
99
87
abstract = True
@@ -294,10 +282,6 @@ class AbstractAccessToken(models.Model):
294
282
related_name = "refreshed_access_token"
295
283
)
296
284
token = models .CharField (max_length = 255 , unique = True , )
297
- id_token = models .OneToOneField (
298
- oauth2_settings .ID_TOKEN_MODEL , on_delete = models .CASCADE , blank = True , null = True ,
299
- related_name = "access_token"
300
- )
301
285
application = models .ForeignKey (
302
286
oauth2_settings .APPLICATION_MODEL , on_delete = models .CASCADE , blank = True , null = True ,
303
287
)
@@ -431,99 +415,6 @@ class Meta(AbstractRefreshToken.Meta):
431
415
swappable = "OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL"
432
416
433
417
434
- class AbstractIDToken (models .Model ):
435
- """
436
- An IDToken instance represents the actual token to
437
- access user's resources, as in :openid:`2`.
438
-
439
- Fields:
440
-
441
- * :attr:`user` The Django user representing resources' owner
442
- * :attr:`token` ID token
443
- * :attr:`application` Application instance
444
- * :attr:`expires` Date and time of token expiration, in DateTime format
445
- * :attr:`scope` Allowed scopes
446
- """
447
- id = models .BigAutoField (primary_key = True )
448
- user = models .ForeignKey (
449
- settings .AUTH_USER_MODEL , on_delete = models .CASCADE , blank = True , null = True ,
450
- related_name = "%(app_label)s_%(class)s"
451
- )
452
- token = models .TextField (unique = True )
453
- application = models .ForeignKey (
454
- oauth2_settings .APPLICATION_MODEL , on_delete = models .CASCADE , blank = True , null = True ,
455
- )
456
- expires = models .DateTimeField ()
457
- scope = models .TextField (blank = True )
458
-
459
- created = models .DateTimeField (auto_now_add = True )
460
- updated = models .DateTimeField (auto_now = True )
461
-
462
- def is_valid (self , scopes = None ):
463
- """
464
- Checks if the access token is valid.
465
-
466
- :param scopes: An iterable containing the scopes to check or None
467
- """
468
- return not self .is_expired () and self .allow_scopes (scopes )
469
-
470
- def is_expired (self ):
471
- """
472
- Check token expiration with timezone awareness
473
- """
474
- if not self .expires :
475
- return True
476
-
477
- return timezone .now () >= self .expires
478
-
479
- def allow_scopes (self , scopes ):
480
- """
481
- Check if the token allows the provided scopes
482
-
483
- :param scopes: An iterable containing the scopes to check
484
- """
485
- if not scopes :
486
- return True
487
-
488
- provided_scopes = set (self .scope .split ())
489
- resource_scopes = set (scopes )
490
-
491
- return resource_scopes .issubset (provided_scopes )
492
-
493
- def revoke (self ):
494
- """
495
- Convenience method to uniform tokens' interface, for now
496
- simply remove this token from the database in order to revoke it.
497
- """
498
- self .delete ()
499
-
500
- @property
501
- def scopes (self ):
502
- """
503
- Returns a dictionary of allowed scope names (as keys) with their descriptions (as values)
504
- """
505
- all_scopes = get_scopes_backend ().get_all_scopes ()
506
- token_scopes = self .scope .split ()
507
- return {name : desc for name , desc in all_scopes .items () if name in token_scopes }
508
-
509
- @property
510
- def claims (self ):
511
- key = jwk .JWK .from_pem (oauth2_settings .OIDC_RSA_PRIVATE_KEY .encode ("utf8" ))
512
- jwt_token = jwt .JWT (key = key , jwt = self .token )
513
- return json .loads (jwt_token .claims )
514
-
515
- def __str__ (self ):
516
- return self .token
517
-
518
- class Meta :
519
- abstract = True
520
-
521
-
522
- class IDToken (AbstractIDToken ):
523
- class Meta (AbstractIDToken .Meta ):
524
- swappable = "OAUTH2_PROVIDER_ID_TOKEN_MODEL"
525
-
526
-
527
418
def get_application_model ():
528
419
""" Return the Application model that is active in this project. """
529
420
return apps .get_model (oauth2_settings .APPLICATION_MODEL )
@@ -539,11 +430,6 @@ def get_access_token_model():
539
430
return apps .get_model (oauth2_settings .ACCESS_TOKEN_MODEL )
540
431
541
432
542
- def get_id_token_model ():
543
- """ Return the AccessToken model that is active in this project. """
544
- return apps .get_model (oauth2_settings .ID_TOKEN_MODEL )
545
-
546
-
547
433
def get_refresh_token_model ():
548
434
""" Return the RefreshToken model that is active in this project. """
549
435
return apps .get_model (oauth2_settings .REFRESH_TOKEN_MODEL )
0 commit comments