fastapi inprogress

merge-requests/1/merge
Ivan Maslov 2 years ago
parent 2b06170730
commit a12de50131

@ -14,6 +14,8 @@ import json
from threading import Thread
import inspect
from requests import request
from pyOpenRPA.Tools import CrossOS
from . import Processor # Add new processor
from . import ProcessorOld # Support old processor - deprecated defs only for backward compatibility
@ -82,7 +84,7 @@ def AuthenticateBlock(inRequest):
def UserAccessCheckBefore(inMethod, inRequest):
# Help def - Get access flag from dict
#pdb.set_trace()
global gSettingsDict
gSettingsDict = __Orchestrator__.GSettingsGet()
def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict):
if "FlagAccess" in inAccessRuleItem:
return inAccessRuleItem["FlagAccess"]
@ -171,6 +173,21 @@ def UserAccessCheckBefore(inMethod, inRequest):
return lResult
class HTTPRequestOld():
mRequest:Request = None
mResponse:Response = None
OpenRPA: dict = {}
def __init__(self,inRequest,inResponse,inAuthDict):
self.mRequest = inRequest
self.mResponse = inResponse
if inAuthDict is None:
self.OpenRPA = {}
self.OpenRPA["IsSuperToken"] = False
self.OpenRPA["AuthToken"] = None
self.OpenRPA["Domain"] = None
self.OpenRPA["User"] = None
else: self.OpenRPA = inAuthDict
# Def to check User Role access grants
def UACClientCheck(self, inRoleKeyList): # Alias
return self.UserRoleAccessAsk(inRoleKeyList=inRoleKeyList)
@ -205,7 +222,7 @@ class HTTPRequestOld():
#Tech def
#return {"headers":[],"body":"","statuscode":111}
def URLItemCheckDo(self, inURLItem, inMethod, inOnlyFlagUACBool = False):
global gSettingsDict
gSettingsDict = __Orchestrator__.GSettingsGet()
###############################
#Tech sub def - do item
################################
@ -256,7 +273,6 @@ class HTTPRequestOld():
else:
inURLItem["ResponseDefRequestGlobal"]()
if "ResponseFolderPath" in inURLItem:
#lRequestPath = inRequest.path
lRequestPath = urllib.parse.unquote(inRequest.path)
if inURLItem["URL"][-1]!="/": inURLItem["URL"]+= "/" # Fix for settings
@ -329,49 +345,35 @@ class HTTPRequestOld():
return False
#ResponseContentTypeFile
def SendResponseContentTypeFile(self, inContentType, inFilePath):
# Send response status code
self.send_response(200)
inResponseDict = self.OpenRPAResponseDict
self.mResponse.status_code = 200
# Send headers
self.send_header('Content-type', inContentType)
self.mResponse.headers["Content-type"]=inContentType
#Check if var exist
if hasattr(self, "OpenRPASetCookie"):
self.send_header("Set-Cookie", f"AuthToken={self.OpenRPA['AuthToken']}")
self.end_headers()
self.mResponse.set_cookie(key='AuthToken',value=self.OpenRPA['AuthToken'])
lFileObject = open(inFilePath, "rb")
# Write content as utf-8 data
self.wfile.write(lFileObject.read())
lFileBytes = lFileObject.read()
#Закрыть файловый объект
lFileObject.close()
return lFileBytes
# ResponseContentTypeFile
def ResponseDictSend(self):
lL = gSettingsDict["Logger"]
inResponseDict = self.OpenRPAResponseDict
# Send response status code
self.send_response(inResponseDict["StatusCode"])
self.mResponse.status_code = inResponseDict["StatusCode"]
# Send headers
for lItemKey, lItemValue in inResponseDict["Headers"].items():
self.send_header(lItemKey, lItemValue)
self.mResponse.headers[lItemKey]=lItemValue
# Send headers: Set-Cookie
for lItemKey, lItemValue in inResponseDict["SetCookies"].items():
self.mResponse.set_cookie(key=lItemKey,value=lItemValue)
self.send_header("Set-Cookie", f"{lItemKey}={lItemValue}")
#Close headers section in response
try:
self.end_headers()
# Write content as utf-8 data
self.wfile.write(inResponseDict["Body"])
except (ConnectionResetError, ConnectionAbortedError) as e:
if lL: lL.warning(f"SERVER: Connection was forcibly closed by the client side - OK for the network interactions (ConnectionResetError: [WinError 10054] or ConnectionAbortedError: [WinError 10053])")
return inResponseDict["Body"]
def do_GET(self):
def do_GET(self, inBodyStr):
try:
global gSettingsDict
#self.timeout=gSettingsDict["ServerDict"]["RequestTimeoutSecFloat"]
self.request.settimeout(gSettingsDict["ServerDict"]["RequestTimeoutSecFloat"])
threading.current_thread().request = self
self.OpenRPA = {}
self.OpenRPA["AuthToken"] = None
self.OpenRPA["Domain"] = None
self.OpenRPA["User"] = None
gSettingsDict = __Orchestrator__.GSettingsGet()
self.OpenRPA["DefUserRoleAccessAsk"]=self.UserRoleAccessAsk # Alias for def
self.OpenRPA["DefUserRoleHierarchyGet"]=self.UserRoleHierarchyGet # Alias for def
# Prepare result dict
@ -395,49 +397,27 @@ class HTTPRequestOld():
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET")
if lFlagURLIsApplied:
self.ResponseDictSend()
return
return self.ResponseDictSend()
#Monitor
if self.path == '/Monitor/JSONDaemonListGet':
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
message = json.dumps(gSettingsDict)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
lResponseDict = {"Headers": {'Content-type':'application/json'}, "SetCookies": {}, "Body": bytes(json.dumps(gSettingsDict), "utf8"), "StatusCode": 200}
return self.ResponseDictSend()
#Filemanager function
if self.path.lower().startswith('/filemanager/'):
lFileURL=self.path[13:]
# check if file in FileURL - File Path Mapping Dict
if lFileURL.lower() in gSettingsDict["FileManager"]["FileURLFilePathDict"]:
self.SendResponseContentTypeFile('application/octet-stream', gSettingsDict["FileManager"]["FileURLFilePathDict"][lFileURL])
return self.SendResponseContentTypeFile('application/octet-stream', gSettingsDict["FileManager"]["FileURLFilePathDict"][lFileURL])
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
except BrokenPipeError as e:
lL = gSettingsDict["Logger"]
if lL: lL.warning(f"Сервер (do_GET): Возникла ошибка сети - BrokenPipeError: [Errno 32] Broken pipe. Сервер продолжает работу")
raise HTTPException(status_code=403, detail="here is the details", headers={})
except Exception as e:
lL = gSettingsDict["Logger"]
if lL: lL.exception(f"Сервер (do_GET): Неопознанная ошибка сети - см. текст ошибки. Сервер продолжает работу")
# POST
def do_POST(self):
def do_POST(self, inBodyStr):
try:
global gSettingsDict
#self.timeout=gSettingsDict["ServerDict"]["RequestTimeoutSecFloat"]
self.request.settimeout(gSettingsDict["ServerDict"]["RequestTimeoutSecFloat"])
threading.current_thread().request = self
gSettingsDict = __Orchestrator__.GSettingsGet()
lL = gSettingsDict["Logger"]
self.OpenRPA = {}
self.OpenRPA["AuthToken"] = None
self.OpenRPA["Domain"] = None
self.OpenRPA["User"] = None
self.OpenRPA["DefUserRoleAccessAsk"]=self.UserRoleAccessAsk # Alias for def
self.OpenRPA["DefUserRoleHierarchyGet"]=self.UserRoleHierarchyGet # Alias for def
# Prepare result dict
@ -461,24 +441,13 @@ class HTTPRequestOld():
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "POST")
if lFlagURLIsApplied:
self.ResponseDictSend()
return
return self.ResponseDictSend()
#Централизованная функция получения запросов/отправки
if self.path == '/Utils/Processor':
#ReadRequest
lInputObject={}
if self.headers.get('Content-Length') is not None:
lInputByteArrayLength = int(self.headers.get('Content-Length'))
lInputByteArray=self.rfile.read(lInputByteArrayLength)
#Превращение массива байт в объект
lInputObject=json.loads(lInputByteArray.decode('utf8'))
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
#Превращение массива байт в объект
lInputObject=json.loads(inBodyStr)
# Logging info about processor activity if not SuperToken ()
if not lIsSuperToken:
if not self.mOpenRPA['IsSuperToken']:
lActivityTypeListStr = ""
try:
if type(lInputObject) is list:
@ -487,22 +456,12 @@ class HTTPRequestOld():
else:
lActivityTypeListStr += f"{lInputObject['Type']}"
except Exception as e:
lActivityTypeListStr = "Has some error with Activity Type read"
lActivityTypeListStr = "Обнаружена ошибка при чтении Activity Type"
if lL: lL.info(f"Сервер:: !ВНИМАНИЕ! /Utils/Processor через некоторое время перестанет поддерживаться. Используйте /pyOpenRPA/Processor или /pyOpenRPA/ActivityListExecute. Активность поступила от пользователя. Домен: {self.OpenRPA['Domain']}, Логин: {self.OpenRPA['User']}, Тип активности: {lActivityTypeListStr}")
# Send message back to client
message = json.dumps(ProcessorOld.ActivityListOrDict(lInputObject))
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return
lResponseDict = {"Headers": {'Content-type':'application/json'}, "SetCookies": {}, "Body": bytes(json.dumps(ProcessorOld.ActivityListOrDict(lInputObject)), "utf8"), "StatusCode": 200}
return self.ResponseDictSend()
else:
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
return
except BrokenPipeError as e:
lL = gSettingsDict["Logger"]
if lL: lL.warning(f"Сервер, обратная совместимость (do_POST): Возникла ошибка сети - BrokenPipeError: [Errno 32] Broken pipe. Сервер продолжает работу")
raise HTTPException(status_code=403, detail="here is the details", headers={})
except Exception as e:
lL = gSettingsDict["Logger"]
if lL: lL.exception(f"Сервер, обратная совместимость (do_POST): Неопознанная ошибка сети - см. текст ошибки. Сервер продолжает работу")
@ -511,7 +470,7 @@ class HTTPRequestOld():
from typing import Union
# объявление import
from fastapi import FastAPI, Form, Request, HTTPException, Depends, Header, Response
from fastapi import FastAPI, Form, Request, HTTPException, Depends, Header, Response, Body
from fastapi.responses import PlainTextResponse, HTMLResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
@ -548,12 +507,12 @@ def IdentifyAuthorize(inRequest:Request, inResponse:Response,
lResult["Domain"] = gSettingsDict["ServerDict"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["Domain"]
lResult["User"] = gSettingsDict["ServerDict"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["User"]
#Set auth token
inRequest.OpenRPA={}
inRequest.OpenRPA["AuthToken"] = lCookieAuthToken
inRequest.OpenRPA["Domain"] = lResult["Domain"]
inRequest.OpenRPA["User"] = lResult["User"]
#Exit earlier
return lResult
mOpenRPA={}
mOpenRPA["AuthToken"] = lAuthToken
mOpenRPA["Domain"] = lResult["Domain"]
mOpenRPA["User"] = lResult["User"]
mOpenRPA["IsSuperToken"] = gSettingsDict.get("ServerDict", {}).get("AccessUsers", {}).get("AuthTokensDict", {}).get(mOpenRPA["AuthToken"], {}).get("FlagDoNotExpire", False)
return mOpenRPA
######################################
#Way 2 - try to logon
elif len(lHeaderAuthorization) == 2:
@ -579,10 +538,12 @@ def IdentifyAuthorize(inRequest:Request, inResponse:Response,
gSettingsDict["ServerDict"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie
inResponse.set_cookie(key="AuthToken",value=lAuthToken)
inRequest.OpenRPA={}
inRequest.OpenRPA["AuthToken"] = lAuthToken
inRequest.OpenRPA["Domain"] = lResult["Domain"]
inRequest.OpenRPA["User"] = lResult["User"]
mOpenRPA={}
mOpenRPA["AuthToken"] = lAuthToken
mOpenRPA["Domain"] = lResult["Domain"]
mOpenRPA["User"] = lResult["User"]
mOpenRPA["IsSuperToken"] = gSettingsDict.get("ServerDict", {}).get("AccessUsers", {}).get("AuthTokensDict", {}).get(mOpenRPA["AuthToken"], {}).get("FlagDoNotExpire", False)
return mOpenRPA
#inRequest.OpenRPASetCookie = {}
#New engine of server
#inRequest.OpenRPAResponseDict["SetCookies"]["AuthToken"] = lAuthToken
@ -594,38 +555,47 @@ def IdentifyAuthorize(inRequest:Request, inResponse:Response,
return True
def BackwardCompatibityWrapper(): # Old from v1.3.1 (updated to FastAPI)
lHTTPRequest = HTTPRequestOld()
lHTTPRequest.do_GET
lHTTPRequest.do_POST
@app.get(path="/", response_class=PlainTextResponse)
def Hi(t:bool=Depends(IdentifyAuthorize)):
return "Hello world"
def BackwardCompatibityWrapperAuth(inRequest:Request, inResponse:Response, inBodyStr:str = Body(...),
inAuthDict:bool=Depends(IdentifyAuthorize)): # Old from v1.3.1 (updated to FastAPI)
lHTTPRequest = HTTPRequestOld(inRequest=inRequest, inResponse=inResponse, inAuthDict=inAuthDict)
threading.current_thread().request = lHTTPRequest
lResult = lHTTPRequest.do_GET(inBodyStr=inBodyStr)
if lResult is None:
lResult = lHTTPRequest.do_POST(inBodyStr=inBodyStr)
return lResult
def BackwardCompatibityWrapperNoAuth(inRequest:Request, inResponse:Response, inBodyStr:str = Body(...)): # Old from v1.3.1 (updated to FastAPI)
lHTTPRequest = HTTPRequestOld(inRequest=inRequest, inResponse=inResponse, inAuthDict=None)
threading.current_thread().request = lHTTPRequest
lResult = lHTTPRequest.do_GET(inBodyStr=inBodyStr)
if lResult is None:
lResult = lHTTPRequest.do_POST(inBodyStr=inBodyStr)
return lResult.decode("utf8")
def FastAPI():
def InitFastAPI():
global gSettingsDict
global app
lL = gSettingsDict.get("Logger",None)
#lThreadServer = Server.RobotDaemonServer(lItemKeyStr, gSettingsDict)
#lThreadServer.start()
gSettingsDict["ServerDict"]["ServerThread"] = app
app.add_api_route(
path="/",
endpoint=ServerSettings.pyOpenRPA_Index,
response_class=PlainTextResponse
for lConnectItemDict in gSettingsDict["ServerDict"]["URLList"]:
if lConnectItemDict.get("UACBool",True):
app.add_api_route(
path=lConnectItemDict["URL"],
endpoint=BackwardCompatibityWrapperAuth,
response_class=PlainTextResponse,
methods=[lConnectItemDict["Method"]]
)
else:
app.add_api_route(
path=lConnectItemDict["URL"],
endpoint=BackwardCompatibityWrapperNoAuth,
response_class=PlainTextResponse,
methods=[lConnectItemDict["Method"]]
)
#app.get("/", ServerSettings.pyOpenRPA_Index, response_class=PlainTextResponse)
uvicorn.run('pyOpenRPA.Orchestrator.Server:app', host='0.0.0.0', port=1024)
if lL: lL.info(f"Сервер инициализирован успешно (с поддержкой SSL):: Наименование: {self.name}, Слушает URL: {lAddressStr}, Слушает порт: {lPortInt}, Путь к файлу сертификата (.pem): {lCertFilePathStr}")
if lL: lL.info(f"Сервер инициализирован успешно (без поддержки SSL):: Наименование: {self.name}, Слушает URL: {lAddressStr}, Слушает порт: {lPortInt}")
#if lL: lL.info(f"Сервер инициализирован успешно (с поддержкой SSL):: Наименование: {self.name}, Слушает URL: {lAddressStr}, Слушает порт: {lPortInt}, Путь к файлу сертификата (.pem): {lCertFilePathStr}")
#if lL: lL.info(f"Сервер инициализирован успешно (без поддержки SSL):: Наименование: {self.name}, Слушает URL: {lAddressStr}, Слушает порт: {lPortInt}")
if lL: lL.info("Модуль сервера FASTAPI") #Logging
if lL: lL.info("Модуль сервера (FastAPI) инициализирован!") #Logging
Loading…
Cancel
Save