2019-04-03 15:44:52 +04:00
|
|
|
from typing import Optional
|
|
|
|
|
|
2018-12-07 19:12:16 +04:00
|
|
|
from fastapi.openapi.models import APIKey, APIKeyIn
|
|
|
|
|
from fastapi.security.base import SecurityBase
|
2018-12-28 20:35:48 +04:00
|
|
|
from starlette.exceptions import HTTPException
|
2018-12-18 22:36:04 +04:00
|
|
|
from starlette.requests import Request
|
2018-12-28 20:35:48 +04:00
|
|
|
from starlette.status import HTTP_403_FORBIDDEN
|
2018-12-07 19:12:16 +04:00
|
|
|
|
2018-12-05 10:56:50 +04:00
|
|
|
|
|
|
|
|
class APIKeyBase(SecurityBase):
|
2018-12-06 23:47:58 +04:00
|
|
|
pass
|
2018-12-05 10:56:50 +04:00
|
|
|
|
2018-12-06 23:47:58 +04:00
|
|
|
|
2018-12-07 19:12:16 +04:00
|
|
|
class APIKeyQuery(APIKeyBase):
|
2019-04-03 15:44:52 +04:00
|
|
|
def __init__(self, *, name: str, scheme_name: str = None, auto_error: bool = True):
|
|
|
|
|
self.model: APIKey = APIKey(**{"in": APIKeyIn.query}, name=name)
|
2018-12-06 23:47:58 +04:00
|
|
|
self.scheme_name = scheme_name or self.__class__.__name__
|
2019-04-03 15:44:52 +04:00
|
|
|
self.auto_error = auto_error
|
2018-12-06 20:24:50 +04:00
|
|
|
|
2019-04-03 15:44:52 +04:00
|
|
|
async def __call__(self, request: Request) -> Optional[str]:
|
2018-12-28 20:35:48 +04:00
|
|
|
api_key: str = request.query_params.get(self.model.name)
|
|
|
|
|
if not api_key:
|
2019-04-03 15:44:52 +04:00
|
|
|
if self.auto_error:
|
|
|
|
|
raise HTTPException(
|
|
|
|
|
status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
return None
|
2018-12-28 20:35:48 +04:00
|
|
|
return api_key
|
2018-12-05 10:56:50 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class APIKeyHeader(APIKeyBase):
|
2019-04-03 15:44:52 +04:00
|
|
|
def __init__(self, *, name: str, scheme_name: str = None, auto_error: bool = True):
|
|
|
|
|
self.model: APIKey = APIKey(**{"in": APIKeyIn.header}, name=name)
|
2018-12-06 23:47:58 +04:00
|
|
|
self.scheme_name = scheme_name or self.__class__.__name__
|
2019-04-03 15:44:52 +04:00
|
|
|
self.auto_error = auto_error
|
2018-12-05 10:56:50 +04:00
|
|
|
|
2019-04-03 15:44:52 +04:00
|
|
|
async def __call__(self, request: Request) -> Optional[str]:
|
2018-12-28 20:35:48 +04:00
|
|
|
api_key: str = request.headers.get(self.model.name)
|
|
|
|
|
if not api_key:
|
2019-04-03 15:44:52 +04:00
|
|
|
if self.auto_error:
|
|
|
|
|
raise HTTPException(
|
|
|
|
|
status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
return None
|
2018-12-28 20:35:48 +04:00
|
|
|
return api_key
|
2018-12-05 10:56:50 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class APIKeyCookie(APIKeyBase):
|
2019-04-03 15:44:52 +04:00
|
|
|
def __init__(self, *, name: str, scheme_name: str = None, auto_error: bool = True):
|
|
|
|
|
self.model: APIKey = APIKey(**{"in": APIKeyIn.cookie}, name=name)
|
2018-12-06 23:47:58 +04:00
|
|
|
self.scheme_name = scheme_name or self.__class__.__name__
|
2019-04-03 15:44:52 +04:00
|
|
|
self.auto_error = auto_error
|
2018-12-05 10:56:50 +04:00
|
|
|
|
2019-04-03 15:44:52 +04:00
|
|
|
async def __call__(self, request: Request) -> Optional[str]:
|
2019-06-27 20:51:17 +02:00
|
|
|
api_key = request.cookies.get(self.model.name)
|
2018-12-28 20:35:48 +04:00
|
|
|
if not api_key:
|
2019-04-03 15:44:52 +04:00
|
|
|
if self.auto_error:
|
|
|
|
|
raise HTTPException(
|
|
|
|
|
status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
|
|
|
|
|
)
|
|
|
|
|
else:
|
|
|
|
|
return None
|
2018-12-28 20:35:48 +04:00
|
|
|
return api_key
|