def get_authorization_url(self, dynamodb):
        try:
            nonce = NonceUtil.generate(
                dynamodb=dynamodb,
                expiration_minites=settings.YAHOO_NONCE_EXPIRATION_MINUTES,
                provider='yahoo',
                type='nonce',
                length=settings.YAHOO_NONCE_LENGTH)
            state = NonceUtil.generate(
                dynamodb=dynamodb,
                expiration_minites=settings.YAHOO_NONCE_EXPIRATION_MINUTES,
                provider='yahoo',
                type='state',
                length=settings.YAHOO_NONCE_LENGTH)
        except (ClientError) as e:
            raise e
        authorization_endpoint = \
            self.endpoints['authorization_endpoint'] + \
            '?response_type=code' + \
            '&client_id=' + self.client_id + \
            '&scope=' + settings.YAHOO_LOGIN_REQUEST_SCOPE + \
            '&redirect_uri=' + self.callback_url + \
            '&nonce='+nonce+'&state='+state

        return authorization_endpoint
 def test_generate_ng(self):
     with self.assertRaises(ClientError):
         self.dynamodb.Table = MagicMock()
         self.dynamodb.Table.return_value.put_item.side_effect = ClientError(
             {'Error': {
                 'Code': 'xxxx'
             }}, 'operation_name')
         NonceUtil.generate(dynamodb=self.dynamodb,
                            expiration_minites=15,
                            provider='yahoo',
                            type='nonce',
                            length=10)
    def test_generate_ok(self):
        nonce = NonceUtil.generate(dynamodb=self.dynamodb,
                                   expiration_minites=15,
                                   provider='yahoo',
                                   type='nonce',
                                   length=10)

        table = self.dynamodb.Table(os.environ['NONCE_TABLE_NAME'])
        result = table.get_item(Key={'nonce': nonce}).get('Item')
        self.assertEqual(len(result), 4)
    def verify_state_nonce(self, dynamodb, state):
        nonce_checked = NonceUtil.verify(dynamodb=dynamodb,
                                         nonce=state,
                                         provider='yahoo',
                                         type='state')

        if nonce_checked is False:
            raise YahooVerifyException(state +
                                       ' was invalid since it may be expired')
        return True
    def verify_access_token(self, dynamodb, access_token, id_token):
        # 以下のコメントはhttps://developer.yahoo.co.jp/yconnect/v2/id_token.htmlの検証手順番号
        try:
            start_time = time.time()
            header = jwt.get_unverified_header(id_token)
            response = requests.get(settings.YAHOO_API_PUBLIC_KEY_URL)
            if response.status_code is not 200:
                raise YahooOauthError(
                    endpoint=settings.YAHOO_API_PUBLIC_KEY_URL,
                    status_code=response.status_code,
                    message=response.text)
            public_keys = json.loads(response.text)

            # 6,7,8の検証
            decoded_data = jwt.decode(id_token,
                                      key=public_keys.get(
                                          header['kid']).encode('utf-8'),
                                      issuer=self.endpoints['issuer'],
                                      audience=self.client_id,
                                      algorithms='RS256')

            nonce_checked = NonceUtil.verify(dynamodb=dynamodb,
                                             nonce=decoded_data['nonce'],
                                             provider='yahoo',
                                             type='nonce')

            # 9の検証
            if nonce_checked is False:
                raise YahooVerifyException(
                    'id token was invalid since nonce was invalid')

            # 10の検証
            token_hash = hashlib.sha256(access_token.encode('utf-8')).digest()
            at_hash = base64.urlsafe_b64encode(
                token_hash[:int(len(token_hash) / 2)])
            if decoded_data['at_hash'] != at_hash.decode().rstrip('='):
                print(at_hash.decode().rstrip('='))
                raise YahooVerifyException(
                    'accesstoken was invalid since at_hash did not match')

            # 12の検証
            if start_time >= decoded_data['exp']:
                raise YahooVerifyException(
                    'id token was invalid since start_time was less than exp')
        except (jwt.ExpiredSignatureError, jwt.InvalidTokenError, ClientError,
                YahooVerifyException) as e:
            raise e

        return True
    def test_verify_ng_with_do_not_match_type(self):
        table = self.dynamodb.Table(os.environ['NONCE_TABLE_NAME'])
        param = {
            'nonce': 'xxxx',
            'provider': 'test',
            'type': 'test',
            'expiration_time': 1232432234322
        }
        table.put_item(Item=param,
                       ConditionExpression='attribute_not_exists(nonce)')

        result = NonceUtil.verify(dynamodb=self.dynamodb,
                                  nonce='xxxx',
                                  provider='test',
                                  type='test1')

        self.assertFalse(result)
Пример #7
0
    def get_authorization_url(self, dynamodb):
        try:
            state = NonceUtil.generate(
                dynamodb=dynamodb,
                expiration_minites=settings.FACEBOOK_NONCE_EXPIRATION_MINUTES,
                provider='facebook',
                type='state',
                length=settings.FACEBOOK_NONCE_LENGTH)
        except (ClientError) as e:
            raise e

        authorization_endpoint = \
            settings.FACEBOOK_API_AUTHENTICATE_URL + \
            '?client_id=' + self.app_id + \
            '&redirect_uri=' + self.callback_url + \
            '&scope=' + settings.FACEBOOK_LOGIN_REQUEST_SCOPE + \
            '&state='+state

        return authorization_endpoint