@@ -105,6 +105,25 @@ def access_token_response_data(self, access_token, response_type=None):
105
105
106
106
return response_data
107
107
108
+ def get_access_and_refresh_tokens (self , request , user , scope , client , reuse_existing_access_token = False , create_refresh_token = True ):
109
+ """
110
+ Returns an AccessToken and RefreshToken for the given user, scope, and client combination.
111
+
112
+ Returns:
113
+ (AccessToken, RefreshToken)
114
+ If create_refresh_token is False, the second element of the tuple will be None.
115
+ """
116
+ if reuse_existing_access_token :
117
+ at = self .get_access_token (request , user , scope , client )
118
+ else :
119
+ at = self .create_access_token (request , user , scope , client )
120
+
121
+ rt = None
122
+ if create_refresh_token and not reuse_existing_access_token :
123
+ rt = self .create_refresh_token (request , user , scope , at , client )
124
+
125
+ return at , rt
126
+
108
127
109
128
class OAuthView (TemplateView ):
110
129
"""
@@ -333,15 +352,14 @@ def get_implicit_response(self, request, client):
333
352
data = self .get_data (request )
334
353
335
354
lookup_kwargs = {
336
- "user" : request .user ,
337
- "client" : client ,
338
- "scope" : scope .to_int (* data .get ('scope' , constants .SCOPES [0 ][1 ]).split ())
355
+ 'user' : request .user ,
356
+ 'client' : client ,
357
+ 'scope' : scope .to_int (* data .get ('scope' , constants .SCOPES [0 ][1 ]).split ()),
358
+ 'reuse_existing_access_token' : constants .SINGLE_ACCESS_TOKEN ,
359
+ 'create_refresh_token' : False
339
360
}
340
361
341
- if constants .SINGLE_ACCESS_TOKEN :
342
- token = self .get_access_token (request , ** lookup_kwargs )
343
- else :
344
- token = self .create_access_token (request , ** lookup_kwargs )
362
+ token , __ = self .get_access_and_refresh_tokens (request , ** lookup_kwargs )
345
363
346
364
response_data = self .access_token_response_data (token , data ['response_type' ])
347
365
@@ -503,7 +521,7 @@ class AccessToken(OAuthView, Mixin, AccessTokenMixin):
503
521
Authentication backends used to authenticate a particular client.
504
522
"""
505
523
506
- grant_types = ['authorization_code' , 'refresh_token' , 'password' ]
524
+ grant_types = ['authorization_code' , 'refresh_token' , 'password' , 'client_credentials' ]
507
525
"""
508
526
The default grant types supported by this view.
509
527
"""
@@ -532,6 +550,14 @@ def get_password_grant(self, request, data, client):
532
550
"""
533
551
raise NotImplementedError # pragma: no cover
534
552
553
+ def get_client_credentials_grant (self , request , data , client ):
554
+ """
555
+ Return the optional parameters (scope) associated with this request.
556
+
557
+ :return: ``tuple`` - ``(True or False, options)``
558
+ """
559
+ raise NotImplementedError # pragma: no cover
560
+
535
561
def invalidate_grant (self , grant ):
536
562
"""
537
563
Override to handle grant invalidation. A grant is invalidated right
@@ -564,13 +590,16 @@ def authorization_code(self, request, data, client):
564
590
Handle ``grant_type=authorization_code`` requests as defined in
565
591
:rfc:`4.1.3`.
566
592
"""
567
- grant = self .get_authorization_code_grant (request , request .POST ,
568
- client )
569
- if constants .SINGLE_ACCESS_TOKEN :
570
- at = self .get_access_token (request , grant .user , grant .scope , client )
571
- else :
572
- at = self .create_access_token (request , grant .user , grant .scope , client )
573
- rt = self .create_refresh_token (request , grant .user , grant .scope , at , client )
593
+ grant = self .get_authorization_code_grant (request , request .POST , client )
594
+
595
+ kwargs = {
596
+ 'request' : request ,
597
+ 'user' : grant .user ,
598
+ 'scope' : grant .scope ,
599
+ 'client' : client ,
600
+ 'reuse_existing_access_token' : constants .SINGLE_ACCESS_TOKEN ,
601
+ }
602
+ at , rt = self .get_access_and_refresh_tokens (** kwargs )
574
603
575
604
self .invalidate_grant (grant )
576
605
@@ -586,8 +615,13 @@ def refresh_token(self, request, data, client):
586
615
self .invalidate_refresh_token (rt )
587
616
self .invalidate_access_token (rt .access_token )
588
617
589
- at = self .create_access_token (request , rt .user , rt .access_token .scope , client )
590
- rt = self .create_refresh_token (request , at .user , at .scope , at , client )
618
+ kwargs = {
619
+ 'request' : request ,
620
+ 'user' : rt .user ,
621
+ 'scope' : rt .access_token .scope ,
622
+ 'client' : client ,
623
+ }
624
+ at , rt = self .get_access_and_refresh_tokens (** kwargs )
591
625
592
626
return self .access_token_response (at )
593
627
@@ -597,16 +631,32 @@ def password(self, request, data, client):
597
631
"""
598
632
599
633
data = self .get_password_grant (request , data , client )
600
- user = data .get ('user' )
601
- scope = data .get ('scope' )
634
+ kwargs = {
635
+ 'request' : request ,
636
+ 'user' : data .get ('user' ),
637
+ 'scope' : data .get ('scope' ),
638
+ 'client' : client ,
639
+ 'reuse_existing_access_token' : constants .SINGLE_ACCESS_TOKEN ,
602
640
603
- if constants .SINGLE_ACCESS_TOKEN :
604
- at = self .get_access_token (request , user , scope , client )
605
- else :
606
- at = self .create_access_token (request , user , scope , client )
607
641
# Public clients don't get refresh tokens
608
- if client .client_type == constants .CONFIDENTIAL :
609
- rt = self .create_refresh_token (request , user , scope , at , client )
642
+ 'create_refresh_token' : client .client_type == constants .CONFIDENTIAL
643
+ }
644
+ at , rt = self .get_access_and_refresh_tokens (** kwargs )
645
+
646
+ return self .access_token_response (at )
647
+
648
+ def client_credentials (self , request , data , client ):
649
+ """ Handle ``grant_type=client_credentials`` requests as defined in :rfc:`4.4`. """
650
+ data = self .get_client_credentials_grant (request , data , client )
651
+ kwargs = {
652
+ 'request' : request ,
653
+ 'user' : client .user ,
654
+ 'scope' : data .get ('scope' ),
655
+ 'client' : client ,
656
+ 'reuse_existing_access_token' : constants .SINGLE_ACCESS_TOKEN ,
657
+ 'create_refresh_token' : False ,
658
+ }
659
+ at , rt = self .get_access_and_refresh_tokens (** kwargs )
610
660
611
661
return self .access_token_response (at )
612
662
@@ -622,6 +672,8 @@ def get_handler(self, grant_type):
622
672
return self .refresh_token
623
673
elif grant_type == 'password' :
624
674
return self .password
675
+ elif grant_type == 'client_credentials' :
676
+ return self .client_credentials
625
677
return None
626
678
627
679
def get (self , request ):
0 commit comments