Skip to content

Commit

Permalink
Add api and wsapi endpoints for plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Wrench56 committed Jul 8, 2024
1 parent a260878 commit 0b9a973
Showing 1 changed file with 73 additions and 9 deletions.
82 changes: 73 additions & 9 deletions src/backend/server/main.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from typing import Any
from typing import Any, Optional

import datetime
import inspect
import logging

from fastapi import FastAPI, Request
from fastapi import BackgroundTasks, FastAPI, Request, WebSocket
from fastapi.responses import FileResponse, ORJSONResponse, PlainTextResponse
from fastapi.staticfiles import StaticFiles

from api import expose
from db import users
from plugins import downloader, handler
from server import build
from utils import config, const, motd, settings, status

Expand Down Expand Up @@ -60,7 +62,8 @@ async def rebuild(request: Request) -> PlainTextResponse:

# Login
@app.get('/', response_class=FileResponse)
async def login_page() -> FileResponse:
async def login_page(bg_tasks: BackgroundTasks) -> FileResponse:
bg_tasks.add_task(handler.load_all)
return FileResponse('../public/login.html')


Expand Down Expand Up @@ -128,10 +131,32 @@ async def update_setting(request: Request, id_: str) -> PlainTextResponse:


# Plugins
@app.get('/plugins/{plugin}/{endpoint:path}')
@app.put('/plugins/{plugin}/{endpoint:path}')
@app.post('/plugins/{plugin}/{endpoint:path}')
@app.delete('/plugins/{plugin}/{endpoint:path}')
@app.get('/plugins', response_class=FileResponse)
async def plugins_page(request: Request) -> FileResponse:
if database.uuid_exists(request.cookies.get('auth_cookie')):
return FileResponse('../public/plugins.html')
return FileResponse('../public/blocked.html')


@app.post('/plugins')
async def install_plugin(request: Request) -> PlainTextResponse:
response = PlainTextResponse()
if not database.uuid_exists(request.cookies.get('auth_cookie')):
response.status_code = 401
return response

data = await request.json()
if data.get('url'):
if not downloader.from_url(data.get('url')):
response.status_code = 501

return response


@app.get('/plugins/api/{plugin}/{endpoint:path}')
@app.put('/plugins/api/{plugin}/{endpoint:path}')
@app.post('/plugins/api/{plugin}/{endpoint:path}')
@app.delete('/plugins/api/{plugin}/{endpoint:path}')
async def plugins(request: Request, plugin: str, endpoint: str) -> Any:
response = PlainTextResponse()
if not database.uuid_exists(request.cookies.get('auth_cookie')):
Expand All @@ -140,7 +165,46 @@ async def plugins(request: Request, plugin: str, endpoint: str) -> Any:

# Remove sensitive cookie(s)
request.cookies['auth_cookie'] = ''

# Run callback in async
callback = expose.fetch_callback(plugin, endpoint, request.method)
if callback:
return callback(endpoint, request)
if callback is None:
logging.error(f'Callback for "{plugin}/{endpoint}" does not exist')
response.status_code = 503
return response
return_value = None
if inspect.iscoroutinefunction(callback):
return_value = await callback(endpoint, request)
else:
# Sync function detected
logging.error(f'Plugin "{plugin}" uses synchronous functions, request blocked')
response.status_code = 503
if return_value is not None:
return return_value
return response


@app.websocket('/plugins/wsapi/{plugin}/{endpoint}')
async def ws_plugins(websocket: WebSocket, plugin: str, endpoint: str) -> Any:
response = PlainTextResponse()
if not database.uuid_exists(websocket.cookies.get('auth_cookie')):
response.status_code = 401
return response

# Remove sensitive cookie(s)
websocket.cookies['auth_cookie'] = ''

# Run callback in async
callback = expose.fetch_callback(plugin, endpoint, 'WEBSOCKET')
if callback is None:
logging.error(f'Callback for "{plugin}/{endpoint}" does not exist')
response.status_code = 503
return response

if inspect.iscoroutinefunction(callback):
await callback(endpoint, websocket)
else:
# Sync function detected
logging.error(f'Plugin "{plugin}" uses synchronous functions, request blocked')
response.status_code = 503
return response

0 comments on commit 0b9a973

Please sign in to comment.