from typing import Optional from fastapi import Security, HTTPException from fastapi.security import APIKeyQuery, APIKeyHeader, HTTPBearer, HTTPAuthorizationCredentials from starlette.status import HTTP_403_FORBIDDEN api_key_query = APIKeyQuery(name='apikey', auto_error=False) api_key_header = APIKeyHeader(name='X-API-Key', auto_error=False) bearer_header = HTTPBearer(auto_error=False) async def get_api_key( api_key_query_param: Optional[str] = Security(api_key_query), api_key_header_param: str = Security(api_key_header), bearer_header_param: Optional[HTTPAuthorizationCredentials] = Security( bearer_header), ): if api_key_query_param is not None: return api_key_query_param elif api_key_header_param is not None: return api_key_header_param elif bearer_header_param and bearer_header_param.scheme.lower( ) == "bearer": return bearer_header_param.credentials else: raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="No credentials given")
from typing import Optional from fastapi import Depends, FastAPI, Security from fastapi.security import APIKeyQuery from pydantic import BaseModel from starlette.testclient import TestClient app = FastAPI() api_key = APIKeyQuery(name="key", auto_error=False) class User(BaseModel): username: str def get_current_user(oauth_header: Optional[str] = Security(api_key)): if oauth_header is None: return None user = User(username=oauth_header) return user @app.get("/users/me") def read_current_user( current_user: Optional[User] = Depends(get_current_user)): if current_user is None: return {"msg": "Create an account first"} return current_user
from fastapi import Security from fastapi.security import APIKeyQuery, APIKeyHeader from starlette.exceptions import HTTPException from starlette.status import HTTP_403_FORBIDDEN from fastapi_simple_security._sqlite_access import sqlite_access API_KEY_NAME = "api_key" api_key_query = APIKeyQuery(name=API_KEY_NAME, scheme_name="API key query", auto_error=False) api_key_header = APIKeyHeader(name=API_KEY_NAME, scheme_name="API key header", auto_error=False) async def api_key_security( query_param: str = Security(api_key_query), header_param: str = Security(api_key_header), ): if not query_param and not header_param: raise HTTPException( status_code=HTTP_403_FORBIDDEN, detail="An API key must be passed as query or header") elif query_param and sqlite_access.check_key(query_param): return query_param elif header_param and sqlite_access.check_key(header_param): return header_param
from fastapi import Depends, FastAPI, Security from fastapi.security import APIKeyQuery from pydantic import BaseModel from starlette.testclient import TestClient app = FastAPI() api_key = APIKeyQuery(name="key") class User(BaseModel): username: str def get_current_user(oauth_header: str = Security(api_key)): user = User(username=oauth_header) return user @app.get("/users/me") def read_current_user(current_user: User = Depends(get_current_user)): return current_user client = TestClient(app) openapi_schema = { "openapi": "3.0.2", "info": { "title": "FastAPI", "version": "0.1.0"
from modules.asyncdb import asyncDB from modules.redis import globalvar, instancestate, instancevar, redis from modules.servertools import stripansi, asyncglobalbuffer from starlette.responses import Response from fastapi.security import APIKeyQuery from starlette.status import HTTP_401_UNAUTHORIZED app = FastAPI(openapi_prefix="/pyarkapi", title="Galaxy Cluster API", description="Ark: Galaxy Cluster Server API", version="2.0.1", redoc_url=None) db = asyncDB() security = APIKeyQuery(name='key') """ async def token_required(f): @wraps(f) def decorated(*args, **kwargs): token = None if 'X-API-KEY' in request.headers: token = request.headers['X-API-KEY'] if not token: apilog.warning(f'API request without a token') return {'message': 'Not Authorized'}, 401 pkeys = dbquery("SELECT * FROM players WHERE apikey = '%s'" % (token,), fmt='dict', fetch='one') if pkeys is None: apilog.warning(f'API request invalid token: {token}') return {'message': 'Invalid Token'}, 401 if pkeys['banned'] == 'True':
from fastapi import Depends, FastAPI, Security from fastapi.security import APIKeyQuery from fastapi.testclient import TestClient from pydantic import BaseModel app = FastAPI() api_key = APIKeyQuery(name="key", description="API Key Query") class User(BaseModel): username: str def get_current_user(oauth_header: str = Security(api_key)): user = User(username=oauth_header) return user @app.get("/users/me") def read_current_user(current_user: User = Depends(get_current_user)): return current_user client = TestClient(app) openapi_schema = { "openapi": "3.0.2", "info": { "title": "FastAPI", "version": "0.1.0"
from fastapi import HTTPException from fastapi import Security from fastapi.routing import APIRouter from fastapi.security import APIKeyQuery, APIKeyHeader from starlette.status import HTTP_403_FORBIDDEN API_KEY = "abcdefghijklmnopqrstuvxz" API_KEY_NAME = "access_token" api_key_query = APIKeyQuery(name=API_KEY_NAME, auto_error=False) api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False) router = APIRouter() async def get_api_key( key_query: str = Security(api_key_query), key_header: str = Security(api_key_header), ) -> str: if key_query == API_KEY: return key_query elif key_header == API_KEY: return key_header else: raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials")
class Server: api_key_name = "access-token" key_query = Security(APIKeyQuery(name=api_key_name, auto_error=False)) key_header = Security(APIKeyHeader(name=api_key_name, auto_error=False)) key_cookie = Security(APIKeyCookie(name=api_key_name, auto_error=False)) def __init__(self, app: BaseApp, telegram: BaseTelegram, routers: list[AppRouter], templates: Templates): self.app = app self.telegram = telegram self.server = FastAPI( title=app.app_config.app_name, docs_url=None, redoc_url=None, openapi_url=None, openapi_tags=app.app_config.tags_metadata, ) self.templates = templates self._configure_server() self._configure_openapi() self._configure_routers(routers) telegram.start() def get_server(self) -> FastAPI: return self.server def _configure_routers(self, routers: list[AppRouter]): base_routers = [ AppRouter(dconfig_router.init(self.app), "dconfig", "/api/dconfigs"), AppRouter(dvalue_router.init(self.app), "dvalue", "/api/dvalues"), AppRouter(dlog_router.init(self.app), "dlog", "/api/dlogs"), AppRouter(system_router.init(self.app, self.telegram), "system", "/api/system"), AppRouter( base_ui_router.init(self.app, self.templates, self.telegram), "base-ui"), ] for r in base_routers + routers: self.server.include_router( r.router, prefix=r.prefix, dependencies=[Depends(self._get_api_key())], tags=[r.tag]) def _configure_server(self): @self.server.exception_handler(Exception) async def exception_handler(_request: Request, err: Exception): code = getattr(err, "code", None) message = str(err) hide_stacktrace = isinstance(err, UserError) if code in [400, 401, 403, 404, 405]: hide_stacktrace = True if not hide_stacktrace: self.app.logger.exception(err) message += "\n\n" + traceback.format_exc() if not self.app.app_config.debug: message = "error" return PlainTextResponse(message, status_code=500) @self.server.on_event("shutdown") def shutdown_server(): self.telegram.stop() self.app.shutdown() current_dir = Path(__file__).parent.absolute() self.server.mount( "/static", StaticFiles(directory=current_dir.joinpath("static")), name="static") def _configure_openapi(self): @self.server.get("/openapi.json", tags=["openapi"], include_in_schema=False) async def get_open_api_endpoint(_api_key: APIKey = Depends( self._get_api_key())): response = JSONResponse( get_openapi( title=self.app.app_config.app_name, version=self.app.app_config.app_version, routes=self.server.routes, tags=self.app.app_config.tags_metadata, ), ) return response @self.server.get("/api", tags=["openapi"], include_in_schema=False) async def get_documentation(api_key: APIKey = Depends( self._get_api_key())): response = get_swagger_ui_html(openapi_url="/openapi.json", title=self.app.app_config.app_name) # noinspection PyTypeChecker response.set_cookie( self.api_key_name, value=api_key, domain=self.app.app_config.domain, httponly=True, max_age=60 * 60 * 24 * 30, expires=60 * 60 * 24 * 30, ) return response @self.server.get("/login", tags=["auth"]) async def route_login_page(): return self.templates.render("login.j2") @self.server.post("/login", tags=["auth"]) async def route_login_action(access_token: str = Form(...)): response = RedirectResponse(url="/", status_code=status.HTTP_303_SEE_OTHER) response.set_cookie( self.api_key_name, value=access_token, domain=self.app.app_config.domain, httponly=True, max_age=60 * 60 * 24 * 30, expires=60 * 60 * 24 * 30, ) return response @self.server.get("/logout", tags=["auth"]) async def route_logout_and_remove_cookie(): response = RedirectResponse(url="/") response.delete_cookie(self.api_key_name, domain=self.app.app_config.domain) return response @self.server.get("/api-link") def api_redirect( request: Request, url: str, method: str, data: Optional[str] = None, api_key: APIKey = Depends(self._get_api_key()), ): method = method.lower() headers = {self.api_key_name: api_key} url = str(request.base_url).removesuffix("/") + url if self.app.app_config.use_https: url = url.replace("http://", "https://", 1) params = None if data: params = json.loads(data) res = hrequest(url, method=method, headers=headers, params=params, json_params=True, timeout=600) if res.json: return res.json return res.body def _get_api_key(self) -> Callable: async def _get_api_key( query: str = Server.key_query, header: str = Server.key_header, cookie: str = Server.key_cookie, ): if query == self.app.app_config.access_token: return query elif header == self.app.app_config.access_token: return header elif cookie == self.app.app_config.access_token: return cookie else: raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="access denied") return _get_api_key
from fastapi import Security, HTTPException from fastapi import status from fastapi.security import APIKeyQuery, APIKeyHeader, APIKeyCookie from settings import settings api_key = settings.api_key api_key_name = settings.api_key_name api_key_query = APIKeyQuery(name=api_key_name, auto_error=False) api_key_header = APIKeyHeader(name=api_key_name, auto_error=False) api_key_cookie = APIKeyCookie(name=api_key_name, auto_error=False) async def check_api_key( api_key_query: str = Security(api_key_query), api_key_header: str = Security(api_key_header), api_key_cookie: str = Security(api_key_cookie), ): if api_key not in (api_key_query, api_key_header, api_key_cookie): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Could not validate credentials", )
from fastapi.openapi.models import APIKey from fastapi.security import APIKeyHeader, APIKeyQuery from core.patreon_api import PatreonApi from core.patreon_response import PatreonModel from core.settings import environment_config from fastapi_cache import FastAPICache, Coder from fastapi_cache.backends.inmemory import InMemoryBackend from fastapi_cache.decorator import cache patreon_pledge_checker = FastAPI() environment_config() x_api_key_valid = os.environ.get('X-API-Key-Valid', None) X_API_KEY_QUERY = APIKeyQuery(name="X-API-Key") X_API_KEY_HEADER = APIKeyHeader(name="X-API-Key") patreonApi = PatreonApi() def check_api_key( api_key_query: str = Security(X_API_KEY_QUERY), api_key_header: str = Security(X_API_KEY_HEADER), ): if api_key_query == x_api_key_valid: return api_key_query elif api_key_header == x_api_key_valid: return api_key_header else: raise HTTPException( status_code=401,
class Server: api_key_name = "access_token" key_query = Security(APIKeyQuery(name=api_key_name, auto_error=False)) key_header = Security(APIKeyHeader(name=api_key_name, auto_error=False)) key_cookie = Security(APIKeyCookie(name=api_key_name, auto_error=False)) def __init__(self, core: Core, telegram: Telegram): self.core = core self.telegram = telegram self.app = FastAPI( title=core.config.app_name, docs_url=None, redoc_url=None, openapi_url=None, openapi_tags=core.config.tags_metadata, ) self.templates = configure_jinja(core) self._configure_app() self._configure_openapi() self._configure_routers() telegram.start() def get_app(self) -> FastAPI: return self.app def _configure_routers(self): self.app.include_router( worker_router.init(self.core), prefix="/api/workers", dependencies=[Depends(self._get_api_key())], tags=["workers"], ) self.app.include_router( data_router.init(self.core), prefix="/api/data", dependencies=[Depends(self._get_api_key())], tags=["data"], ) self.app.include_router( system_router.init(self.core), prefix="/api/system", dependencies=[Depends(self._get_api_key())], tags=["system"], ) self.app.include_router( telegram_router.init(self.telegram), prefix="/api/telegram", dependencies=[Depends(self._get_api_key())], tags=["telegram"], ) self.app.include_router( ui_router.init(self.core, self.templates), prefix="/ui", dependencies=[Depends(self._get_api_key())], tags=["ui"], ) def _configure_app(self): @self.app.exception_handler(Exception) async def exception_handler(_request: Request, err: Exception): code = getattr(err, "code", None) message = str(err) hide_stacktrace = isinstance(err, UserError) if code in [400, 401, 403, 404, 405]: hide_stacktrace = True if not hide_stacktrace: self.core.log.exception(err) message += "\n\n" + traceback.format_exc() if not self.core.config.debug: message = "error" return PlainTextResponse(message, status_code=500) @self.app.on_event("shutdown") def shutdown_server(): self.telegram.stop() self.core.shutdown() current_dir = Path(__file__).parent.absolute() self.app.mount("/static", StaticFiles(directory=current_dir.joinpath("static")), name="static") def _configure_openapi(self): @self.app.get("/openapi.json", tags=["openapi"], include_in_schema=False) async def get_open_api_endpoint(_api_key: APIKey = Depends(self._get_api_key())): response = JSONResponse( get_openapi( title=self.core.config.app_name, version=self.core.config.version, routes=self.app.routes, tags=self.core.config.tags_metadata, ), ) return response @self.app.get("/api", tags=["openapi"], include_in_schema=False) async def get_documentation(api_key: APIKey = Depends(self._get_api_key())): response = get_swagger_ui_html(openapi_url="/openapi.json", title=self.core.config.app_name) # noinspection PyTypeChecker response.set_cookie( self.api_key_name, value=api_key, domain=self.core.config.domain, httponly=True, max_age=60 * 60 * 24 * 30, expires=60 * 60 * 24 * 30, ) return response @self.app.get("/logout", tags=["auth"]) async def route_logout_and_remove_cookie(): response = RedirectResponse(url="/") response.delete_cookie(self.api_key_name, domain=self.core.config.domain) return response @self.app.get("/") async def redirect_to_api(): return RedirectResponse(url="/ui") def _get_api_key(self) -> Callable: async def _get_api_key( query: str = Server.key_query, header: str = Server.key_header, cookie: str = Server.key_cookie, ): if query == self.core.config.access_token: return query elif header == self.core.config.access_token: return header elif cookie == self.core.config.access_token: return cookie else: raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="access denied") return _get_api_key