Ejemplo n.º 1
0
    def _debug_token(self, access_token, id_token=None) -> OAuth2TokenPack:
        """
        Debug adnd get access token that was sent by Mobile SDK
        :param access_token:
        :return:
        """
        res = requests.get(
            self.__verify_token_uri(version=self.channel.api_version),
            params={'access_token': access_token})
        if res.status_code != 200:
            body = res.json()
            error, desc = self._get_error(body, action='get_token')
            logger.warn('Verify access token failed',
                        style='hybrid',
                        provider=self.provider.upper(),
                        **body)
            self._raise_error(error=self.ERROR_GET_TOKEN_FAILED,
                              msg='{}: {}'.format(error, desc))
        token_info = res.json()
        client_id = token_info['client_id']
        if client_id != self.channel.client_id:
            logger.warn('Access token does not belong to current app',
                        client_id=client_id,
                        expected=self.channel.client_id)
            raise PermissionDeniedError('Illegal access token')

        return OAuth2TokenPack(access_token=access_token,
                               expires_in=token_info['expires_in'],
                               token_type='Bearer',
                               id_token=id_token)
Ejemplo n.º 2
0
    def _get_profile_oa1(
            self, token_tup: Tuple[str, str]) -> Tuple[str, Dict[str, Any]]:
        profile_uri = self.__profile_uri__(version=self.channel.api_version,
                                           numeric_format=True)
        auth = self.create_authorization_header(
            method='GET',
            url=profile_uri,
            consumer_key=self.channel.client_id,
            consumer_secret=self.channel.client_secret,
            oauth_token_secret=token_tup[1],
            oauth_token=token_tup[0],
            include_entities='false',
            skip_status='true',
            include_email='true')
        res = requests.get(profile_uri,
                           headers={'Authorization': auth},
                           params={
                               'include_entities': 'false',
                               'skip_status': 'true',
                               'include_email': 'true'
                           })
        if res.status_code != 200:
            body = res.json()
            logger.warn('Getting profile failed', code=res.status_code, **body)
            self._raise_error(error=self.ERROR_GET_PROFILE_FAILED,
                              msg='Getting profile failed')

        return self._parse_attributes(response=res.json())
Ejemplo n.º 3
0
 def _get_token(self, code) -> OAuth2TokenPack:
     """
     Get OAuth2 access token by authorization code
     :param code:
     :return:
     """
     res = requests.post(
         self.__token_uri__(version=self.channel.api_version),
         data={
             'grant_type': 'authorization_code',
             'code': code,
             'redirect_uri': self.__provider_callback_uri__(),
             'client_id': self.channel.client_id,
             'client_secret': self.channel.client_secret
         })
     if res.status_code != 200:
         body = res.json()
         error, desc = self._get_error(body, action='get_token')
         logger.warn('Getting access token failed',
                     style='hybrid',
                     provider=self.provider.upper(),
                     **body)
         self._raise_error(error=self.ERROR_GET_TOKEN_FAILED,
                           msg='{}: {}'.format(error, desc))
     return OAuth2TokenPack(data=res.json())
Ejemplo n.º 4
0
    def _parse_oauth_state(self,
                           state: str) -> Tuple[AuthLogs, OAuthSessionParams]:
        try:
            log_id, args = jwt_token_helper.decode(token=state)
            log: Optional[AuthLogs] = AuthLogs.query.filter_by(
                _id=log_id).one_or_none()

            if not log or log.nonce != args.get('_nonce'):
                logger.debug('Invalid OAuth state or nonce does not match')
                raise BadRequestError('Invalid OAuth state')

            if log.status != AuthLogs.STATUS_UNKNOWN:
                logger.debug(
                    'Validate OAuth state failed. Illegal auth log status.',
                    status=log.status,
                    expected=AuthLogs.STATUS_UNKNOWN)
                raise BadRequestError('Invalid OAuth state')

            if log.provider != self.provider:
                logger.warn(
                    'Provider in OAuth state does not match with current provider',
                    provider=log.provider,
                    expected=self.provider)
                raise PermissionDeniedError(
                    'OAuth state invalid, provider does not match')

            return log, OAuthSessionParams(data=args)
        except TokenParseError as e:
            logger.warning('Parse OAuth state failed',
                           error=e.message,
                           token=state)
            raise BadRequestError('Invalid OAuth state')
Ejemplo n.º 5
0
def _verify_auth_request(auth_token, params):
    log, args = parse_auth_token(auth_token=auth_token)
    api_key = params.get('api_key')
    if api_key:
        expected = (db.session.query(Apps.api_key).filter_by(
            _id=log.app_id, _deleted=0).scalar())
        if expected != api_key:
            raise UnauthorizedError('API key authorization failed')
    else:
        code_challenge = args.get('code_challenge')
        verifier = params.get('code_verifier', '')
        if not _verify_code_verifier(verifier=verifier,
                                     challenge=code_challenge):
            logger.warn('code_verifier does not match', verifier=verifier)
            raise UnauthorizedError('code_verifier does not match')

    return log, args
Ejemplo n.º 6
0
 def _get_token(self, code: str):
     res = requests.get(
         self.__token_uri__(version=self.channel.api_version),
         params={
             'code': code,
             'redirect_uri': self.__provider_callback_uri__(),
             'client_id': self.channel.client_id,
             'client_secret': self.channel.client_secret
         })
     if res.status_code != 200:
         body = res.json()
         error, desc = self._get_error(body, action='get_token')
         logger.warn('Getting access token failed',
                     provider=self.provider.upper(),
                     **body)
         self._raise_error(error=self.ERROR_GET_TOKEN_FAILED,
                           msg='{}: {}'.format(error, desc))
     return res.json()
Ejemplo n.º 7
0
    def _get_profile(
            self, token_pack: OAuth2TokenPack) -> Tuple[str, Dict[str, Any]]:
        fields = self.channel.get_required_fields()
        res = requests.get(
            self.__profile_uri__(version=self.channel.api_version),
            params={
                'fields': ','.join(fields),
                'access_token': token_pack.access_token
            })
        if res.status_code != 200:
            body = res.json()
            logger.warn('Getting profile failed',
                        style='hybrid',
                        provider=self.provider.upper(),
                        **body)
            self._raise_error(
                error=self.ERROR_GET_PROFILE_FAILED,
                msg='Getting user attributes from provider failed')

        return self._parse_attributes(response=res.json(), nofilter=True)
Ejemplo n.º 8
0
    def _get_token_oa1(self, oauth_verifier: str) -> Tuple[str, str]:
        token_uri = self.__token_uri__(version=self.channel.api_version)
        auth = self.create_authorization_header(
            method='POST',
            url=token_uri,
            consumer_key=self.channel.client_id,
            consumer_secret=self.channel.client_secret,
            oauth_token_secret=self.log.oa1_secret,
            oauth_token=self.log.oa1_token)
        res = requests.post(token_uri,
                            headers={'Authorization': auth},
                            data={'oauth_verifier': oauth_verifier})
        if res.status_code != 200:
            body = up.parse_qs(res.text)
            logger.warn('Getting access token failed',
                        code=res.status_code,
                        **body)
            self._raise_error(error=self.ERROR_GET_TOKEN_FAILED,
                              msg='Getting access token failed')

        body = up.parse_qs(res.text)
        return body['oauth_token'][0], body['oauth_token_secret'][0]
Ejemplo n.º 9
0
    def _get_profile(
            self, token_pack: OAuth2TokenPack) -> Tuple[str, Dict[str, Any]]:
        """
        Get profile attributes of authenticated profile
        :param token_pack:
        :return:
        """
        authorization = token_pack.token_type + ' ' + token_pack.access_token
        res = requests.get(
            self.__profile_uri__(version=self.channel.api_version),
            headers={'Authorization': authorization})
        if res.status_code != 200:
            body = res.json()
            logger.warn('Getting profile failed',
                        style='hybrid',
                        provider=self.provider.upper(),
                        **body)
            self._raise_error(
                error=self.ERROR_GET_PROFILE_FAILED,
                msg='Getting user attributes from provider failed')

        return self._parse_attributes(response=res.json())
Ejemplo n.º 10
0
    def _build_authorize_uri(self, state):
        callback_uri = add_params_to_uri(self.__provider_callback_uri__(),
                                         state=state)
        auth = self.create_authorization_header(
            method='POST',
            url=self.REQUEST_TOKEN_URI,
            consumer_key=self.channel.client_id,
            consumer_secret=self.channel.client_secret,
            oauth_callback=callback_uri)

        res = requests.post(self.REQUEST_TOKEN_URI,
                            headers={'Authorization': auth})
        if res.status_code != 200:
            body = up.parse_qs(res.text)
            logger.warn('Getting request token failed',
                        code=res.status_code,
                        **body)
            self._raise_error(error=self.ERROR_GET_TOKEN_FAILED,
                              msg='Getting request token failed')

        body = up.parse_qs(res.text)
        if not body['oauth_callback_confirmed'][0]:
            logger.warn('Getting request token failed',
                        oauth_callback_confirmed=0)
            self._raise_error(
                error=self.ERROR_GET_TOKEN_FAILED,
                msg=
                'Getting request token failed: oauth_callback_confirmed=false')

        token = body['oauth_token'][0]
        secret = body['oauth_token_secret'][0]
        self.log.oa1_token = token
        self.log.oa1_secret = secret

        uri = add_params_to_uri(
            uri=self.__authorize_uri__(version=self.channel.api_version),
            oauth_token=token)
        return uri
Ejemplo n.º 11
0
    def _get_profile(self, token_pack: OAuth2TokenPack):
        perms = self.channel.get_permissions()
        fields = self.channel.get_required_fields()
        if 'email' in perms and 'emailAddresses' not in fields:
            fields.append('emailAddresses')
        fields.remove('#')
        res = requests.get(
            self.__profile_uri__(version=self.channel.api_version),
            params={
                'personFields': ','.join(fields),
                'access_token': token_pack.access_token
            })
        if res.status_code != 200:
            body = res.json()
            logger.warn('Getting profile failed',
                        style='hybrid',
                        provider=self.provider.upper(),
                        **body)
            self._raise_error(
                error=self.ERROR_GET_PROFILE_FAILED,
                msg='Getting user attributes from provider failed')

        return self._parse_attributes(response=res.json(), nofilter=True)