Add needed functionality

- Access token acquire
- Item update
- Startup from CLI
This commit is contained in:
Andrew 2023-04-12 01:19:06 +07:00
parent 200d70313a
commit b406a9a3c8

83
app.py
View file

@ -1,24 +1,28 @@
import io import io
from typing import Any from typing import Any
from fastapi import FastAPI, status, Header, UploadFile from fastapi import FastAPI, status, Header, UploadFile, Response
from starlette.responses import StreamingResponse from starlette.responses import StreamingResponse
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from based import db from based import db
import psycopg import psycopg
from hashlib import sha256
from secrets import token_hex from secrets import token_hex
from minio import Minio from minio import Minio
from minio.error import S3Error
from minio.helpers import ObjectWriteResult from minio.helpers import ObjectWriteResult
from urllib3 import HTTPResponse from urllib3 import HTTPResponse
import uvicorn
from dba import * from dba import *
from models import ( from models import (
AuthModel,
ColumnsDefinitionList, ColumnsDefinitionList,
ErrorResponseDefinition,
ItemDeletionDefinitionList, ItemDeletionDefinitionList,
ItemsFieldSelectorList, ItemsFieldSelectorList,
TableDefinition,
TableListDefinition,
UserDefinition, UserDefinition,
) )
from secutils import hash_password
from utils import ( from utils import (
check_if_admin_access_token, check_if_admin_access_token,
parse_columns_from_definition, parse_columns_from_definition,
@ -52,14 +56,27 @@ app.add_middleware(
) )
@app.post("/api/getAccessToken")
async def getAccessToken(userData: AuthModel):
user = check_user(connector, userData.username, userData.password)
if not user:
return {"error": "Wrong username or password"}
return {"access_token": user.access_token}
@app.get("/api/listTables") @app.get("/api/listTables")
async def listTables(access_token: str | None = Header(default=None)): async def listTables(
response: Response,
access_token: str | None = Header(default=None),
) -> TableListDefinition | ErrorResponseDefinition:
is_admin = check_if_admin_access_token(connector, access_token) is_admin = check_if_admin_access_token(connector, access_token)
if not is_admin: if not is_admin:
return {"error": "Not allowed"} return ErrorResponseDefinition(error="Not allowed")
tables = connector.tables() return TableListDefinition(
return tables tables=[TableDefinition.parse_obj(table) for table in connector.tables()]
)
@app.post("/api/createTable/{tableName}") @app.post("/api/createTable/{tableName}")
@ -160,14 +177,11 @@ async def items(
if column not in allowedColumns: if column not in allowedColumns:
return {"error": "Not allowed"} return {"error": "Not allowed"}
print(columnsNames)
print(selector)
table_items = connector.selectFromTable( table_items = connector.selectFromTable(
tableName, selector.fields if selector.fields else ["*"] tableName, selector.fields if selector.fields else ["*"]
) )
return table_items return {"items": table_items}
@app.post("/items/{tableName}/+") @app.post("/items/{tableName}/+")
@ -210,6 +224,49 @@ async def itemsCreate(
return {"ok": True} return {"ok": True}
@app.post("/items/{tableName}/*")
async def itemsUpdate(
tableName: str,
item: dict[str, str],
oldItem: dict[str, str],
access_token: str | None = Header(default=None),
):
table_info = connector.getTable(tableName)
if not table_info:
return {"error": "Not found"}
is_admin = check_if_admin_access_token(connector, access_token)
if table_info["system"] and not is_admin:
return {"error": "Not allowed"}
user, group = get_user_by_access_token(connector, access_token)
if not is_admin:
allowedColumns = get_allowed_columns_for_group(
connector, tableName, group.id if group else -1
)
if not allowedColumns:
return {"error": "Not allowed"}
elif len(allowedColumns) == 1 and allowedColumns[0] == "*":
pass
else:
for column in item:
if column not in allowedColumns:
return {"error": "Not allowed"}
try:
connector.updateDataInTable(
tableName,
[ColumnUpdate(column=c, value=item[c]) for c in item],
[ColumnCondition(column=c, value=oldItem[c]) for c in oldItem],
)
except psycopg.errors.UndefinedColumn:
return {"error": "Column not found"}
except Exception as e:
return {"error": str(e)}
return {"ok": True}
@app.post("/items/{tableName}/-") @app.post("/items/{tableName}/-")
async def itemsDelete( async def itemsDelete(
tableName: str, tableName: str,
@ -300,3 +357,7 @@ async def createAsset(
if not create_asset(connector, filename, "", str(result.version_id)): if not create_asset(connector, filename, "", str(result.version_id)):
return {"error": "Failed to create asset"} return {"error": "Failed to create asset"}
return {"ok": True, "fid": result.version_id} return {"ok": True, "fid": result.version_id}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)