2021-01-06 19:52:14 +08:00
|
|
|
from felicity.init import initialize_felicity
|
2021-09-20 17:27:40 +08:00
|
|
|
import logging
|
|
|
|
from typing import List
|
|
|
|
from fastapi import FastAPI, WebSocket
|
|
|
|
from starlette.middleware.cors import CORSMiddleware
|
|
|
|
from graphql.execution.executors.asyncio import AsyncioExecutor
|
|
|
|
|
|
|
|
from starlette.middleware.authentication import AuthenticationMiddleware
|
|
|
|
from starlette.authentication import (
|
|
|
|
AuthenticationBackend,
|
|
|
|
AuthenticationError,
|
|
|
|
SimpleUser,
|
|
|
|
# UnauthenticatedUser,
|
|
|
|
AuthCredentials
|
|
|
|
)
|
|
|
|
import base64
|
|
|
|
import binascii
|
|
|
|
|
|
|
|
from felicity.api.api_v1.api import api_router # noqa
|
|
|
|
from felicity.core.config import settings # noqa
|
|
|
|
|
|
|
|
from starlette.graphql import GraphQLApp
|
|
|
|
from felicity.gql.schema import gql_schema # noqa
|
|
|
|
from felicity.gql.deps import get_current_active_user
|
|
|
|
|
|
|
|
from felicity.apps.job.sched import felicity_workforce_init, felicity_halt_workforce
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class FelicityAuthBackend(AuthenticationBackend):
|
|
|
|
async def authenticate(self, request):
|
|
|
|
if "Authorization" not in request.headers:
|
|
|
|
logger.info(f"No Authorization Data")
|
|
|
|
return
|
|
|
|
|
|
|
|
auth = request.headers["Authorization"]
|
|
|
|
try:
|
|
|
|
scheme, credentials = auth.split()
|
|
|
|
if scheme.lower() == 'basic':
|
|
|
|
decoded = base64.b64decode(credentials).decode("ascii")
|
|
|
|
username, _, password = decoded.partition(":")
|
|
|
|
# TODO: You'd want to verify the username and password here if needed
|
|
|
|
elif scheme.lower() == 'bearer':
|
|
|
|
""""get is active user from token"""
|
|
|
|
# logger.info(f"credentials bearer: {credentials}")
|
|
|
|
user = await get_current_active_user(credentials)
|
|
|
|
# logger.info(f"User from token: {user.auth.user_name}")
|
|
|
|
username, _, password = user.auth.user_name, None, None
|
|
|
|
else:
|
|
|
|
raise AuthenticationError(f'UnKnown Authentication Backend: {scheme.lower()}')
|
|
|
|
|
|
|
|
return AuthCredentials(["authenticated"]), SimpleUser(username)
|
|
|
|
|
|
|
|
except (ValueError, UnicodeDecodeError, binascii.Error) as exc:
|
|
|
|
raise AuthenticationError(f'Invalid auth credentials: {exc}')
|
|
|
|
|
|
|
|
|
|
|
|
flims = FastAPI(
|
|
|
|
title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json"
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@flims.on_event("startup")
|
|
|
|
async def startup():
|
|
|
|
await initialize_felicity()
|
|
|
|
felicity_workforce_init()
|
|
|
|
|
|
|
|
|
|
|
|
@flims.on_event("shutdown")
|
|
|
|
async def shutdown():
|
|
|
|
felicity_halt_workforce()
|
|
|
|
|
|
|
|
|
|
|
|
# Set all CORS enabled origins
|
|
|
|
if settings.BACKEND_CORS_ORIGINS:
|
|
|
|
flims.add_middleware(
|
|
|
|
CORSMiddleware,
|
|
|
|
allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],
|
|
|
|
allow_credentials=True,
|
|
|
|
allow_methods=["*"],
|
|
|
|
allow_headers=["*"],
|
2021-01-06 19:52:14 +08:00
|
|
|
)
|
|
|
|
|
2021-09-20 17:27:40 +08:00
|
|
|
flims.add_middleware(
|
|
|
|
AuthenticationMiddleware,
|
|
|
|
backend=FelicityAuthBackend()
|
|
|
|
)
|
|
|
|
|
|
|
|
flims.include_router(api_router, prefix=settings.API_V1_STR)
|
|
|
|
flims.add_route("/felicity-gql", GraphQLApp(schema=gql_schema, executor_class=AsyncioExecutor))
|
2021-09-05 17:10:59 +08:00
|
|
|
|
2021-01-06 19:52:14 +08:00
|
|
|
|
2021-09-20 17:27:40 +08:00
|
|
|
class ConnectionManager:
|
|
|
|
def __init__(self):
|
|
|
|
self.connections: List[WebSocket] = []
|
2021-04-18 18:37:49 +08:00
|
|
|
|
2021-09-20 17:27:40 +08:00
|
|
|
async def connect(self, websocket: WebSocket):
|
|
|
|
await websocket.accept()
|
|
|
|
self.connections.append(websocket)
|
2021-04-18 18:37:49 +08:00
|
|
|
|
2021-09-20 17:27:40 +08:00
|
|
|
async def broadcast(self, data: str):
|
|
|
|
for connection in self.connections:
|
|
|
|
await connection.send_text(data)
|
2021-04-18 18:37:49 +08:00
|
|
|
|
|
|
|
|
2021-09-20 17:27:40 +08:00
|
|
|
manager = ConnectionManager()
|
2021-04-18 18:37:49 +08:00
|
|
|
|
|
|
|
|
2021-09-20 17:27:40 +08:00
|
|
|
@flims.websocket("/ws")
|
|
|
|
async def websocket_endpoint(websocket: WebSocket):
|
|
|
|
await manager.connect(websocket)
|
|
|
|
while True:
|
|
|
|
data = await websocket.receive_text()
|
|
|
|
await manager.broadcast(f"Client {data}")
|