aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-04-12 12:45:55 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-04-12 13:42:15 +0300
commita592841bc0deb67c364dea234d7c5adbe0dadad5 (patch)
tree90a280604bae87f20b5007a185611c45040bdd17
parentdd11d72c358cf78610025a4d12ef888be70054bf (diff)
downloadydb-a592841bc0deb67c364dea234d7c5adbe0dadad5.tar.gz
Intermediate changes
-rw-r--r--contrib/python/PyJWT/py2/.dist-info/METADATA115
-rw-r--r--contrib/python/PyJWT/py2/.dist-info/entry_points.txt3
-rw-r--r--contrib/python/PyJWT/py2/.dist-info/top_level.txt1
-rw-r--r--contrib/python/PyJWT/py2/jwt/__init__.py31
-rw-r--r--contrib/python/PyJWT/py2/jwt/__main__.py168
-rw-r--r--contrib/python/PyJWT/py2/jwt/algorithms.py403
-rw-r--r--contrib/python/PyJWT/py2/jwt/api_jws.py242
-rw-r--r--contrib/python/PyJWT/py2/jwt/api_jwt.py222
-rw-r--r--contrib/python/PyJWT/py2/jwt/compat.py68
-rw-r--r--contrib/python/PyJWT/py2/jwt/contrib/__init__.py0
-rw-r--r--contrib/python/PyJWT/py2/jwt/contrib/algorithms/__init__.py0
-rw-r--r--contrib/python/PyJWT/py2/jwt/contrib/algorithms/py_ecdsa.py60
-rw-r--r--contrib/python/PyJWT/py2/jwt/contrib/algorithms/pycrypto.py46
-rw-r--r--contrib/python/PyJWT/py2/jwt/exceptions.py59
-rw-r--r--contrib/python/PyJWT/py2/jwt/help.py61
-rw-r--r--contrib/python/PyJWT/py2/jwt/utils.py113
-rw-r--r--contrib/python/PyJWT/py2/ya.make43
-rw-r--r--contrib/python/ydb/py3/.dist-info/METADATA3
-rw-r--r--contrib/python/ydb/py3/ya.make3
-rw-r--r--contrib/python/ydb/py3/ydb/_topic_reader/topic_reader_sync.py8
-rw-r--r--contrib/python/ydb/py3/ydb/aio/iam.py109
-rw-r--r--contrib/python/ydb/py3/ydb/driver.py7
-rw-r--r--contrib/python/ydb/py3/ydb/iam/__init__.py1
-rw-r--r--contrib/python/ydb/py3/ydb/iam/auth.py151
-rw-r--r--contrib/python/ydb/py3/ydb/ydb_version.py2
25 files changed, 38 insertions, 1881 deletions
diff --git a/contrib/python/PyJWT/py2/.dist-info/METADATA b/contrib/python/PyJWT/py2/.dist-info/METADATA
deleted file mode 100644
index 47ee558907..0000000000
--- a/contrib/python/PyJWT/py2/.dist-info/METADATA
+++ /dev/null
@@ -1,115 +0,0 @@
-Metadata-Version: 2.1
-Name: PyJWT
-Version: 1.7.1
-Summary: JSON Web Token implementation in Python
-Home-page: http://github.com/jpadilla/pyjwt
-Author: Jose Padilla
-Author-email: hello@jpadilla.com
-License: MIT
-Keywords: jwt json web token security signing
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Natural Language :: English
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Utilities
-Provides-Extra: crypto
-Requires-Dist: cryptography (>=1.4) ; extra == 'crypto'
-Provides-Extra: flake8
-Requires-Dist: flake8 ; extra == 'flake8'
-Requires-Dist: flake8-import-order ; extra == 'flake8'
-Requires-Dist: pep8-naming ; extra == 'flake8'
-Provides-Extra: test
-Requires-Dist: pytest (<5.0.0,>=4.0.1) ; extra == 'test'
-Requires-Dist: pytest-cov (<3.0.0,>=2.6.0) ; extra == 'test'
-Requires-Dist: pytest-runner (<5.0.0,>=4.2) ; extra == 'test'
-
-PyJWT
-=====
-
-.. image:: https://travis-ci.com/jpadilla/pyjwt.svg?branch=master
- :target: http://travis-ci.com/jpadilla/pyjwt?branch=master
-
-.. image:: https://ci.appveyor.com/api/projects/status/h8nt70aqtwhht39t?svg=true
- :target: https://ci.appveyor.com/project/jpadilla/pyjwt
-
-.. image:: https://img.shields.io/pypi/v/pyjwt.svg
- :target: https://pypi.python.org/pypi/pyjwt
-
-.. image:: https://coveralls.io/repos/jpadilla/pyjwt/badge.svg?branch=master
- :target: https://coveralls.io/r/jpadilla/pyjwt?branch=master
-
-.. image:: https://readthedocs.org/projects/pyjwt/badge/?version=latest
- :target: https://pyjwt.readthedocs.io
-
-A Python implementation of `RFC 7519 <https://tools.ietf.org/html/rfc7519>`_. Original implementation was written by `@progrium <https://github.com/progrium>`_.
-
-Sponsor
--------
-
-+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-| |auth0-logo| | If you want to quickly add secure token-based authentication to Python projects, feel free to check Auth0's Python SDK and free plan at `auth0.com/overview <https://auth0.com/overview?utm_source=GHsponsor&utm_medium=GHsponsor&utm_campaign=pyjwt&utm_content=auth>`_. |
-+--------------+-----------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
-
-.. |auth0-logo| image:: https://user-images.githubusercontent.com/83319/31722733-de95bbde-b3ea-11e7-96bf-4f4e8f915588.png
-
-Installing
-----------
-
-Install with **pip**:
-
-.. code-block:: sh
-
- $ pip install PyJWT
-
-
-Usage
------
-
-.. code:: python
-
- >>> import jwt
- >>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256')
- 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg'
-
- >>> jwt.decode(encoded, 'secret', algorithms=['HS256'])
- {'some': 'payload'}
-
-
-Command line
-------------
-
-Usage::
-
- pyjwt [options] INPUT
-
-Decoding examples::
-
- pyjwt --key=secret decode TOKEN
- pyjwt decode --no-verify TOKEN
-
-See more options executing ``pyjwt --help``.
-
-
-Documentation
--------------
-
-View the full docs online at https://pyjwt.readthedocs.io/en/latest/
-
-
-Tests
------
-
-You can run tests from the project root after cloning with:
-
-.. code-block:: sh
-
- $ python setup.py test
-
-
diff --git a/contrib/python/PyJWT/py2/.dist-info/entry_points.txt b/contrib/python/PyJWT/py2/.dist-info/entry_points.txt
deleted file mode 100644
index 78717b2661..0000000000
--- a/contrib/python/PyJWT/py2/.dist-info/entry_points.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[console_scripts]
-pyjwt = jwt.__main__:main
-
diff --git a/contrib/python/PyJWT/py2/.dist-info/top_level.txt b/contrib/python/PyJWT/py2/.dist-info/top_level.txt
deleted file mode 100644
index 27ccc9bc3a..0000000000
--- a/contrib/python/PyJWT/py2/.dist-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-jwt
diff --git a/contrib/python/PyJWT/py2/jwt/__init__.py b/contrib/python/PyJWT/py2/jwt/__init__.py
deleted file mode 100644
index 946983f022..0000000000
--- a/contrib/python/PyJWT/py2/jwt/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-# flake8: noqa
-
-"""
-JSON Web Token implementation
-
-Minimum implementation based on this spec:
-http://self-issued.info/docs/draft-jones-json-web-token-01.html
-"""
-
-
-__title__ = 'pyjwt'
-__version__ = '1.7.1'
-__author__ = 'José Padilla'
-__license__ = 'MIT'
-__copyright__ = 'Copyright 2015-2018 José Padilla'
-
-
-from .api_jwt import (
- encode, decode, register_algorithm, unregister_algorithm,
- get_unverified_header, PyJWT
-)
-from .api_jws import PyJWS
-from .exceptions import (
- InvalidTokenError, DecodeError, InvalidAlgorithmError,
- InvalidAudienceError, ExpiredSignatureError, ImmatureSignatureError,
- InvalidIssuedAtError, InvalidIssuerError, ExpiredSignature,
- InvalidAudience, InvalidIssuer, MissingRequiredClaimError,
- InvalidSignatureError,
- PyJWTError,
-)
diff --git a/contrib/python/PyJWT/py2/jwt/__main__.py b/contrib/python/PyJWT/py2/jwt/__main__.py
deleted file mode 100644
index bf50aabf4a..0000000000
--- a/contrib/python/PyJWT/py2/jwt/__main__.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import absolute_import, print_function
-
-import argparse
-import json
-import sys
-import time
-
-from . import DecodeError, __version__, decode, encode
-
-
-def encode_payload(args):
- # Try to encode
- if args.key is None:
- raise ValueError('Key is required when encoding. See --help for usage.')
-
- # Build payload object to encode
- payload = {}
-
- for arg in args.payload:
- k, v = arg.split('=', 1)
-
- # exp +offset special case?
- if k == 'exp' and v[0] == '+' and len(v) > 1:
- v = str(int(time.time()+int(v[1:])))
-
- # Cast to integer?
- if v.isdigit():
- v = int(v)
- else:
- # Cast to float?
- try:
- v = float(v)
- except ValueError:
- pass
-
- # Cast to true, false, or null?
- constants = {'true': True, 'false': False, 'null': None}
-
- if v in constants:
- v = constants[v]
-
- payload[k] = v
-
- token = encode(
- payload,
- key=args.key,
- algorithm=args.algorithm
- )
-
- return token.decode('utf-8')
-
-
-def decode_payload(args):
- try:
- if args.token:
- token = args.token
- else:
- if sys.stdin.isatty():
- token = sys.stdin.readline().strip()
- else:
- raise IOError('Cannot read from stdin: terminal not a TTY')
-
- token = token.encode('utf-8')
- data = decode(token, key=args.key, verify=args.verify)
-
- return json.dumps(data)
-
- except DecodeError as e:
- raise DecodeError('There was an error decoding the token: %s' % e)
-
-
-def build_argparser():
-
- usage = '''
- Encodes or decodes JSON Web Tokens based on input.
-
- %(prog)s [options] <command> [options] input
-
- Decoding examples:
-
- %(prog)s --key=secret decode json.web.token
- %(prog)s decode --no-verify json.web.token
-
- Encoding requires the key option and takes space separated key/value pairs
- separated by equals (=) as input. Examples:
-
- %(prog)s --key=secret encode iss=me exp=1302049071
- %(prog)s --key=secret encode foo=bar exp=+10
-
- The exp key is special and can take an offset to current Unix time.
- '''
-
- arg_parser = argparse.ArgumentParser(
- prog='pyjwt',
- usage=usage
- )
-
- arg_parser.add_argument(
- '-v', '--version',
- action='version',
- version='%(prog)s ' + __version__
- )
-
- arg_parser.add_argument(
- '--key',
- dest='key',
- metavar='KEY',
- default=None,
- help='set the secret key to sign with'
- )
-
- arg_parser.add_argument(
- '--alg',
- dest='algorithm',
- metavar='ALG',
- default='HS256',
- help='set crypto algorithm to sign with. default=HS256'
- )
-
- subparsers = arg_parser.add_subparsers(
- title='PyJWT subcommands',
- description='valid subcommands',
- help='additional help'
- )
-
- # Encode subcommand
- encode_parser = subparsers.add_parser('encode', help='use to encode a supplied payload')
-
- payload_help = """Payload to encode. Must be a space separated list of key/value
- pairs separated by equals (=) sign."""
-
- encode_parser.add_argument('payload', nargs='+', help=payload_help)
- encode_parser.set_defaults(func=encode_payload)
-
- # Decode subcommand
- decode_parser = subparsers.add_parser('decode', help='use to decode a supplied JSON web token')
- decode_parser.add_argument(
- 'token',
- help='JSON web token to decode.',
- nargs='?')
-
- decode_parser.add_argument(
- '-n', '--no-verify',
- action='store_false',
- dest='verify',
- default=True,
- help='ignore signature and claims verification on decode'
- )
-
- decode_parser.set_defaults(func=decode_payload)
-
- return arg_parser
-
-
-def main():
- arg_parser = build_argparser()
-
- try:
- arguments = arg_parser.parse_args(sys.argv[1:])
-
- output = arguments.func(arguments)
-
- print(output)
- except Exception as e:
- print('There was an unforseen error: ', e)
- arg_parser.print_help()
diff --git a/contrib/python/PyJWT/py2/jwt/algorithms.py b/contrib/python/PyJWT/py2/jwt/algorithms.py
deleted file mode 100644
index 1343688341..0000000000
--- a/contrib/python/PyJWT/py2/jwt/algorithms.py
+++ /dev/null
@@ -1,403 +0,0 @@
-import hashlib
-import hmac
-import json
-
-
-from .compat import constant_time_compare, string_types
-from .exceptions import InvalidKeyError
-from .utils import (
- base64url_decode, base64url_encode, der_to_raw_signature,
- force_bytes, force_unicode, from_base64url_uint, raw_to_der_signature,
- to_base64url_uint
-)
-
-try:
- from cryptography.hazmat.primitives import hashes
- from cryptography.hazmat.primitives.serialization import (
- load_pem_private_key, load_pem_public_key, load_ssh_public_key
- )
- from cryptography.hazmat.primitives.asymmetric.rsa import (
- RSAPrivateKey, RSAPublicKey, RSAPrivateNumbers, RSAPublicNumbers,
- rsa_recover_prime_factors, rsa_crt_dmp1, rsa_crt_dmq1, rsa_crt_iqmp
- )
- from cryptography.hazmat.primitives.asymmetric.ec import (
- EllipticCurvePrivateKey, EllipticCurvePublicKey
- )
- from cryptography.hazmat.primitives.asymmetric import ec, padding
- from cryptography.hazmat.backends import default_backend
- from cryptography.exceptions import InvalidSignature
-
- has_crypto = True
-except ImportError:
- has_crypto = False
-
-requires_cryptography = set(['RS256', 'RS384', 'RS512', 'ES256', 'ES384',
- 'ES521', 'ES512', 'PS256', 'PS384', 'PS512'])
-
-
-def get_default_algorithms():
- """
- Returns the algorithms that are implemented by the library.
- """
- default_algorithms = {
- 'none': NoneAlgorithm(),
- 'HS256': HMACAlgorithm(HMACAlgorithm.SHA256),
- 'HS384': HMACAlgorithm(HMACAlgorithm.SHA384),
- 'HS512': HMACAlgorithm(HMACAlgorithm.SHA512)
- }
-
- if has_crypto:
- default_algorithms.update({
- 'RS256': RSAAlgorithm(RSAAlgorithm.SHA256),
- 'RS384': RSAAlgorithm(RSAAlgorithm.SHA384),
- 'RS512': RSAAlgorithm(RSAAlgorithm.SHA512),
- 'ES256': ECAlgorithm(ECAlgorithm.SHA256),
- 'ES384': ECAlgorithm(ECAlgorithm.SHA384),
- 'ES521': ECAlgorithm(ECAlgorithm.SHA512),
- 'ES512': ECAlgorithm(ECAlgorithm.SHA512), # Backward compat for #219 fix
- 'PS256': RSAPSSAlgorithm(RSAPSSAlgorithm.SHA256),
- 'PS384': RSAPSSAlgorithm(RSAPSSAlgorithm.SHA384),
- 'PS512': RSAPSSAlgorithm(RSAPSSAlgorithm.SHA512)
- })
-
- return default_algorithms
-
-
-class Algorithm(object):
- """
- The interface for an algorithm used to sign and verify tokens.
- """
- def prepare_key(self, key):
- """
- Performs necessary validation and conversions on the key and returns
- the key value in the proper format for sign() and verify().
- """
- raise NotImplementedError
-
- def sign(self, msg, key):
- """
- Returns a digital signature for the specified message
- using the specified key value.
- """
- raise NotImplementedError
-
- def verify(self, msg, key, sig):
- """
- Verifies that the specified digital signature is valid
- for the specified message and key values.
- """
- raise NotImplementedError
-
- @staticmethod
- def to_jwk(key_obj):
- """
- Serializes a given RSA key into a JWK
- """
- raise NotImplementedError
-
- @staticmethod
- def from_jwk(jwk):
- """
- Deserializes a given RSA key from JWK back into a PublicKey or PrivateKey object
- """
- raise NotImplementedError
-
-
-class NoneAlgorithm(Algorithm):
- """
- Placeholder for use when no signing or verification
- operations are required.
- """
- def prepare_key(self, key):
- if key == '':
- key = None
-
- if key is not None:
- raise InvalidKeyError('When alg = "none", key value must be None.')
-
- return key
-
- def sign(self, msg, key):
- return b''
-
- def verify(self, msg, key, sig):
- return False
-
-
-class HMACAlgorithm(Algorithm):
- """
- Performs signing and verification operations using HMAC
- and the specified hash function.
- """
- SHA256 = hashlib.sha256
- SHA384 = hashlib.sha384
- SHA512 = hashlib.sha512
-
- def __init__(self, hash_alg):
- self.hash_alg = hash_alg
-
- def prepare_key(self, key):
- key = force_bytes(key)
-
- invalid_strings = [
- b'-----BEGIN PUBLIC KEY-----',
- b'-----BEGIN CERTIFICATE-----',
- b'-----BEGIN RSA PUBLIC KEY-----',
- b'ssh-rsa'
- ]
-
- if any([string_value in key for string_value in invalid_strings]):
- raise InvalidKeyError(
- 'The specified key is an asymmetric key or x509 certificate and'
- ' should not be used as an HMAC secret.')
-
- return key
-
- @staticmethod
- def to_jwk(key_obj):
- return json.dumps({
- 'k': force_unicode(base64url_encode(force_bytes(key_obj))),
- 'kty': 'oct'
- })
-
- @staticmethod
- def from_jwk(jwk):
- obj = json.loads(jwk)
-
- if obj.get('kty') != 'oct':
- raise InvalidKeyError('Not an HMAC key')
-
- return base64url_decode(obj['k'])
-
- def sign(self, msg, key):
- return hmac.new(key, msg, self.hash_alg).digest()
-
- def verify(self, msg, key, sig):
- return constant_time_compare(sig, self.sign(msg, key))
-
-
-if has_crypto:
-
- class RSAAlgorithm(Algorithm):
- """
- Performs signing and verification operations using
- RSASSA-PKCS-v1_5 and the specified hash function.
- """
- SHA256 = hashes.SHA256
- SHA384 = hashes.SHA384
- SHA512 = hashes.SHA512
-
- def __init__(self, hash_alg):
- self.hash_alg = hash_alg
-
- def prepare_key(self, key):
- if isinstance(key, RSAPrivateKey) or \
- isinstance(key, RSAPublicKey):
- return key
-
- if isinstance(key, string_types):
- key = force_bytes(key)
-
- try:
- if key.startswith(b'ssh-rsa'):
- key = load_ssh_public_key(key, backend=default_backend())
- else:
- key = load_pem_private_key(key, password=None, backend=default_backend())
- except ValueError:
- key = load_pem_public_key(key, backend=default_backend())
- else:
- raise TypeError('Expecting a PEM-formatted key.')
-
- return key
-
- @staticmethod
- def to_jwk(key_obj):
- obj = None
-
- if getattr(key_obj, 'private_numbers', None):
- # Private key
- numbers = key_obj.private_numbers()
-
- obj = {
- 'kty': 'RSA',
- 'key_ops': ['sign'],
- 'n': force_unicode(to_base64url_uint(numbers.public_numbers.n)),
- 'e': force_unicode(to_base64url_uint(numbers.public_numbers.e)),
- 'd': force_unicode(to_base64url_uint(numbers.d)),
- 'p': force_unicode(to_base64url_uint(numbers.p)),
- 'q': force_unicode(to_base64url_uint(numbers.q)),
- 'dp': force_unicode(to_base64url_uint(numbers.dmp1)),
- 'dq': force_unicode(to_base64url_uint(numbers.dmq1)),
- 'qi': force_unicode(to_base64url_uint(numbers.iqmp))
- }
-
- elif getattr(key_obj, 'verify', None):
- # Public key
- numbers = key_obj.public_numbers()
-
- obj = {
- 'kty': 'RSA',
- 'key_ops': ['verify'],
- 'n': force_unicode(to_base64url_uint(numbers.n)),
- 'e': force_unicode(to_base64url_uint(numbers.e))
- }
- else:
- raise InvalidKeyError('Not a public or private key')
-
- return json.dumps(obj)
-
- @staticmethod
- def from_jwk(jwk):
- try:
- obj = json.loads(jwk)
- except ValueError:
- raise InvalidKeyError('Key is not valid JSON')
-
- if obj.get('kty') != 'RSA':
- raise InvalidKeyError('Not an RSA key')
-
- if 'd' in obj and 'e' in obj and 'n' in obj:
- # Private key
- if 'oth' in obj:
- raise InvalidKeyError('Unsupported RSA private key: > 2 primes not supported')
-
- other_props = ['p', 'q', 'dp', 'dq', 'qi']
- props_found = [prop in obj for prop in other_props]
- any_props_found = any(props_found)
-
- if any_props_found and not all(props_found):
- raise InvalidKeyError('RSA key must include all parameters if any are present besides d')
-
- public_numbers = RSAPublicNumbers(
- from_base64url_uint(obj['e']), from_base64url_uint(obj['n'])
- )
-
- if any_props_found:
- numbers = RSAPrivateNumbers(
- d=from_base64url_uint(obj['d']),
- p=from_base64url_uint(obj['p']),
- q=from_base64url_uint(obj['q']),
- dmp1=from_base64url_uint(obj['dp']),
- dmq1=from_base64url_uint(obj['dq']),
- iqmp=from_base64url_uint(obj['qi']),
- public_numbers=public_numbers
- )
- else:
- d = from_base64url_uint(obj['d'])
- p, q = rsa_recover_prime_factors(
- public_numbers.n, d, public_numbers.e
- )
-
- numbers = RSAPrivateNumbers(
- d=d,
- p=p,
- q=q,
- dmp1=rsa_crt_dmp1(d, p),
- dmq1=rsa_crt_dmq1(d, q),
- iqmp=rsa_crt_iqmp(p, q),
- public_numbers=public_numbers
- )
-
- return numbers.private_key(default_backend())
- elif 'n' in obj and 'e' in obj:
- # Public key
- numbers = RSAPublicNumbers(
- from_base64url_uint(obj['e']), from_base64url_uint(obj['n'])
- )
-
- return numbers.public_key(default_backend())
- else:
- raise InvalidKeyError('Not a public or private key')
-
- def sign(self, msg, key):
- return key.sign(msg, padding.PKCS1v15(), self.hash_alg())
-
- def verify(self, msg, key, sig):
- try:
- key.verify(sig, msg, padding.PKCS1v15(), self.hash_alg())
- return True
- except InvalidSignature:
- return False
-
- class ECAlgorithm(Algorithm):
- """
- Performs signing and verification operations using
- ECDSA and the specified hash function
- """
- SHA256 = hashes.SHA256
- SHA384 = hashes.SHA384
- SHA512 = hashes.SHA512
-
- def __init__(self, hash_alg):
- self.hash_alg = hash_alg
-
- def prepare_key(self, key):
- if isinstance(key, EllipticCurvePrivateKey) or \
- isinstance(key, EllipticCurvePublicKey):
- return key
-
- if isinstance(key, string_types):
- key = force_bytes(key)
-
- # Attempt to load key. We don't know if it's
- # a Signing Key or a Verifying Key, so we try
- # the Verifying Key first.
- try:
- if key.startswith(b'ecdsa-sha2-'):
- key = load_ssh_public_key(key, backend=default_backend())
- else:
- key = load_pem_public_key(key, backend=default_backend())
- except ValueError:
- key = load_pem_private_key(key, password=None, backend=default_backend())
-
- else:
- raise TypeError('Expecting a PEM-formatted key.')
-
- return key
-
- def sign(self, msg, key):
- der_sig = key.sign(msg, ec.ECDSA(self.hash_alg()))
-
- return der_to_raw_signature(der_sig, key.curve)
-
- def verify(self, msg, key, sig):
- try:
- der_sig = raw_to_der_signature(sig, key.curve)
- except ValueError:
- return False
-
- try:
- key.verify(der_sig, msg, ec.ECDSA(self.hash_alg()))
- return True
- except InvalidSignature:
- return False
-
- class RSAPSSAlgorithm(RSAAlgorithm):
- """
- Performs a signature using RSASSA-PSS with MGF1
- """
-
- def sign(self, msg, key):
- return key.sign(
- msg,
- padding.PSS(
- mgf=padding.MGF1(self.hash_alg()),
- salt_length=self.hash_alg.digest_size
- ),
- self.hash_alg()
- )
-
- def verify(self, msg, key, sig):
- try:
- key.verify(
- sig,
- msg,
- padding.PSS(
- mgf=padding.MGF1(self.hash_alg()),
- salt_length=self.hash_alg.digest_size
- ),
- self.hash_alg()
- )
- return True
- except InvalidSignature:
- return False
diff --git a/contrib/python/PyJWT/py2/jwt/api_jws.py b/contrib/python/PyJWT/py2/jwt/api_jws.py
deleted file mode 100644
index a9354adb06..0000000000
--- a/contrib/python/PyJWT/py2/jwt/api_jws.py
+++ /dev/null
@@ -1,242 +0,0 @@
-import binascii
-import json
-import warnings
-try:
- # import required by mypy to perform type checking, not used for normal execution
- from typing import Callable, Dict, List, Optional, Union # NOQA
-except ImportError:
- pass
-
-from .algorithms import (
- Algorithm, get_default_algorithms, has_crypto, requires_cryptography # NOQA
-)
-from .compat import Mapping, binary_type, string_types, text_type
-from .exceptions import (
- DecodeError, InvalidAlgorithmError, InvalidSignatureError,
- InvalidTokenError
-)
-from .utils import base64url_decode, base64url_encode, force_bytes, merge_dict
-
-
-class PyJWS(object):
- header_typ = 'JWT'
-
- def __init__(self, algorithms=None, options=None):
- self._algorithms = get_default_algorithms()
- self._valid_algs = (set(algorithms) if algorithms is not None
- else set(self._algorithms))
-
- # Remove algorithms that aren't on the whitelist
- for key in list(self._algorithms.keys()):
- if key not in self._valid_algs:
- del self._algorithms[key]
-
- if not options:
- options = {}
-
- self.options = merge_dict(self._get_default_options(), options)
-
- @staticmethod
- def _get_default_options():
- return {
- 'verify_signature': True
- }
-
- def register_algorithm(self, alg_id, alg_obj):
- """
- Registers a new Algorithm for use when creating and verifying tokens.
- """
- if alg_id in self._algorithms:
- raise ValueError('Algorithm already has a handler.')
-
- if not isinstance(alg_obj, Algorithm):
- raise TypeError('Object is not of type `Algorithm`')
-
- self._algorithms[alg_id] = alg_obj
- self._valid_algs.add(alg_id)
-
- def unregister_algorithm(self, alg_id):
- """
- Unregisters an Algorithm for use when creating and verifying tokens
- Throws KeyError if algorithm is not registered.
- """
- if alg_id not in self._algorithms:
- raise KeyError('The specified algorithm could not be removed'
- ' because it is not registered.')
-
- del self._algorithms[alg_id]
- self._valid_algs.remove(alg_id)
-
- def get_algorithms(self):
- """
- Returns a list of supported values for the 'alg' parameter.
- """
- return list(self._valid_algs)
-
- def encode(self,
- payload, # type: Union[Dict, bytes]
- key, # type: str
- algorithm='HS256', # type: str
- headers=None, # type: Optional[Dict]
- json_encoder=None # type: Optional[Callable]
- ):
- segments = []
-
- if algorithm is None:
- algorithm = 'none'
-
- if algorithm not in self._valid_algs:
- pass
-
- # Header
- header = {'typ': self.header_typ, 'alg': algorithm}
-
- if headers:
- self._validate_headers(headers)
- header.update(headers)
-
- json_header = force_bytes(
- json.dumps(
- header,
- separators=(',', ':'),
- cls=json_encoder
- )
- )
-
- segments.append(base64url_encode(json_header))
- segments.append(base64url_encode(payload))
-
- # Segments
- signing_input = b'.'.join(segments)
- try:
- alg_obj = self._algorithms[algorithm]
- key = alg_obj.prepare_key(key)
- signature = alg_obj.sign(signing_input, key)
-
- except KeyError:
- if not has_crypto and algorithm in requires_cryptography:
- raise NotImplementedError(
- "Algorithm '%s' could not be found. Do you have cryptography "
- "installed?" % algorithm
- )
- else:
- raise NotImplementedError('Algorithm not supported')
-
- segments.append(base64url_encode(signature))
-
- return b'.'.join(segments)
-
- def decode(self,
- jwt, # type: str
- key='', # type: str
- verify=True, # type: bool
- algorithms=None, # type: List[str]
- options=None, # type: Dict
- **kwargs):
-
- merged_options = merge_dict(self.options, options)
- verify_signature = merged_options['verify_signature']
-
- if verify_signature and not algorithms:
- warnings.warn(
- 'It is strongly recommended that you pass in a ' +
- 'value for the "algorithms" argument when calling decode(). ' +
- 'This argument will be mandatory in a future version.',
- DeprecationWarning
- )
-
- payload, signing_input, header, signature = self._load(jwt)
-
- if not verify:
- warnings.warn('The verify parameter is deprecated. '
- 'Please use verify_signature in options instead.',
- DeprecationWarning, stacklevel=2)
- elif verify_signature:
- self._verify_signature(payload, signing_input, header, signature,
- key, algorithms)
-
- return payload
-
- def get_unverified_header(self, jwt):
- """Returns back the JWT header parameters as a dict()
-
- Note: The signature is not verified so the header parameters
- should not be fully trusted until signature verification is complete
- """
- headers = self._load(jwt)[2]
- self._validate_headers(headers)
-
- return headers
-
- def _load(self, jwt):
- if isinstance(jwt, text_type):
- jwt = jwt.encode('utf-8')
-
- if not issubclass(type(jwt), binary_type):
- raise DecodeError("Invalid token type. Token must be a {0}".format(
- binary_type))
-
- try:
- signing_input, crypto_segment = jwt.rsplit(b'.', 1)
- header_segment, payload_segment = signing_input.split(b'.', 1)
- except ValueError:
- raise DecodeError('Not enough segments')
-
- try:
- header_data = base64url_decode(header_segment)
- except (TypeError, binascii.Error):
- raise DecodeError('Invalid header padding')
-
- try:
- header = json.loads(header_data.decode('utf-8'))
- except ValueError as e:
- raise DecodeError('Invalid header string: %s' % e)
-
- if not isinstance(header, Mapping):
- raise DecodeError('Invalid header string: must be a json object')
-
- try:
- payload = base64url_decode(payload_segment)
- except (TypeError, binascii.Error):
- raise DecodeError('Invalid payload padding')
-
- try:
- signature = base64url_decode(crypto_segment)
- except (TypeError, binascii.Error):
- raise DecodeError('Invalid crypto padding')
-
- return (payload, signing_input, header, signature)
-
- def _verify_signature(self, payload, signing_input, header, signature,
- key='', algorithms=None):
-
- alg = header.get('alg')
-
- if algorithms is not None and alg not in algorithms:
- raise InvalidAlgorithmError('The specified alg value is not allowed')
-
- try:
- alg_obj = self._algorithms[alg]
- key = alg_obj.prepare_key(key)
-
- if not alg_obj.verify(signing_input, key, signature):
- raise InvalidSignatureError('Signature verification failed')
-
- except KeyError:
- raise InvalidAlgorithmError('Algorithm not supported')
-
- def _validate_headers(self, headers):
- if 'kid' in headers:
- self._validate_kid(headers['kid'])
-
- def _validate_kid(self, kid):
- if not isinstance(kid, string_types):
- raise InvalidTokenError('Key ID header parameter must be a string')
-
-
-_jws_global_obj = PyJWS()
-encode = _jws_global_obj.encode
-decode = _jws_global_obj.decode
-register_algorithm = _jws_global_obj.register_algorithm
-unregister_algorithm = _jws_global_obj.unregister_algorithm
-get_unverified_header = _jws_global_obj.get_unverified_header
diff --git a/contrib/python/PyJWT/py2/jwt/api_jwt.py b/contrib/python/PyJWT/py2/jwt/api_jwt.py
deleted file mode 100644
index 85504acf93..0000000000
--- a/contrib/python/PyJWT/py2/jwt/api_jwt.py
+++ /dev/null
@@ -1,222 +0,0 @@
-import json
-import warnings
-from calendar import timegm
-from datetime import datetime, timedelta
-try:
- # import required by mypy to perform type checking, not used for normal execution
- from typing import Callable, Dict, List, Optional, Union # NOQA
-except ImportError:
- pass
-
-from .api_jws import PyJWS
-from .algorithms import Algorithm, get_default_algorithms # NOQA
-from .compat import Iterable, Mapping, string_types
-from .exceptions import (
- DecodeError, ExpiredSignatureError, ImmatureSignatureError,
- InvalidAudienceError, InvalidIssuedAtError,
- InvalidIssuerError, MissingRequiredClaimError
-)
-from .utils import merge_dict
-
-
-class PyJWT(PyJWS):
- header_type = 'JWT'
-
- @staticmethod
- def _get_default_options():
- # type: () -> Dict[str, bool]
- return {
- 'verify_signature': True,
- 'verify_exp': True,
- 'verify_nbf': True,
- 'verify_iat': True,
- 'verify_aud': True,
- 'verify_iss': True,
- 'require_exp': False,
- 'require_iat': False,
- 'require_nbf': False
- }
-
- def encode(self,
- payload, # type: Union[Dict, bytes]
- key, # type: str
- algorithm='HS256', # type: str
- headers=None, # type: Optional[Dict]
- json_encoder=None # type: Optional[Callable]
- ):
- # Check that we get a mapping
- if not isinstance(payload, Mapping):
- raise TypeError('Expecting a mapping object, as JWT only supports '
- 'JSON objects as payloads.')
-
- # Payload
- for time_claim in ['exp', 'iat', 'nbf']:
- # Convert datetime to a intDate value in known time-format claims
- if isinstance(payload.get(time_claim), datetime):
- payload[time_claim] = timegm(payload[time_claim].utctimetuple()) # type: ignore
-
- json_payload = json.dumps(
- payload,
- separators=(',', ':'),
- cls=json_encoder
- ).encode('utf-8')
-
- return super(PyJWT, self).encode(
- json_payload, key, algorithm, headers, json_encoder
- )
-
- def decode(self,
- jwt, # type: str
- key='', # type: str
- verify=True, # type: bool
- algorithms=None, # type: List[str]
- options=None, # type: Dict
- **kwargs):
-
- if verify and not algorithms:
- warnings.warn(
- 'It is strongly recommended that you pass in a ' +
- 'value for the "algorithms" argument when calling decode(). ' +
- 'This argument will be mandatory in a future version.',
- DeprecationWarning
- )
-
- payload, _, _, _ = self._load(jwt)
-
- if options is None:
- options = {'verify_signature': verify}
- else:
- options.setdefault('verify_signature', verify)
-
- decoded = super(PyJWT, self).decode(
- jwt, key=key, algorithms=algorithms, options=options, **kwargs
- )
-
- try:
- payload = json.loads(decoded.decode('utf-8'))
- except ValueError as e:
- raise DecodeError('Invalid payload string: %s' % e)
- if not isinstance(payload, Mapping):
- raise DecodeError('Invalid payload string: must be a json object')
-
- if verify:
- merged_options = merge_dict(self.options, options)
- self._validate_claims(payload, merged_options, **kwargs)
-
- return payload
-
- def _validate_claims(self, payload, options, audience=None, issuer=None,
- leeway=0, **kwargs):
-
- if 'verify_expiration' in kwargs:
- options['verify_exp'] = kwargs.get('verify_expiration', True)
- warnings.warn('The verify_expiration parameter is deprecated. '
- 'Please use verify_exp in options instead.',
- DeprecationWarning)
-
- if isinstance(leeway, timedelta):
- leeway = leeway.total_seconds()
-
- if not isinstance(audience, (string_types, type(None), Iterable)):
- raise TypeError('audience must be a string, iterable, or None')
-
- self._validate_required_claims(payload, options)
-
- now = timegm(datetime.utcnow().utctimetuple())
-
- if 'iat' in payload and options.get('verify_iat'):
- self._validate_iat(payload, now, leeway)
-
- if 'nbf' in payload and options.get('verify_nbf'):
- self._validate_nbf(payload, now, leeway)
-
- if 'exp' in payload and options.get('verify_exp'):
- self._validate_exp(payload, now, leeway)
-
- if options.get('verify_iss'):
- self._validate_iss(payload, issuer)
-
- if options.get('verify_aud'):
- self._validate_aud(payload, audience)
-
- def _validate_required_claims(self, payload, options):
- if options.get('require_exp') and payload.get('exp') is None:
- raise MissingRequiredClaimError('exp')
-
- if options.get('require_iat') and payload.get('iat') is None:
- raise MissingRequiredClaimError('iat')
-
- if options.get('require_nbf') and payload.get('nbf') is None:
- raise MissingRequiredClaimError('nbf')
-
- def _validate_iat(self, payload, now, leeway):
- try:
- int(payload['iat'])
- except ValueError:
- raise InvalidIssuedAtError('Issued At claim (iat) must be an integer.')
-
- def _validate_nbf(self, payload, now, leeway):
- try:
- nbf = int(payload['nbf'])
- except ValueError:
- raise DecodeError('Not Before claim (nbf) must be an integer.')
-
- if nbf > (now + leeway):
- raise ImmatureSignatureError('The token is not yet valid (nbf)')
-
- def _validate_exp(self, payload, now, leeway):
- try:
- exp = int(payload['exp'])
- except ValueError:
- raise DecodeError('Expiration Time claim (exp) must be an'
- ' integer.')
-
- if exp < (now - leeway):
- raise ExpiredSignatureError('Signature has expired')
-
- def _validate_aud(self, payload, audience):
- if audience is None and 'aud' not in payload:
- return
-
- if audience is not None and 'aud' not in payload:
- # Application specified an audience, but it could not be
- # verified since the token does not contain a claim.
- raise MissingRequiredClaimError('aud')
-
- if audience is None and 'aud' in payload:
- # Application did not specify an audience, but
- # the token has the 'aud' claim
- raise InvalidAudienceError('Invalid audience')
-
- audience_claims = payload['aud']
-
- if isinstance(audience_claims, string_types):
- audience_claims = [audience_claims]
- if not isinstance(audience_claims, list):
- raise InvalidAudienceError('Invalid claim format in token')
- if any(not isinstance(c, string_types) for c in audience_claims):
- raise InvalidAudienceError('Invalid claim format in token')
-
- if isinstance(audience, string_types):
- audience = [audience]
-
- if not any(aud in audience_claims for aud in audience):
- raise InvalidAudienceError('Invalid audience')
-
- def _validate_iss(self, payload, issuer):
- if issuer is None:
- return
-
- if 'iss' not in payload:
- raise MissingRequiredClaimError('iss')
-
- if payload['iss'] != issuer:
- raise InvalidIssuerError('Invalid issuer')
-
-
-_jwt_global_obj = PyJWT()
-encode = _jwt_global_obj.encode
-decode = _jwt_global_obj.decode
-register_algorithm = _jwt_global_obj.register_algorithm
-unregister_algorithm = _jwt_global_obj.unregister_algorithm
-get_unverified_header = _jwt_global_obj.get_unverified_header
diff --git a/contrib/python/PyJWT/py2/jwt/compat.py b/contrib/python/PyJWT/py2/jwt/compat.py
deleted file mode 100644
index e79e258e56..0000000000
--- a/contrib/python/PyJWT/py2/jwt/compat.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""
-The `compat` module provides support for backwards compatibility with older
-versions of python, and compatibility wrappers around optional packages.
-"""
-# flake8: noqa
-import hmac
-import struct
-import sys
-
-
-PY3 = sys.version_info[0] == 3
-
-
-if PY3:
- text_type = str
- binary_type = bytes
-else:
- text_type = unicode
- binary_type = str
-
-string_types = (text_type, binary_type)
-
-try:
- # Importing ABCs from collections will be removed in PY3.8
- from collections.abc import Iterable, Mapping
-except ImportError:
- from collections import Iterable, Mapping
-
-try:
- constant_time_compare = hmac.compare_digest
-except AttributeError:
- # Fallback for Python < 2.7
- def constant_time_compare(val1, val2):
- """
- Returns True if the two strings are equal, False otherwise.
-
- The time taken is independent of the number of characters that match.
- """
- if len(val1) != len(val2):
- return False
-
- result = 0
-
- for x, y in zip(val1, val2):
- result |= ord(x) ^ ord(y)
-
- return result == 0
-
-# Use int.to_bytes if it exists (Python 3)
-if getattr(int, 'to_bytes', None):
- def bytes_from_int(val):
- remaining = val
- byte_length = 0
-
- while remaining != 0:
- remaining = remaining >> 8
- byte_length += 1
-
- return val.to_bytes(byte_length, 'big', signed=False)
-else:
- def bytes_from_int(val):
- buf = []
- while val:
- val, remainder = divmod(val, 256)
- buf.append(remainder)
-
- buf.reverse()
- return struct.pack('%sB' % len(buf), *buf)
diff --git a/contrib/python/PyJWT/py2/jwt/contrib/__init__.py b/contrib/python/PyJWT/py2/jwt/contrib/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/PyJWT/py2/jwt/contrib/__init__.py
+++ /dev/null
diff --git a/contrib/python/PyJWT/py2/jwt/contrib/algorithms/__init__.py b/contrib/python/PyJWT/py2/jwt/contrib/algorithms/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/PyJWT/py2/jwt/contrib/algorithms/__init__.py
+++ /dev/null
diff --git a/contrib/python/PyJWT/py2/jwt/contrib/algorithms/py_ecdsa.py b/contrib/python/PyJWT/py2/jwt/contrib/algorithms/py_ecdsa.py
deleted file mode 100644
index bf0dea5ae2..0000000000
--- a/contrib/python/PyJWT/py2/jwt/contrib/algorithms/py_ecdsa.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Note: This file is named py_ecdsa.py because import behavior in Python 2
-# would cause ecdsa.py to squash the ecdsa library that it depends upon.
-
-import hashlib
-
-import ecdsa
-
-from jwt.algorithms import Algorithm
-from jwt.compat import string_types, text_type
-
-
-class ECAlgorithm(Algorithm):
- """
- Performs signing and verification operations using
- ECDSA and the specified hash function
-
- This class requires the ecdsa package to be installed.
-
- This is based off of the implementation in PyJWT 0.3.2
- """
- SHA256 = hashlib.sha256
- SHA384 = hashlib.sha384
- SHA512 = hashlib.sha512
-
- def __init__(self, hash_alg):
- self.hash_alg = hash_alg
-
- def prepare_key(self, key):
-
- if isinstance(key, ecdsa.SigningKey) or \
- isinstance(key, ecdsa.VerifyingKey):
- return key
-
- if isinstance(key, string_types):
- if isinstance(key, text_type):
- key = key.encode('utf-8')
-
- # Attempt to load key. We don't know if it's
- # a Signing Key or a Verifying Key, so we try
- # the Verifying Key first.
- try:
- key = ecdsa.VerifyingKey.from_pem(key)
- except ecdsa.der.UnexpectedDER:
- key = ecdsa.SigningKey.from_pem(key)
-
- else:
- raise TypeError('Expecting a PEM-formatted key.')
-
- return key
-
- def sign(self, msg, key):
- return key.sign(msg, hashfunc=self.hash_alg,
- sigencode=ecdsa.util.sigencode_string)
-
- def verify(self, msg, key, sig):
- try:
- return key.verify(sig, msg, hashfunc=self.hash_alg,
- sigdecode=ecdsa.util.sigdecode_string)
- except AssertionError:
- return False
diff --git a/contrib/python/PyJWT/py2/jwt/contrib/algorithms/pycrypto.py b/contrib/python/PyJWT/py2/jwt/contrib/algorithms/pycrypto.py
deleted file mode 100644
index e49cdbfe40..0000000000
--- a/contrib/python/PyJWT/py2/jwt/contrib/algorithms/pycrypto.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import Crypto.Hash.SHA256
-import Crypto.Hash.SHA384
-import Crypto.Hash.SHA512
-from Crypto.PublicKey import RSA
-from Crypto.Signature import PKCS1_v1_5
-
-from jwt.algorithms import Algorithm
-from jwt.compat import string_types, text_type
-
-
-class RSAAlgorithm(Algorithm):
- """
- Performs signing and verification operations using
- RSASSA-PKCS-v1_5 and the specified hash function.
-
- This class requires PyCrypto package to be installed.
-
- This is based off of the implementation in PyJWT 0.3.2
- """
- SHA256 = Crypto.Hash.SHA256
- SHA384 = Crypto.Hash.SHA384
- SHA512 = Crypto.Hash.SHA512
-
- def __init__(self, hash_alg):
- self.hash_alg = hash_alg
-
- def prepare_key(self, key):
-
- if isinstance(key, RSA._RSAobj):
- return key
-
- if isinstance(key, string_types):
- if isinstance(key, text_type):
- key = key.encode('utf-8')
-
- key = RSA.importKey(key)
- else:
- raise TypeError('Expecting a PEM- or RSA-formatted key.')
-
- return key
-
- def sign(self, msg, key):
- return PKCS1_v1_5.new(key).sign(self.hash_alg.new(msg))
-
- def verify(self, msg, key, sig):
- return PKCS1_v1_5.new(key).verify(self.hash_alg.new(msg), sig)
diff --git a/contrib/python/PyJWT/py2/jwt/exceptions.py b/contrib/python/PyJWT/py2/jwt/exceptions.py
deleted file mode 100644
index 2a6aa596ba..0000000000
--- a/contrib/python/PyJWT/py2/jwt/exceptions.py
+++ /dev/null
@@ -1,59 +0,0 @@
-class PyJWTError(Exception):
- """
- Base class for all exceptions
- """
- pass
-
-
-class InvalidTokenError(PyJWTError):
- pass
-
-
-class DecodeError(InvalidTokenError):
- pass
-
-
-class InvalidSignatureError(DecodeError):
- pass
-
-
-class ExpiredSignatureError(InvalidTokenError):
- pass
-
-
-class InvalidAudienceError(InvalidTokenError):
- pass
-
-
-class InvalidIssuerError(InvalidTokenError):
- pass
-
-
-class InvalidIssuedAtError(InvalidTokenError):
- pass
-
-
-class ImmatureSignatureError(InvalidTokenError):
- pass
-
-
-class InvalidKeyError(PyJWTError):
- pass
-
-
-class InvalidAlgorithmError(InvalidTokenError):
- pass
-
-
-class MissingRequiredClaimError(InvalidTokenError):
- def __init__(self, claim):
- self.claim = claim
-
- def __str__(self):
- return 'Token is missing the "%s" claim' % self.claim
-
-
-# Compatibility aliases (deprecated)
-ExpiredSignature = ExpiredSignatureError
-InvalidAudience = InvalidAudienceError
-InvalidIssuer = InvalidIssuerError
diff --git a/contrib/python/PyJWT/py2/jwt/help.py b/contrib/python/PyJWT/py2/jwt/help.py
deleted file mode 100644
index 55e39ebb27..0000000000
--- a/contrib/python/PyJWT/py2/jwt/help.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from __future__ import print_function
-
-import json
-import platform
-import sys
-
-from . import __version__ as pyjwt_version
-
-try:
- import cryptography
-except ImportError:
- cryptography = None
-
-try:
- import ecdsa
-except ImportError:
- ecdsa = None
-
-
-def info():
- """
- Generate information for a bug report.
- Based on the requests package help utility module.
- """
- try:
- platform_info = {"system": platform.system(), "release": platform.release()}
- except IOError:
- platform_info = {"system": "Unknown", "release": "Unknown"}
-
- implementation = platform.python_implementation()
-
- if implementation == "CPython":
- implementation_version = platform.python_version()
- elif implementation == "PyPy":
- implementation_version = "%s.%s.%s" % (
- sys.pypy_version_info.major,
- sys.pypy_version_info.minor,
- sys.pypy_version_info.micro,
- )
- if sys.pypy_version_info.releaselevel != "final":
- implementation_version = "".join(
- [implementation_version, sys.pypy_version_info.releaselevel]
- )
- else:
- implementation_version = "Unknown"
-
- return {
- "platform": platform_info,
- "implementation": {"name": implementation, "version": implementation_version},
- "cryptography": {"version": getattr(cryptography, "__version__", "")},
- "pyjwt": {"version": pyjwt_version},
- }
-
-
-def main():
- """Pretty-print the bug information as JSON."""
- print(json.dumps(info(), sort_keys=True, indent=2))
-
-
-if __name__ == "__main__":
- main()
diff --git a/contrib/python/PyJWT/py2/jwt/utils.py b/contrib/python/PyJWT/py2/jwt/utils.py
deleted file mode 100644
index b33c7a2d45..0000000000
--- a/contrib/python/PyJWT/py2/jwt/utils.py
+++ /dev/null
@@ -1,113 +0,0 @@
-import base64
-import binascii
-import struct
-
-from .compat import binary_type, bytes_from_int, text_type
-
-try:
- from cryptography.hazmat.primitives.asymmetric.utils import (
- decode_dss_signature, encode_dss_signature
- )
-except ImportError:
- pass
-
-
-def force_unicode(value):
- if isinstance(value, binary_type):
- return value.decode('utf-8')
- elif isinstance(value, text_type):
- return value
- else:
- raise TypeError('Expected a string value')
-
-
-def force_bytes(value):
- if isinstance(value, text_type):
- return value.encode('utf-8')
- elif isinstance(value, binary_type):
- return value
- else:
- raise TypeError('Expected a string value')
-
-
-def base64url_decode(input):
- if isinstance(input, text_type):
- input = input.encode('ascii')
-
- rem = len(input) % 4
-
- if rem > 0:
- input += b'=' * (4 - rem)
-
- return base64.urlsafe_b64decode(input)
-
-
-def base64url_encode(input):
- return base64.urlsafe_b64encode(input).replace(b'=', b'')
-
-
-def to_base64url_uint(val):
- if val < 0:
- raise ValueError('Must be a positive integer')
-
- int_bytes = bytes_from_int(val)
-
- if len(int_bytes) == 0:
- int_bytes = b'\x00'
-
- return base64url_encode(int_bytes)
-
-
-def from_base64url_uint(val):
- if isinstance(val, text_type):
- val = val.encode('ascii')
-
- data = base64url_decode(val)
-
- buf = struct.unpack('%sB' % len(data), data)
- return int(''.join(["%02x" % byte for byte in buf]), 16)
-
-
-def merge_dict(original, updates):
- if not updates:
- return original
-
- try:
- merged_options = original.copy()
- merged_options.update(updates)
- except (AttributeError, ValueError) as e:
- raise TypeError('original and updates must be a dictionary: %s' % e)
-
- return merged_options
-
-
-def number_to_bytes(num, num_bytes):
- padded_hex = '%0*x' % (2 * num_bytes, num)
- big_endian = binascii.a2b_hex(padded_hex.encode('ascii'))
- return big_endian
-
-
-def bytes_to_number(string):
- return int(binascii.b2a_hex(string), 16)
-
-
-def der_to_raw_signature(der_sig, curve):
- num_bits = curve.key_size
- num_bytes = (num_bits + 7) // 8
-
- r, s = decode_dss_signature(der_sig)
-
- return number_to_bytes(r, num_bytes) + number_to_bytes(s, num_bytes)
-
-
-def raw_to_der_signature(raw_sig, curve):
- num_bits = curve.key_size
- num_bytes = (num_bits + 7) // 8
-
- if len(raw_sig) != 2 * num_bytes:
- raise ValueError('Invalid signature')
-
- r = bytes_to_number(raw_sig[:num_bytes])
- s = bytes_to_number(raw_sig[num_bytes:])
-
- return encode_dss_signature(r, s)
diff --git a/contrib/python/PyJWT/py2/ya.make b/contrib/python/PyJWT/py2/ya.make
deleted file mode 100644
index 57a9352fba..0000000000
--- a/contrib/python/PyJWT/py2/ya.make
+++ /dev/null
@@ -1,43 +0,0 @@
-# Generated by devtools/yamaker (pypi).
-
-PY2_LIBRARY()
-
-VERSION(1.7.1)
-
-LICENSE(MIT)
-
-PEERDIR(
- contrib/python/cryptography
-)
-
-NO_LINT()
-
-NO_CHECK_IMPORTS(
- jwt.contrib.*
-)
-
-PY_SRCS(
- TOP_LEVEL
- jwt/__init__.py
- jwt/__main__.py
- jwt/algorithms.py
- jwt/api_jws.py
- jwt/api_jwt.py
- jwt/compat.py
- jwt/contrib/__init__.py
- jwt/contrib/algorithms/__init__.py
- jwt/contrib/algorithms/py_ecdsa.py
- jwt/contrib/algorithms/pycrypto.py
- jwt/exceptions.py
- jwt/help.py
- jwt/utils.py
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/PyJWT/py2/
- .dist-info/METADATA
- .dist-info/entry_points.txt
- .dist-info/top_level.txt
-)
-
-END()
diff --git a/contrib/python/ydb/py3/.dist-info/METADATA b/contrib/python/ydb/py3/.dist-info/METADATA
index d921ac7f1f..e7397b376d 100644
--- a/contrib/python/ydb/py3/.dist-info/METADATA
+++ b/contrib/python/ydb/py3/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: ydb
-Version: 3.9.0
+Version: 3.10.0
Summary: YDB Python SDK
Home-page: http://github.com/ydb-platform/ydb-python-sdk
Author: Yandex LLC
@@ -18,7 +18,6 @@ Requires-Dist: grpcio >=1.42.0
Requires-Dist: packaging
Requires-Dist: protobuf <5.0.0,>=3.13.0
Requires-Dist: aiohttp <4
-Requires-Dist: pyjwt ==2.8.0
Provides-Extra: yc
Requires-Dist: yandexcloud ; extra == 'yc'
diff --git a/contrib/python/ydb/py3/ya.make b/contrib/python/ydb/py3/ya.make
index b8611eae13..df4b531e51 100644
--- a/contrib/python/ydb/py3/ya.make
+++ b/contrib/python/ydb/py3/ya.make
@@ -2,12 +2,11 @@
PY3_LIBRARY()
-VERSION(3.9.0)
+VERSION(3.10.0)
LICENSE(Apache-2.0)
PEERDIR(
- contrib/python/PyJWT
contrib/python/aiohttp
contrib/python/grpcio
contrib/python/packaging
diff --git a/contrib/python/ydb/py3/ydb/_topic_reader/topic_reader_sync.py b/contrib/python/ydb/py3/ydb/_topic_reader/topic_reader_sync.py
index e5b4e1a2b4..c266de828e 100644
--- a/contrib/python/ydb/py3/ydb/_topic_reader/topic_reader_sync.py
+++ b/contrib/python/ydb/py3/ydb/_topic_reader/topic_reader_sync.py
@@ -76,11 +76,11 @@ class TopicReaderSync:
def async_wait_message(self) -> concurrent.futures.Future:
"""
- Return future, which will completed when the reader has least one message in queue.
- If reader already has message - future will return completed.
+ Returns a future, which will complete when the reader has at least one message in queue.
+ If the reader already has a message - the future will complete immediately.
- Possible situation when receive signal about message available, but no messages when try to receive a message.
- If message expired between send event and try to retrieve message (for example connection broken).
+ A message may expire before it gets read so that the attempt to receive the massage will fail
+ despite the future has signaled about its availability.
"""
self._check_closed()
diff --git a/contrib/python/ydb/py3/ydb/aio/iam.py b/contrib/python/ydb/py3/ydb/aio/iam.py
index 40622f8a9d..eab8faffe0 100644
--- a/contrib/python/ydb/py3/ydb/aio/iam.py
+++ b/contrib/python/ydb/py3/ydb/aio/iam.py
@@ -5,19 +5,15 @@ import abc
import logging
from ydb.iam import auth
from .credentials import AbstractExpiringTokenCredentials
-from ydb import issues
logger = logging.getLogger(__name__)
try:
- import jwt
-except ImportError:
- jwt = None
-
-try:
from yandex.cloud.iam.v1 import iam_token_service_pb2_grpc
from yandex.cloud.iam.v1 import iam_token_service_pb2
+ import jwt
except ImportError:
+ jwt = None
iam_token_service_pb2_grpc = None
iam_token_service_pb2 = None
@@ -59,51 +55,6 @@ class TokenServiceCredentials(AbstractExpiringTokenCredentials):
IamTokenCredentials = TokenServiceCredentials
-class OAuth2JwtTokenExchangeCredentials(AbstractExpiringTokenCredentials, auth.BaseJWTCredentials):
- def __init__(
- self,
- token_exchange_url,
- account_id,
- access_key_id,
- private_key,
- algorithm,
- token_service_url,
- subject=None,
- ):
- super(OAuth2JwtTokenExchangeCredentials, self).__init__()
- auth.BaseJWTCredentials.__init__(
- self, account_id, access_key_id, private_key, algorithm, token_service_url, subject
- )
- assert aiohttp is not None, "Install aiohttp library to use OAuth 2.0 token exchange credentials provider"
- self._token_exchange_url = token_exchange_url
-
- async def _make_token_request(self):
- params = {
- "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
- "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
- "subject_token": self._get_jwt(),
- "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
- }
- headers = {"Content-Type": "application/x-www-form-urlencoded"}
-
- timeout = aiohttp.ClientTimeout(total=2)
- async with aiohttp.ClientSession(timeout=timeout) as session:
- async with session.post(self._token_exchange_url, data=params, headers=headers) as response:
- if response.status == 403:
- raise issues.Unauthenticated(await response.text())
- if response.status >= 500:
- raise issues.Unavailable(await response.text())
- if response.status >= 400:
- raise issues.BadRequest(await response.text())
- if response.status != 200:
- raise issues.Error(await response.text())
-
- response_json = await response.json()
- access_token = response_json["access_token"]
- expires_in = response_json["expires_in"]
- return {"access_token": access_token, "expires_in": expires_in}
-
-
class JWTIamCredentials(TokenServiceCredentials, auth.BaseJWTCredentials):
def __init__(
self,
@@ -114,39 +65,16 @@ class JWTIamCredentials(TokenServiceCredentials, auth.BaseJWTCredentials):
iam_channel_credentials=None,
):
TokenServiceCredentials.__init__(self, iam_endpoint, iam_channel_credentials)
- auth.BaseJWTCredentials.__init__(
- self,
- account_id,
- access_key_id,
- private_key,
- auth.YANDEX_CLOUD_JWT_ALGORITHM,
- auth.YANDEX_CLOUD_IAM_TOKEN_SERVICE_URL,
- )
+ auth.BaseJWTCredentials.__init__(self, account_id, access_key_id, private_key)
def _get_token_request(self):
- return iam_token_service_pb2.CreateIamTokenRequest(jwt=self._get_jwt())
-
-
-class NebiusJWTIamCredentials(OAuth2JwtTokenExchangeCredentials):
- def __init__(
- self,
- account_id,
- access_key_id,
- private_key,
- token_exchange_url=None,
- ):
- url = token_exchange_url
- if url is None:
- url = auth.NEBIUS_CLOUD_IAM_TOKEN_EXCHANGE_URL
- OAuth2JwtTokenExchangeCredentials.__init__(
- self,
- url,
- account_id,
- access_key_id,
- private_key,
- auth.NEBIUS_CLOUD_JWT_ALGORITHM,
- auth.NEBIUS_CLOUD_IAM_TOKEN_SERVICE_AUDIENCE,
- account_id,
+ return iam_token_service_pb2.CreateIamTokenRequest(
+ jwt=auth.get_jwt(
+ self._account_id,
+ self._access_key_id,
+ self._private_key,
+ self._jwt_expiration_timeout,
+ )
)
@@ -202,20 +130,3 @@ class ServiceAccountCredentials(JWTIamCredentials):
iam_endpoint,
iam_channel_credentials,
)
-
-
-class NebiusServiceAccountCredentials(NebiusJWTIamCredentials):
- def __init__(
- self,
- service_account_id,
- access_key_id,
- private_key,
- iam_endpoint=None,
- iam_channel_credentials=None,
- ):
- super(NebiusServiceAccountCredentials, self).__init__(
- service_account_id,
- access_key_id,
- private_key,
- iam_endpoint,
- )
diff --git a/contrib/python/ydb/py3/ydb/driver.py b/contrib/python/ydb/py3/ydb/driver.py
index 16bba15154..89109b9b57 100644
--- a/contrib/python/ydb/py3/ydb/driver.py
+++ b/contrib/python/ydb/py3/ydb/driver.py
@@ -38,13 +38,6 @@ def credentials_from_env_variables(tracer=None):
return ydb.iam.ServiceAccountCredentials.from_file(service_account_key_file)
- nebius_service_account_key_file = os.getenv("YDB_NEBIUS_SERVICE_ACCOUNT_KEY_FILE_CREDENTIALS")
- if nebius_service_account_key_file is not None:
- ctx.trace({"credentials.nebius_service_account_key_file": True})
- import ydb.iam
-
- return ydb.iam.NebiusServiceAccountCredentials.from_file(nebius_service_account_key_file)
-
anonymous_credetials = os.getenv("YDB_ANONYMOUS_CREDENTIALS", "0") == "1"
if anonymous_credetials:
ctx.trace({"credentials.anonymous": True})
diff --git a/contrib/python/ydb/py3/ydb/iam/__init__.py b/contrib/python/ydb/py3/ydb/iam/__init__.py
index cf835769db..7167efe13e 100644
--- a/contrib/python/ydb/py3/ydb/iam/__init__.py
+++ b/contrib/python/ydb/py3/ydb/iam/__init__.py
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
from .auth import ServiceAccountCredentials # noqa
-from .auth import NebiusServiceAccountCredentials # noqa
from .auth import MetadataUrlCredentials # noqa
diff --git a/contrib/python/ydb/py3/ydb/iam/auth.py b/contrib/python/ydb/py3/ydb/iam/auth.py
index 852c0c28bb..82e7c9f6c8 100644
--- a/contrib/python/ydb/py3/ydb/iam/auth.py
+++ b/contrib/python/ydb/py3/ydb/iam/auth.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from ydb import credentials, tracing, issues
+from ydb import credentials, tracing
import grpc
import time
import abc
@@ -8,14 +8,11 @@ import json
import os
try:
- import jwt
-except ImportError:
- jwt = None
-
-try:
from yandex.cloud.iam.v1 import iam_token_service_pb2_grpc
from yandex.cloud.iam.v1 import iam_token_service_pb2
+ import jwt
except ImportError:
+ jwt = None
iam_token_service_pb2_grpc = None
iam_token_service_pb2 = None
@@ -26,32 +23,22 @@ except ImportError:
DEFAULT_METADATA_URL = "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token"
-YANDEX_CLOUD_IAM_TOKEN_SERVICE_URL = "https://iam.api.cloud.yandex.net/iam/v1/tokens"
-NEBIUS_CLOUD_IAM_TOKEN_SERVICE_AUDIENCE = "token-service.iam.new.nebiuscloud.net"
-NEBIUS_CLOUD_IAM_TOKEN_EXCHANGE_URL = "https://auth.new.nebiuscloud.net/oauth2/token/exchange"
-YANDEX_CLOUD_JWT_ALGORITHM = "PS256"
-NEBIUS_CLOUD_JWT_ALGORITHM = "RS256"
-
-def get_jwt(account_id, access_key_id, private_key, jwt_expiration_timeout, algorithm, token_service_url, subject=None):
- assert jwt is not None, "Install pyjwt library to use jwt tokens"
+def get_jwt(account_id, access_key_id, private_key, jwt_expiration_timeout):
now = time.time()
now_utc = datetime.utcfromtimestamp(now)
exp_utc = datetime.utcfromtimestamp(now + jwt_expiration_timeout)
- payload = {
- "iss": account_id,
- "aud": token_service_url,
- "iat": now_utc,
- "exp": exp_utc,
- }
- if subject is not None:
- payload["sub"] = subject
return jwt.encode(
key=private_key,
- algorithm=algorithm,
- headers={"typ": "JWT", "alg": algorithm, "kid": access_key_id},
- payload=payload,
+ algorithm="PS256",
+ headers={"typ": "JWT", "alg": "PS256", "kid": access_key_id},
+ payload={
+ "iss": account_id,
+ "aud": "https://iam.api.cloud.yandex.net/iam/v1/tokens",
+ "iat": now_utc,
+ "exp": exp_utc,
+ },
)
@@ -86,15 +73,12 @@ class TokenServiceCredentials(credentials.AbstractExpiringTokenCredentials):
class BaseJWTCredentials(abc.ABC):
- def __init__(self, account_id, access_key_id, private_key, algorithm, token_service_url, subject=None):
+ def __init__(self, account_id, access_key_id, private_key):
self._account_id = account_id
self._jwt_expiration_timeout = 60.0 * 60
self._token_expiration_timeout = 120
self._access_key_id = access_key_id
self._private_key = private_key
- self._algorithm = algorithm
- self._token_service_url = token_service_url
- self._subject = subject
def set_token_expiration_timeout(self, value):
self._token_expiration_timeout = value
@@ -115,64 +99,6 @@ class BaseJWTCredentials(abc.ABC):
iam_channel_credentials=iam_channel_credentials,
)
- def _get_jwt(self):
- return get_jwt(
- self._account_id,
- self._access_key_id,
- self._private_key,
- self._jwt_expiration_timeout,
- self._algorithm,
- self._token_service_url,
- self._subject,
- )
-
-
-class OAuth2JwtTokenExchangeCredentials(credentials.AbstractExpiringTokenCredentials, BaseJWTCredentials):
- def __init__(
- self,
- token_exchange_url,
- account_id,
- access_key_id,
- private_key,
- algorithm,
- token_service_url,
- subject=None,
- tracer=None,
- ):
- BaseJWTCredentials.__init__(self, account_id, access_key_id, private_key, algorithm, token_service_url, subject)
- super(OAuth2JwtTokenExchangeCredentials, self).__init__(tracer)
- assert requests is not None, "Install requests library to use OAuth 2.0 token exchange credentials provider"
- self._token_exchange_url = token_exchange_url
-
- def _process_response_status_code(self, response):
- if response.status_code == 403:
- raise issues.Unauthenticated(response.content)
- if response.status_code >= 500:
- raise issues.Unavailable(response.content)
- if response.status_code >= 400:
- raise issues.BadRequest(response.content)
- if response.status_code != 200:
- raise issues.Error(response.content)
-
- def _process_response(self, response):
- self._process_response_status_code(response)
- response_json = json.loads(response.content)
- access_token = response_json["access_token"]
- expires_in = response_json["expires_in"]
- return {"access_token": access_token, "expires_in": expires_in}
-
- @tracing.with_trace()
- def _make_token_request(self):
- params = {
- "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
- "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
- "subject_token": self._get_jwt(),
- "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
- }
- headers = {"Content-Type": "application/x-www-form-urlencoded"}
- response = requests.post(self._token_exchange_url, data=params, headers=headers)
- return self._process_response(response)
-
class JWTIamCredentials(TokenServiceCredentials, BaseJWTCredentials):
def __init__(
@@ -184,34 +110,16 @@ class JWTIamCredentials(TokenServiceCredentials, BaseJWTCredentials):
iam_channel_credentials=None,
):
TokenServiceCredentials.__init__(self, iam_endpoint, iam_channel_credentials)
- BaseJWTCredentials.__init__(
- self, account_id, access_key_id, private_key, YANDEX_CLOUD_JWT_ALGORITHM, YANDEX_CLOUD_IAM_TOKEN_SERVICE_URL
- )
+ BaseJWTCredentials.__init__(self, account_id, access_key_id, private_key)
def _get_token_request(self):
- return self._iam_token_service_pb2.CreateIamTokenRequest(jwt=self._get_jwt())
-
-
-class NebiusJWTIamCredentials(OAuth2JwtTokenExchangeCredentials):
- def __init__(
- self,
- account_id,
- access_key_id,
- private_key,
- token_exchange_url=None,
- ):
- url = token_exchange_url
- if url is None:
- url = NEBIUS_CLOUD_IAM_TOKEN_EXCHANGE_URL
- OAuth2JwtTokenExchangeCredentials.__init__(
- self,
- url,
- account_id,
- access_key_id,
- private_key,
- NEBIUS_CLOUD_JWT_ALGORITHM,
- NEBIUS_CLOUD_IAM_TOKEN_SERVICE_AUDIENCE,
- account_id,
+ return self._iam_token_service_pb2.CreateIamTokenRequest(
+ jwt=get_jwt(
+ self._account_id,
+ self._access_key_id,
+ self._private_key,
+ self._jwt_expiration_timeout,
+ )
)
@@ -268,20 +176,3 @@ class ServiceAccountCredentials(JWTIamCredentials):
iam_endpoint,
iam_channel_credentials,
)
-
-
-class NebiusServiceAccountCredentials(NebiusJWTIamCredentials):
- def __init__(
- self,
- service_account_id,
- access_key_id,
- private_key,
- iam_endpoint=None,
- iam_channel_credentials=None,
- ):
- super(NebiusServiceAccountCredentials, self).__init__(
- service_account_id,
- access_key_id,
- private_key,
- iam_endpoint,
- )
diff --git a/contrib/python/ydb/py3/ydb/ydb_version.py b/contrib/python/ydb/py3/ydb/ydb_version.py
index 10baa2a41a..71960e35b5 100644
--- a/contrib/python/ydb/py3/ydb/ydb_version.py
+++ b/contrib/python/ydb/py3/ydb/ydb_version.py
@@ -1 +1 @@
-VERSION = "3.9.0"
+VERSION = "3.10.0"