WhintPy 1.1

https://sourceforge.net/projects/whintpy/

Module whintpy.connection

Class JwtAuthentication

Description

JSON Web Tokens authentication method.

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

JwtAuthentication allows to decode, verify and generate JWT.

Constructor

Create a JwtAuthentication instance.

Parameters
  • secret_key: (str) The secret key
View Source
def __init__(self, secret_key: str, **kwargs):
    """Create a JwtAuthentication instance.

    :param secret_key: (str) The secret key

    """
    super(JwtAuthentication, self).__init__(**kwargs)
    self._available = JWT
    if self._available is False:
        logging.warning("JwtAuthentication was not initialized: requirement to 'jwt' module is not satisfied.")
    else:
        if isinstance(secret_key, str) is False:
            raise TypeError(f"JwtAuthentication secret key must be a 'str'. Got '{type(secret_key).__name__}' instead.")
        self.__secret_key = secret_key

Public functions

name

Override. Return the name of the authentication method.

Returns
  • (str) The name of the authentication method.
View Source
@staticmethod
def name() -> str:
    """Override. Return the name of the authentication method.

        :return: (str) The name of the authentication method.

        """
    return BaseAuthentication._get_default_name(JwtAuthentication)

get_args

Return the secret key of the JWT.

Returns
  • (list) The secret key or an empty list if JWT is not available
View Source
def get_args(self) -> list:
    """Return the secret key of the JWT.

        :return: (list) The secret key or an empty list if JWT is not available

        """
    if self._available is True:
        return [self.__secret_key]
    return []

authenticate

Verify a token.

Verify by decoding the given token, and checking both its validity and expiration date.

Parameters
  • token: (str) The token to verify
Returns
  • (bool) True if the token is valid, False otherwise)
View Source
def authenticate(self, token: str) -> tuple[bool, str]:
    """Verify a token.

        Verify by decoding the given token, and checking both its validity
        and expiration date.

        :param token: (str) The token to verify
        :return: (bool) True if the token is valid, False otherwise)

        """
    if self._available is False:
        return (False, 'JwtAuthentication unavailable')
    if isinstance(token, str) is False:
        raise TypeError(f"JwtAuthentication.authenticate: Token must be a 'string'. Got a '{type(token).__name__}' instead.")
    if len(token) == 0:
        return (False, 'Token is empty')
    try:
        return (True, self.decode_token(token))
    except KeyError:
        return (False, 'Token is invalid')

generate_token

Generate a JWT token from the given parameter.

Parameters
  • entry: (str) The string to encode in the token
  • validity: (int) The amount of time in seconds that the token should expire
Returns
  • (str | None) A coded token or None if JWT is not available
Raises
  • TypeError: if the entry is invalid
View Source
def generate_token(self, entry: str, validity: int=30) -> str | None:
    """Generate a JWT token from the given parameter.

        :param entry: (str) The string to encode in the token
        :param validity: (int) The amount of time in seconds that the token should expire
        :return: (str | None) A coded token or None if JWT is not available
        :raises: TypeError: if the entry is invalid

        """
    if self._available is False:
        return None
    if isinstance(entry, str) is False:
        raise TypeError(f'Entry to generate a token must be a string.Got {type(entry).__name__} instead.')
    if isinstance(validity, int) is False:
        logging.error("JwtAuthentication.generate_token: validity must be a 'int'. Set to 30 minutes.")
        validity = 30
    payload = {'exp': datetime.now(tz=timezone.utc) + timedelta(minutes=validity), 'iat': datetime.now(tz=timezone.utc), 'sub': entry}
    return jwt.encode(payload, self.__secret_key, algorithm='HS256')

decode_token

Decode a JWT token.

Parameters
  • token: (str) the token to be decoded
Returns
  • (str | None) the decoded token or None if JWT is not available
Raises
  • KeyError: if the token is invalid
  • KeyError: if the token is expired
View Source
def decode_token(self, token: str) -> str | None:
    """Decode a JWT token.

        :param token: (str) the token to be decoded
        :return: (str | None) the decoded token or None if JWT is not available
        :raises: KeyError: if the token is invalid
        :raises: KeyError: if the token is expired

        """
    if self._available is False:
        return None
    if isinstance(token, str) is False:
        raise TypeError(f'Token to be decoded must be a string.Got {type(token).__name__} instead.')
    try:
        payload = jwt.decode(token, self.__secret_key, algorithms=['HS256'])
        return payload['sub']
    except jwt.ExpiredSignatureError:
        raise KeyError('Token is expired')
    except jwt.InvalidTokenError:
        raise KeyError('Token is invalid')

Overloads

__str__

Return a string representation of the class.

Returns
  • (str) A string representation of the JwtAuthentication
View Source
def __str__(self):
    """Return a string representation of the class.

        :return: (str) A string representation of the JwtAuthentication

        """
    if self._available is False:
        return '{:s} unavailable'.format(self.__class__.__name__)
    return "{:s}(secret key: '{:s}', id: '{}')".format(self.__class__.__name__, self.__secret_key, self.method_id)

__repr__

Return the official string representation of the class.

Returns
  • (str) The official string representation of the JwtAuthentication
View Source
def __repr__(self):
    """Return the official string representation of the class.

        :return: (str) The official string representation of the JwtAuthentication

        """
    if self._available is False:
        return '{:s} unavailable'.format(self.__class__.__name__)
    return '{:s}({:s})'.format(self.__class__.__name__, ', '.join(["name: '{}'".format(self.name()), "id: '{}'".format(self.method_id), "secret key: '{}'".format(self.__secret_key)]))