Exemplo n.º 1
0
    def _get_authorization_token(self, cache_token=True) -> str:
        """ Step 2
        """

        logger.info('Get authorization token')

        code_verifier, code_challenge = self._generate_consts()

        data = {
            'client_id': self.client_id,
            'grant_type': 'authorization_code',
            'code': self._get_authorization_code(code_challenge),
            'redirect_uri': self.redirect_uri,
            'code_verifier': code_verifier
        }

        resp = self._session.post(url=self.AUTH_TOKEN_URL, data=data)
        if resp.status_code != 200:
            result = resp.json()
            logger.error('Getting responce token error')
            raise AuthFlowRequestError(error=result['error'],
                                       error_descr=result['error_description'],
                                       code=resp.status_code)

        self.token_info = resp.json()
        self.token_info['expires_at'] = int(
            time.time()) + self.token_info["expires_in"]

        if cache_token:
            self._cache_token()
Exemplo n.º 2
0
    def _refresh_authorization_token(self, cache_token=True) -> None:
        """ Requesting a refreshed access token; Spotify returns a new access token to your app
        """

        logger.info('Refresh expired token')
        headers = self._make_authorization_headers(self._client_id,
                                                   self._client_secret)

        data = {
            'grant_type': 'refresh_token',
            'refresh_token': self.token_info['refresh_token'],
            'redirect_uri': self.redirect_uri
        }

        resp = self._session.post(url=self.AUTH_TOKEN_URL,
                                  headers=headers,
                                  data=data)
        if resp.status_code != 200:
            result = resp.json()
            logger.error('Getting responce token error')
            raise AuthFlowRequestError(error=result['error'],
                                       error_descr=result['error_description'],
                                       code=resp.status_code)
        logger.debug(resp.text)
        self.token_info = resp.json()
        self.token_info['expires_at'] = int(
            time.time()) + self.token_info["expires_in"]
        if cache_token:
            self._cache_token()
Exemplo n.º 3
0
 def _get_cached_token(self) -> None:
     token_info = None
     try:
         with open(self.cache_token_path, 'r') as f:
             token_info = json.load(f)
             logger.info('Got cached token')
     except (IOError, json.decoder.JSONDecodeError) as e:
         logger.warning(
             f'Can not get token from {self.cache_token_path}: {e}')
     # self.token_info = token_info
     return token_info
Exemplo n.º 4
0
    def _get_authorization_token(self, cache_token=True) -> None:
        """ Step 2. Exchange code with an access token

        POST https://accounts.spotify.com/api/token

        The body must contain the following parameters encoded in application/x-www-form-urlencoded as defined in the OAuth 2.0 specification:

        POST data: grant_type=authorization_code, code, redirect_uri
        Headers: Base 64 encoded string that contains the client ID and client secret key. The field must have the format: "Authorization: Basic *<base64 encoded client_id:client_secret>*"

        Return:
        - access_token
        - token_type=“Bearer”
        - scope -- space-separated list of scopes which have been granted for this access_token
        - expires_in -- The time period (in seconds) for which the access token is valid
        - refresh_token -- a token that can be sent to the Spotify Accounts service in place of an authorization code.
          When the access code expires, send a POST request to the Accounts service /api/token endpoint,
          but use this code in place of an authorization code. A new access token will be returned.
          A new refresh token might be returned too.)
        """

        logger.info('Get authorization token')

        headers = self._make_authorization_headers(self._client_id,
                                                   self._client_secret)

        data = {
            'grant_type': 'authorization_code',
            'code': self._get_authorization_code(),
            'redirect_uri': self.redirect_uri
        }

        resp = self._session.post(url=self.AUTH_TOKEN_URL,
                                  headers=headers,
                                  data=data)
        if resp.status_code != 200:
            result = resp.json()
            logger.error('Getting responce token error')
            raise AuthFlowRequestError(error=result['error'],
                                       error_descr=result['error_description'],
                                       code=resp.status_code)
        self.token_info = resp.json(
        )  # {'access_token': 'BQ...', 'token_type': 'Bearer', 'expires_in': 3600, 'refresh_token': 'AQ...', 'scope': '...'}
        self.token_info['expires_at'] = int(
            time.time()) + self.token_info["expires_in"]

        if cache_token:
            self._cache_token()
Exemplo n.º 5
0
    def get_token(self) -> str:
        logger.info('Authorizing with Authorization Code Flow')
        self.token_info = self._get_cached_token()

        if self.token_info:
            logger.debug(f'Cached token: {str(self.token_info)[:25]}...')
            if Scope(self.token_info['scope']) == self.scope:
                if self._is_token_expired():
                    logger.debug(
                        f'Token expired at {time.ctime(int(self.token_info["expires_at"]))}. Refreshing token...'
                    )
                    try:
                        self._refresh_authorization_token()
                    except AuthFlowRequestError as err:
                        if err.code == 400:
                            logger.debug(err)
                            logger.debug(
                                'Cleaning cache, trying to get another token')
                            self._clean_cache()
                            self._get_authorization_token()
            else:
                logger.info('Scopes are not compatible. Getting new token...')
                self._get_authorization_token()
        else:
            self._get_authorization_token()

        logger.info(
            f'Authorization complite. Token "{self.token_info["access_token"][:7]}..." will be expire at {time.ctime(int(self.token_info["expires_at"]))}'
        )
        return self.token_info['access_token']