16
16
from rsa import pkcs1
17
17
import ntp
18
18
19
+
19
20
def encode_dict_to_base64 (d ):
20
21
return encode_bytes_to_safe_base64 (json .dumps (d ).encode ('utf8' ))
21
22
23
+
22
24
def encode_bytes_to_safe_base64 (bytes ):
23
25
encoded = binascii .b2a_base64 (bytes ).replace (b'+' , b'-' )
24
26
return encoded .replace (b'/' , b'_' ).strip ().decode ('utf8' )
25
27
28
+
26
29
# this class builds a JWT to request an access token
27
30
# from the Google OAuth 2.0 Authorization Server using a service account
28
31
# see https://developers.google.com/identity/protocols/OAuth2ServiceAccount
29
32
class JWTBuilder :
30
33
31
34
def __init__ (self ):
32
- self ._header = {}
33
- self . _header [ 'alg' ] = 'RS256'
34
- self . _header [ 'typ' ] = 'JWT'
35
- self ._claim = {}
36
- self . _claim [ 'iss' ] = ''
37
- self . _claim [ 'scope' ] = ''
38
- self . _claim [ 'aud' ] = 'https://www.googleapis.com/oauth2/v4/token'
39
- self . _claim [ 'exp' ] = 0
40
- self . _claim [ 'iat' ] = 0
35
+ self ._header = {
36
+ 'alg' : 'RS256' ,
37
+ 'typ' : 'JWT' }
38
+ self ._claim = {
39
+ 'iss' : '' ,
40
+ 'scope' : '' ,
41
+ 'aud' : 'https://www.googleapis.com/oauth2/v4/token' ,
42
+ 'exp' : 0 ,
43
+ 'iat' : 0 }
41
44
self ._key = None
42
- self ._expiration = 30 * 60 # 30 minutes, in seconds
45
+ self ._expiration = 30 * 60 # 30 minutes, in seconds
43
46
44
47
def service_account (self , email ):
45
48
self ._claim ['iss' ] = email
@@ -65,10 +68,12 @@ def build(self):
65
68
print ('jwt: signing ...' )
66
69
signature = pkcs1 .sign (to_be_signed .encode ('utf8' ), self ._key , 'SHA-256' )
67
70
print ('jwt: done' )
68
- print ('jwt: encodeing ' )
71
+ print ('jwt: encoding ' )
69
72
encoded_signature = encode_bytes_to_safe_base64 (signature )
70
73
return '%s.%s' % (to_be_signed , encoded_signature )
71
74
75
+
76
+ # the class obtains a token for accessing the Google API
72
77
class ServiceAccount :
73
78
74
79
def __init__ (self ):
@@ -97,13 +102,18 @@ def token(self):
97
102
jwt = builder .build ()
98
103
print ('token: jwt is done' )
99
104
100
- type = 'urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer'
101
- body = 'grant_type=%s&assertion=%s' % (type , jwt )
105
+ grant_type = 'urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer'
106
+ body = 'grant_type=%s&assertion=%s' % (grant_type , jwt )
102
107
headers = {'Content-Type' : 'application/x-www-form-urlencoded' }
103
108
response = requests .post ('https://www.googleapis.com/oauth2/v4/token' ,
104
109
data = body ,
105
110
headers = headers )
106
111
if not response :
107
- print ('token: no response received' )
112
+ raise Exception ('token: no response received' )
113
+
114
+ data = response .json ()
115
+ if 'access_token' not in data :
116
+ print ('response data: {}' .format (data ))
117
+ raise Exception ('token: no access token in response' )
108
118
109
- return response . json () ['access_token' ]
119
+ return data ['access_token' ]
0 commit comments