Skip to content

Commit

Permalink
Fixes (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
grigoriev-semyon authored May 9, 2023
1 parent 92134fc commit 15e7fd5
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 62 deletions.
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
configure: venv
source ./venv/bin/activate && pip install -r requirements.dev.txt

venv:
python3.11 -m venv venv

format:
autoflake -r --in-place --remove-all-unused-imports ./auth_lib
isort ./auth_lib
black ./auth_lib


42 changes: 18 additions & 24 deletions auth_lib/aiomethods.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import Any
from urllib.parse import urljoin

import aiohttp

from .exceptions import AuthFailed, IncorrectData, NotFound, SessionExpired
from .exceptions import AuthFailed, SessionExpired

# See docs on https://api.test.profcomff.com/?urls.primaryName=auth

Expand All @@ -23,30 +24,23 @@ async def email_login(self, email: str, password: str) -> dict[str, Any]:
case 401:
raise AuthFailed(response=await response.json())

async def check_token(self, token: str) -> dict[str, Any]:
async def check_token(self, token: str) -> dict[str, Any] | None:
headers = {"Authorization": token}
async with aiohttp.ClientSession() as session:
response = await session.get(
url=f"{self.url}/me",
headers=headers,
params={
"info": [
"groups",
"indirect_groups",
"session_scopes",
"user_scopes",
]
},
)
match response.status:
case 200:
return await response.json()
case 400:
raise IncorrectData(response=await response.json())
case 404:
raise NotFound(response=await response.json())
case 403:
raise SessionExpired(response=await response.json())
async with aiohttp.request(
"GET",
urljoin(self.url, "me"),
headers={"Authorization": token},
params={
"info": [
"indirect_groups",
"session_scopes",
]
},
) as r:
user_session = await r.json()
if r.ok:
return user_session
return None

async def logout(self, token: str) -> bool:
headers = {"Authorization": token}
Expand Down
36 changes: 16 additions & 20 deletions auth_lib/fastapi.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from urllib.parse import urljoin
from typing import Any
from warnings import warn

import aiohttp
from fastapi.exceptions import HTTPException
from fastapi.openapi.models import APIKey, APIKeyIn
from fastapi.security.base import SecurityBase
from pydantic import BaseSettings
from starlette.requests import Request
from starlette.status import HTTP_403_FORBIDDEN
from starlette.websockets import WebSocket

from auth_lib.aiomethods import AsyncAuthLib


class UnionAuthSettings(BaseSettings):
Expand Down Expand Up @@ -57,29 +59,23 @@ def _except(self):
status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
)
else:
return {}
return None

async def __call__(
self,
request: Request,
) -> dict[str, str] | None:
token = request.headers.get("Authorization")
async def _get_session(self, token: str | None) -> dict[str, Any] | None:
if not token and self.allow_none:
return None
if not token:
return self._except()
async with aiohttp.request(
"GET",
urljoin(self.auth_url, "me"),
headers={"Authorization": token},
params={
"info": ["groups", "indirect_groups", "session_scopes", "user_scopes"]
},
) as r:
status_code = r.status
user_session = await r.json()
if status_code != 200:
self._except()
return await AsyncAuthLib(url=self.auth_url).check_token(token)

async def __call__(
self,
request: Request | WebSocket,
) -> dict[str, Any] | None:
token = request.headers.get("Authorization")
user_session = await self._get_session(token)
if user_session is None:
return self._except()
session_scopes = set(
[scope["name"].lower() for scope in user_session["session_scopes"]]
)
Expand Down
24 changes: 11 additions & 13 deletions auth_lib/methods.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import Any
from urllib.parse import urljoin

import requests

from .exceptions import AuthFailed, IncorrectData, NotFound, SessionExpired
from .exceptions import AuthFailed, SessionExpired

# See docs on https://api.test.profcomff.com/?urls.primaryName=auth

Expand All @@ -22,24 +23,21 @@ def email_login(self, email: str, password: str) -> dict[str, Any]:
case 401:
raise AuthFailed(response=response.json()["body"])

def check_token(self, token: str) -> dict[str, Any]:
def check_token(self, token: str) -> dict[str, Any] | None:
headers = {"Authorization": token}
response = requests.get(
url=f"{self.url}/me",
url=urljoin(self.url, "me"),
headers=headers,
params={
"info": ["groups", "indirect_groups", "session_scopes", "user_scopes"]
"info": [
"indirect_groups",
"session_scopes",
]
},
)
match response.status_code:
case 200:
return response.json()
case 400:
raise IncorrectData(response=response.json()["body"])
case 404:
raise NotFound(response=response.json()["body"])
case 403:
raise SessionExpired(response=response.json()["body"])
if response.ok:
return response.json()
return None

def logout(self, token: str) -> bool:
headers = {"Authorization": token}
Expand Down
5 changes: 4 additions & 1 deletion auth_lib/testing/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
try:
from auth_lib.testing.testutils import auth_mock, pytest_configure
except ImportError:
except ImportError as e:
print("You have to install testing requirements")
print("pip install 'auth-lib-profcomff[testing]'")
raise e

__all__ = ["auth_mock", "pytest_configure"]
6 changes: 3 additions & 3 deletions auth_lib/testing/testutils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from unittest.mock import MagicMock, patch
from unittest.mock import AsyncMock, patch

import pytest

Expand All @@ -25,8 +25,8 @@ def auth_mock(request):
"user_scopes": session_scopes,
}
patcher = patch(
"auth_lib.fastapi.UnionAuth.__call__",
new=MagicMock(return_value=_return_val),
"auth_lib.fastapi.UnionAuth._get_session",
new=AsyncMock(return_value=_return_val),
)
patcher.start()
yield
Expand Down
1 change: 1 addition & 0 deletions requirements.dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ fastapi
starlette
requests
aiohttp
autoflake
setuptools
pydantic
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name="auth_lib_profcomff",
version="2023.04.23",
version="2023.05.10",
author="Semyon Grigoriev",
long_description=readme,
long_description_content_type="text/markdown",
Expand Down

0 comments on commit 15e7fd5

Please sign in to comment.