Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check authentication before authenticating #95

Merged
merged 1 commit into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion src/python_opensky/opensky.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,35 @@ class OpenSky:
_auth: BasicAuth | None = None
_contributing_user: bool = False

def authenticate(self, auth: BasicAuth, *, contributing_user: bool = False) -> None:
async def authenticate(
self,
auth: BasicAuth,
*,
contributing_user: bool = False,
) -> None:
"""Authenticate the user."""
self._auth = auth
try:
await self.get_states()
except OpenSkyUnauthenticatedError as exc:
self._auth = None
raise OpenSkyUnauthenticatedError from exc
self._contributing_user = contributing_user
if contributing_user:
self.opensky_credits = 8000
else:
self.opensky_credits = 4000

@property
def is_contributing_user(self) -> bool:
"""Return if the user is contributing to OpenSky."""
return self._contributing_user

@property
def is_authenticated(self) -> bool:
"""Return if the user is correctly authenticated."""
return self._auth is not None

async def _request(
self,
uri: str,
Expand Down Expand Up @@ -107,6 +127,8 @@ async def _request(
ClientResponseError,
socket.gaierror,
) as exception:
if isinstance(exception, ClientResponseError) and exception.status == 401:
raise OpenSkyUnauthenticatedError from exception
msg = "Error occurred while communicating with OpenSky API"
raise OpenSkyConnectionError(msg) from exception

Expand Down
78 changes: 71 additions & 7 deletions tests/test_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ async def test_own_states(
aresponses: ResponsesMockServer,
) -> None:
"""Test retrieving own states."""
aresponses.add(
OPENSKY_URL,
"/api/states/all",
"GET",
aresponses.Response(
status=200,
headers={"Content-Type": "application/json"},
text=load_fixture("states.json"),
),
)
aresponses.add(
OPENSKY_URL,
"/api/states/own",
Expand All @@ -103,17 +113,31 @@ async def test_own_states(
)
async with aiohttp.ClientSession() as session:
opensky = OpenSky(session=session)
opensky.authenticate(BasicAuth(login="test", password="test"))
await opensky.authenticate(
BasicAuth(login="test", password="test"),
contributing_user=True,
)
response: StatesResponse = await opensky.get_own_states()
assert len(response.states) == 4
assert opensky.remaining_credits() == opensky.opensky_credits
assert opensky.opensky_credits == 8000
assert opensky.remaining_credits() == 7996
await opensky.close()


async def test_unavailable_own_states(
aresponses: ResponsesMockServer,
) -> None:
"""Test retrieving no own states."""
aresponses.add(
OPENSKY_URL,
"/api/states/all",
"GET",
aresponses.Response(
status=200,
headers={"Content-Type": "application/json"},
text=load_fixture("states.json"),
),
)
aresponses.add(
OPENSKY_URL,
"/api/states/own",
Expand All @@ -126,7 +150,10 @@ async def test_unavailable_own_states(
)
async with aiohttp.ClientSession() as session:
opensky = OpenSky(session=session)
opensky.authenticate(BasicAuth(login="test", password="test"))
await opensky.authenticate(
BasicAuth(login="test", password="test"),
contributing_user=True,
)
response: StatesResponse = await opensky.get_own_states()
assert response.states is not None
assert len(response.states) == 0
Expand Down Expand Up @@ -244,27 +271,64 @@ def response_handler(request: BaseRequest) -> Response:
"/api/states/all",
"GET",
response_handler,
repeat=2,
)

async with aiohttp.ClientSession() as session:
opensky = OpenSky(session=session)
opensky.authenticate(BasicAuth(login="test", password="test"))
await opensky.authenticate(BasicAuth(login="test", password="test"))
await opensky.get_states()
await opensky.close()


async def test_user_credits() -> None:
async def test_unauthorized(aresponses: ResponsesMockServer) -> None:
"""Test request authentication."""
aresponses.add(
OPENSKY_URL,
"/api/states/all",
"GET",
aresponses.Response(
status=401,
headers={"Content-Type": "application/json"},
text=load_fixture("states.json"),
),
)

async with aiohttp.ClientSession() as session:
opensky = OpenSky(session=session)
try:
await opensky.authenticate(BasicAuth(login="test", password="test"))
pytest.fail("Should've thrown exception")
except OpenSkyUnauthenticatedError:
pass
assert opensky.is_authenticated is False
await opensky.close()


async def test_user_credits(aresponses: ResponsesMockServer) -> None:
"""Test authenticated user credits."""
aresponses.add(
OPENSKY_URL,
"/api/states/all",
"GET",
aresponses.Response(
status=200,
headers={"Content-Type": "application/json"},
text=load_fixture("states.json"),
),
repeat=2,
)
async with aiohttp.ClientSession() as session:
opensky = OpenSky(session=session)
assert opensky.opensky_credits == 400
opensky.authenticate(BasicAuth(login="test", password="test"))
await opensky.authenticate(BasicAuth(login="test", password="test"))
assert opensky.opensky_credits == 4000
opensky.authenticate(
await opensky.authenticate(
BasicAuth(login="test", password="test"),
contributing_user=True,
)
assert opensky.opensky_credits == 8000
assert opensky.is_contributing_user is True
await opensky.close()


Expand Down