from abc import ABCMeta, abstractmethod
from frontegg.helpers.frontegg_urls import frontegg_urls
import typing
import jwt
import requests
from frontegg.helpers.logger import logger
from jwt import InvalidTokenError


class IdentityClientMixin(metaclass=ABCMeta):
    __publicKey = None

    @property
    @abstractmethod
    def vendor_session_request(self) -> requests.Session:
        pass

    @property
    @abstractmethod
    def should_refresh_vendor_token(self) -> bool:
        pass

    @abstractmethod
    def refresh_vendor_token(self) -> None:
        pass

    def get_public_key(self) -> str:
        if self.__publicKey:
            return self.__publicKey

        logger.info('could not find public key locally, will fetch public key')
        reties = 0
        while reties < 10:
            try:
                self.__publicKey = self.fetch_public_key()
                return self.__publicKey
            except Exception as e:
                reties = reties + 1
                logger.error(
                    'could not get public key from frontegg, retry number - ' + str(reties) + ', ' + str(e))

        logger.error('failed to get public key in all retries')

    def fetch_public_key(self) -> str:

        if self.should_refresh_vendor_token:
            self.refresh_vendor_token()

        response = self.vendor_session_request.get(
            frontegg_urls.identity_service['vendor_config'])
        response.raise_for_status()
        data = response.json()
        return data.get('publicKey')

    def decode_jwt(self, authorization_header, verify: typing.Optional[bool] = True):
        if not authorization_header:
            raise InvalidTokenError('Authorization headers is missing')
        logger.debug('found authorization header: ' +
                     str(authorization_header))
        jwt_token = authorization_header.replace('Bearer ', '')
        if verify:
            public_key = self.get_public_key()
            logger.debug('got public key' + str(public_key))
            decoded = jwt.decode(jwt_token, public_key, algorithms='RS256')
        else:
            decoded = jwt.decode(jwt_token, algorithms='RS256', verify=False)

        logger.info('jwt was decoded successfully')
        logger.debug('JWT value - ' + str(decoded))
        return decoded

[((681, 752), 'frontegg.helpers.logger.logger.info', 'logger.info', (['"""could not find public key locally, will fetch public key"""'], {}), "('could not find public key locally, will fetch public key')\n", (692, 752), False, 'from frontegg.helpers.logger import logger\n'), ((1134, 1189), 'frontegg.helpers.logger.logger.error', 'logger.error', (['"""failed to get public key in all retries"""'], {}), "('failed to get public key in all retries')\n", (1146, 1189), False, 'from frontegg.helpers.logger import logger\n'), ((2200, 2243), 'frontegg.helpers.logger.logger.info', 'logger.info', (['"""jwt was decoded successfully"""'], {}), "('jwt was decoded successfully')\n", (2211, 2243), False, 'from frontegg.helpers.logger import logger\n'), ((1676, 1729), 'jwt.InvalidTokenError', 'InvalidTokenError', (['"""Authorization headers is missing"""'], {}), "('Authorization headers is missing')\n", (1693, 1729), False, 'from jwt import InvalidTokenError\n'), ((2045, 2098), 'jwt.decode', 'jwt.decode', (['jwt_token', 'public_key'], {'algorithms': '"""RS256"""'}), "(jwt_token, public_key, algorithms='RS256')\n", (2055, 2098), False, 'import jwt\n'), ((2135, 2190), 'jwt.decode', 'jwt.decode', (['jwt_token'], {'algorithms': '"""RS256"""', 'verify': '(False)'}), "(jwt_token, algorithms='RS256', verify=False)\n", (2145, 2190), False, 'import jwt\n')]