Skip to content

Commit

Permalink
version 0.30
Browse files Browse the repository at this point in the history
  • Loading branch information
FriendsOfGalaxy committed May 18, 2020
1 parent cf94685 commit c06b31f
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 3 deletions.
2 changes: 1 addition & 1 deletion requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ pytest-pythonpath==0.7.3
pytest-asyncio==0.10.0
pytest-mock==1.10.3
cryptography==2.5
pip-tools==4.5.0
pip-tools==5.1.2
13 changes: 12 additions & 1 deletion src/http_client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import aiohttp
import logging
import asyncio

from urllib.parse import parse_qsl, urlsplit

Expand Down Expand Up @@ -94,6 +95,7 @@ def __init__(self, auth_lost_callback, store_credentials_callback):
self._refresh_token = None
self._auth_lost_callback = auth_lost_callback
self._store_credentials_callback = store_credentials_callback
self.can_refresh = asyncio.Event()
super().__init__()

@property
Expand Down Expand Up @@ -145,11 +147,18 @@ async def get_access_token(self, refresh_token=None, url=OAUTH_TOKEN_URL, cookie

async def authenticate(self, refresh_token):
self._refresh_token = refresh_token
self._access_token = await self.get_access_token(self._refresh_token)
try:
self._access_token = await self.get_access_token(self._refresh_token)
finally:
self.can_refresh.set()
if not self._access_token:
raise UnknownBackendResponse("Empty access token")

async def _refresh_access_token(self):
if not self.can_refresh.is_set():
await self.can_refresh.wait()
return
self.can_refresh.clear()
try:
self._access_token = await self.get_access_token(self._refresh_token)
if not self._access_token:
Expand All @@ -162,6 +171,8 @@ async def _refresh_access_token(self):
if self._auth_lost_callback:
self._auth_lost_callback()
raise AuthenticationRequired()
finally:
self.can_refresh.set()

async def request(self, method, *args, **kwargs):
if not self._access_token:
Expand Down
5 changes: 4 additions & 1 deletion src/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
__version__ = "0.29"
__version__ = "0.30"

__changelog__ = {
"0.30":"""
- Only allow one token refresh at a time
""",
"0.29": """
- Fix broken authentication due to change on psn side
""",
Expand Down
8 changes: 8 additions & 0 deletions tests/async_mock.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
from unittest.mock import MagicMock
import asyncio


class AsyncMock(MagicMock):
async def __call__(self, *args, **kwargs):
# pylint: disable=useless-super-delegation
return super(AsyncMock, self).__call__(*args, **kwargs)


class AsyncMockDelayed(MagicMock):
async def __call__(self, *args, **kwargs):
await asyncio.sleep(0.1)
# pylint: disable=useless-super-delegation
return super(AsyncMockDelayed, self).__call__(*args, **kwargs)
1 change: 1 addition & 0 deletions tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,4 @@ async def test_failed_to_refresh_access_token(
await authenticated_psn_client.async_get_own_user_info()

get_access_token.assert_called_once_with(npsso)

27 changes: 27 additions & 0 deletions tests/test_http_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import asyncio
import pytest
from unittest.mock import Mock
from galaxy.api.errors import AuthenticationRequired
from http_client import AuthenticatedHttpClient
from tests.async_mock import AsyncMockDelayed, AsyncMock


@pytest.mark.asyncio
async def test_multiple_refreshing():
EXPIRED_TOKEN = "old access token"
REFRESHED_TOKEN = "refreshed access token"
def raise_on_old_token(*args, **kwargs):
if http_client._access_token == EXPIRED_TOKEN:
raise AuthenticationRequired()
return 'ok'
http_client = AuthenticatedHttpClient(Mock, Mock)
http_client.can_refresh.set()
http_client._access_token = EXPIRED_TOKEN
http_client.get_access_token = AsyncMockDelayed(return_value=REFRESHED_TOKEN)
http_client._oauth_request = AsyncMock(side_effect=raise_on_old_token)
responses = await asyncio.gather(
http_client.request('url'),
http_client.request('url'),
)
for i in responses:
assert i == 'ok'

0 comments on commit c06b31f

Please sign in to comment.