2
2
import json
3
3
import uuid
4
4
from datetime import datetime
5
+ from json import JSONDecodeError
5
6
6
7
from cryptojwt import as_unicode
7
8
from cryptojwt import jwe
@@ -83,12 +84,14 @@ def get_jwt_keys(jwt, keys, use):
83
84
class JWT (object ):
84
85
85
86
def __init__ (self , own_keys = None , iss = '' , rec_keys = None , lifetime = 0 ,
86
- sign_alg = 'RS256' , encrypt = False , enc_enc = "A128CBC-HS256" ,
87
- enc_alg = "RSA1_5" , msg_cls = None , iss2msg_cls = None ):
87
+ sign = True , sign_alg = 'RS256' , encrypt = False ,
88
+ enc_enc = "A128CBC-HS256" , enc_alg = "RSA1_5" , msg_cls = None ,
89
+ iss2msg_cls = None ):
88
90
self .own_keys = own_keys
89
91
self .rec_keys = rec_keys or {}
90
92
self .iss = iss
91
93
self .lifetime = lifetime
94
+ self .sign = sign
92
95
self .sign_alg = sign_alg
93
96
self .encrypt = encrypt
94
97
self .enc_alg = enc_alg
@@ -154,12 +157,6 @@ def pack(self, payload=None, kid='', owner='', recv='', **kwargs):
154
157
"""
155
158
_args = self .pack_init ()
156
159
157
- if self .sign_alg != 'none' :
158
- _key = self .pack_key (owner , kid )
159
- _args ['kid' ] = _key .kid
160
- else :
161
- _key = None
162
-
163
160
try :
164
161
_encrypt = kwargs ['encrypt' ]
165
162
except KeyError :
@@ -178,11 +175,23 @@ def pack(self, payload=None, kid='', owner='', recv='', **kwargs):
178
175
if payload is not None :
179
176
_args .update (payload )
180
177
181
- _jws = JWS (json .dumps (_args ), alg = self .sign_alg )
182
- _sjwt = _jws .sign_compact ([_key ])
183
- # _jws = _jwt.to_jwt([_key], self.sign_alg)
178
+ if self .sign :
179
+ if self .sign_alg != 'none' :
180
+ _key = self .pack_key (owner , kid )
181
+ _args ['kid' ] = _key .kid
182
+ else :
183
+ _key = None
184
+
185
+ _jws = JWS (json .dumps (_args ), alg = self .sign_alg )
186
+ _sjwt = _jws .sign_compact ([_key ])
187
+ else :
188
+ _sjwt = json .dumps (_args )
189
+
184
190
if _encrypt :
185
- return self ._encrypt (_sjwt , recv )
191
+ if not self .sign :
192
+ return self ._encrypt (_sjwt , recv , cty = 'json' )
193
+ else :
194
+ return self ._encrypt (_sjwt , recv )
186
195
else :
187
196
return _sjwt
188
197
@@ -213,27 +222,53 @@ def unpack(self, token):
213
222
214
223
:param token: The Json Web Token
215
224
:return: If decryption and signature verification work the payload
216
- will be returned as a Message instance.
225
+ will be returned as a Message instance if possible .
217
226
"""
218
227
if not token :
219
228
raise KeyError
220
229
221
- _rj = jwe .factory (token )
222
- if _rj :
223
- token = self ._decrypt (_rj , token )
230
+ _content_type = 'jwt'
224
231
225
- _rj = jws .factory (token )
232
+ # Check if it's an encrypted JWT
233
+ _rj = jwe .factory (token )
226
234
if _rj :
227
- info = self ._verify (_rj , token )
235
+ # Yes, try to decode
236
+ _info = self ._decrypt (_rj , token )
237
+ # Try to find out if the information encrypted was a signed JWT
238
+ try :
239
+ _content_type = _rj .jwt .headers ['cty' ]
240
+ except KeyError :
241
+ pass
242
+ else :
243
+ _info = token
244
+
245
+ # If I have reason to believe the information I have is a signed JWT
246
+ if _content_type .lower () == 'jwt' :
247
+ # Check that is a signed JWT
248
+ _rj = jws .factory (_info )
249
+ if _rj :
250
+ _info = self ._verify (_rj , _info )
251
+ else :
252
+ raise Exception ()
228
253
else :
229
- raise Exception ()
254
+ # So, not a signed JWT
255
+ try :
256
+ # A JSON document ?
257
+ _info = json .loads (_info )
258
+ except JSONDecodeError : # Oh, no ! Not JSON
259
+ return _info
230
260
261
+ # If I know what message class the info should be mapped into
231
262
if self .msg_cls :
232
- return self .verify_profile ( self . msg_cls , ** info )
263
+ _msg_cls = self .msg_cls
233
264
else :
234
265
try :
235
- _msg_cls = self .iss2msg_cls [info ['iss' ]]
266
+ # try to find a issuer specific message class
267
+ _msg_cls = self .iss2msg_cls [_info ['iss' ]]
236
268
except KeyError :
237
- return info
238
- else :
239
- return self .verify_profile (_msg_cls , ** info )
269
+ _msg_cls = None
270
+
271
+ if _msg_cls :
272
+ return self .verify_profile (_msg_cls , ** _info )
273
+ else :
274
+ return _info
0 commit comments