def _decode_jwt_segment(encoded_section): """Decodes a single JWT segment.""" section_bytes = _helpers.padded_urlsafe_b64decode(encoded_section) try: return json.loads(section_bytes.decode('utf-8')) except ValueError: raise ValueError('Can\'t parse segment: {0}'.format(section_bytes))
def _unverified_decode(token): """Decodes a token and does no verification. Args: token (Union[str, bytes]): The encoded JWT. Returns: Tuple[str, str, str, str]: header, payload, signed_section, and signature. Raises: ValueError: if there are an incorrect amount of segments in the token. """ token = _helpers.to_bytes(token) if token.count(b'.') != 2: raise ValueError( 'Wrong number of segments in token: {0}'.format(token)) encoded_header, encoded_payload, signature = token.split(b'.') signed_section = encoded_header + b'.' + encoded_payload signature = _helpers.padded_urlsafe_b64decode(signature) # Parse segments header = _decode_jwt_segment(encoded_header) payload = _decode_jwt_segment(encoded_payload) return header, payload, signed_section, signature
def _decode_jwt_segment(encoded_section): """Decodes a single JWT segment.""" section_bytes = _helpers.padded_urlsafe_b64decode(encoded_section) try: return json.loads(section_bytes.decode("utf-8")) except ValueError as caught_exc: new_exc = ValueError("Can't parse segment: {0}".format(section_bytes)) six.raise_from(new_exc, caught_exc)
async def facebook_get_details(m: FacebookSiwModel, app): try: sig, data = m.signed_request.split(b'.', 1) except ValueError: raise JsonErrors.HTTPBadRequest( message='"signedRequest" not correctly formed') settings: Settings = app['settings'] expected_sig = hmac.new(settings.facebook_siw_app_secret, data, hashlib.sha256).digest() if not compare_digest(padded_urlsafe_b64decode(sig), expected_sig): raise JsonErrors.HTTPBadRequest( message='"signedRequest" not correctly signed') signed_data = json.loads(padded_urlsafe_b64decode(data).decode()) # can add 'picture' here, but it seems to be low res. details_url = (settings.facebook_siw_url + '?' + urlencode({ 'access_token': m.access_token, 'fields': ['email', 'first_name', 'last_name'] })) async with app['http_client'].get(details_url) as r: if r.status != 200: raise RequestError(r.status, details_url, text=await r.text()) response_data = await r.json() if not (response_data['id'] == signed_data['user_id'] == m.user_id): raise JsonErrors.HTTPBadRequest( message='facebook userID not consistent') if not response_data.get('email') or not response_data.get('last_name'): raise JsonErrors.HTTPBadRequest( message= 'Your Facebook profile needs to have both a last name and email address associated with it.' ) return { 'email': response_data['email'].lower(), 'first_name': response_data['first_name'], 'last_name': response_data['last_name'], }