diff --git a/Orchestrator/config.py b/Orchestrator/config.py index 3ae229b1..0d8f441a 100755 --- a/Orchestrator/config.py +++ b/Orchestrator/config.py @@ -44,7 +44,7 @@ else: Orchestrator.OrchestratorLoggerGet().setLevel(logging.INFO) # TEST Add User ND - Add Login ND to superuser of the Orchestrator lUACClientDict = SettingsTemplate.__UACClientAdminCreate__() - gSettings["ServerDict"]["AccessUsers"]["FlagCredentialsAsk"]=False + gSettings["ServerDict"]["AccessUsers"]["FlagCredentialsAsk"]=True Orchestrator.UACUpdate(inGSettings=gSettings, inADLoginStr="ND", inADStr="", inADIsDefaultBool=True, inURLList=[], inRoleHierarchyAllowedDict=lUACClientDict) Orchestrator.UACUpdate(inGSettings=gSettings, inADLoginStr="rpa00", inADStr="", inADIsDefaultBool=True, inURLList=[], inRoleHierarchyAllowedDict=lUACClientDict) # TEST Add User IMaslov - Add Login IMaslov to superuser of the Orchestrator diff --git a/Sources/pyOpenRPA/Orchestrator/Server.py b/Sources/pyOpenRPA/Orchestrator/Server.py index 3f877ad3..ee5c7c2a 100755 --- a/Sources/pyOpenRPA/Orchestrator/Server.py +++ b/Sources/pyOpenRPA/Orchestrator/Server.py @@ -18,9 +18,10 @@ from . import ServerBC # объявление import from fastapi import FastAPI, Form, Request, HTTPException, Depends, Header, Response, Body -from fastapi.responses import PlainTextResponse, HTMLResponse, FileResponse, RedirectResponse +from fastapi.responses import PlainTextResponse, HTMLResponse, FileResponse, RedirectResponse, JSONResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates +from fastapi.encoders import jsonable_encoder from starlette.datastructures import MutableHeaders from pydantic import BaseModel import uvicorn @@ -74,11 +75,11 @@ def IdentifyAuthorize(inRequest:Request, inResponse:Response, return lCookieAuthToken ###################################### #Way 2 - try to logon - if len(lHeaderAuthorization) == 2: + if lHeaderAuthorization != ['']: if "AuthExc" in lCookies: raise AuthException() else: - llHeaderAuthorizationDecodedUserPasswordList = base64.b64decode(lHeaderAuthorization[1]).decode("utf-8").split(":") + llHeaderAuthorizationDecodedUserPasswordList = base64.b64decode(lHeaderAuthorization[0]).decode("utf-8").split(":") lUser = llHeaderAuthorizationDecodedUserPasswordList[0] lPassword = llHeaderAuthorizationDecodedUserPasswordList[1] lDomain = "" @@ -114,9 +115,7 @@ def IdentifyAuthorize(inRequest:Request, inResponse:Response, mOpenRPA["Domain"] = lResult["Domain"] mOpenRPA["User"] = lResult["User"] mOpenRPA["IsSuperToken"] = __Orchestrator__.GSettingsGet().get("ServerDict", {}).get("AccessUsers", {}).get("AuthTokensDict", {}).get(mOpenRPA["AuthToken"], {}).get("FlagDoNotExpire", False) - try:inResponse.delete_cookie(key="AuthExc") - except Exception:pass - return lAuthToken + raise ReloadPage(token=lAuthToken) #inRequest.OpenRPASetCookie = {} #New engine of server #inRequest.OpenRPAResponseDict["SetCookies"]["AuthToken"] = lAuthToken @@ -151,27 +150,40 @@ class ErrorException(Exception): self.text = text class AuthException(Exception): - def __init__(self, name: str="AuthTryWindowCreate"): + def __init__(self, name: str="AuthTryWindowCreate"): self.name = name +class ReloadPage(Exception): + def __init__(self, token :str, name: str="AuthToken"): + self.name = name + self.token = token + templates = Jinja2Templates(directory=CrossOS.PathJoinList(CrossOS.PathSplitList(__file__)[:-2] + ["Resources","Web","orpa"])) # Обработчик ошибки авторизации (вывод информации о причинах неудачной авторизации) @app.exception_handler(ErrorException) async def unicorn_exception_handler(request: Request, exc:ErrorException): - response = templates.TemplateResponse(status_code=401,name="badAuth.xhtml", context={"request":request, "errorMsg":exc.text, "title":"ОРКЕСТРАТОР PYOPENRPA", "subtitle":"ПАНЕЛЬ УПРАВЛЕНИЯ", "version":__version__}) - response.set_cookie(key=exc.name,value="True") + response = templates.TemplateResponse(status_code=401,name="badAuth.xhtml", context={"request":request, "errorMsg":exc.text, "title":"ОРКЕСТРАТОР PYOPENRPA", "subtitle":"АВТОРИЗАЦИЯ", "version":__version__}) + response.set_cookie(key="AuthExc",value="True") return response -# Обработчик попытки авторизации (отвечает за вызов окна для ввода пары логин / пароль) -@app.exception_handler(AuthException) -async def unicorn_exception_handler_2(request: Request, exc: AuthException): - response = HTMLResponse(status_code=401, headers={'Content-type':'text/html; charset=utf-8', 'WWW-Authenticate':'Basic'}) +# Обработчик успешной попытки авторизации (обновление страницы + установки куки-токена) +@app.exception_handler(ReloadPage) +async def unicorn_exception_handler_3(request: Request, exc:ReloadPage): + response = HTMLResponse(content="", status_code=200) + response.set_cookie(key=exc.name, value=exc.token) try:response.delete_cookie(key="AuthExc") except Exception:pass return response +# Обработчик попытки авторизации (отвечает за рендер формы для ввода пары логин / пароль) +@app.exception_handler(AuthException) +def unicorn_exception_handler_2(request: Request, exc: AuthException): + response = templates.TemplateResponse(status_code=401,name="auth.xhtml", context={"request":request, "title":"ОРКЕСТРАТОР PYOPENRPA", "subtitle":"АВТОРИЗАЦИЯ", "version":__version__}) + try:response.delete_cookie(key="AuthExc") + except Exception:pass + return response diff --git a/Sources/pyOpenRPA/Resources/Web/orpa/auth.xhtml b/Sources/pyOpenRPA/Resources/Web/orpa/auth.xhtml new file mode 100644 index 00000000..b4a05070 --- /dev/null +++ b/Sources/pyOpenRPA/Resources/Web/orpa/auth.xhtml @@ -0,0 +1,142 @@ + + + + + + + + + + + Оркестратор pyOpenRPA + + + + + + + + + + + + + + + + {% include 'header.xhtml' %} +
+
+
+ + Для доступа к панели управления, пожалуйста, пройдите авторизацию +
+
+
+

+
Логин от учетной записи
+
+ +
+

+
+

+
Пароль от учетной записи
+
+ +
+

+
+ +
+
+ +
+
+
+ {% include 'footer.xhtml' %} + + + + + + + + + diff --git a/Sources/pyOpenRPA/Resources/Web/orpa/badAuth.xhtml b/Sources/pyOpenRPA/Resources/Web/orpa/badAuth.xhtml index 7e8c0992..0f1e37ca 100644 --- a/Sources/pyOpenRPA/Resources/Web/orpa/badAuth.xhtml +++ b/Sources/pyOpenRPA/Resources/Web/orpa/badAuth.xhtml @@ -17,15 +17,15 @@ - - + + Оркестратор pyOpenRPA - - - - - - + + + + + + @@ -34,68 +34,32 @@ + {% include 'header.xhtml' %} -




+




Внимание

{{errorMsg}}

- +
{% include 'footer.xhtml' %} diff --git a/Sources/pyOpenRPA/Resources/Web/orpa/header.xhtml b/Sources/pyOpenRPA/Resources/Web/orpa/header.xhtml index bf933b79..e0b7cd06 100755 --- a/Sources/pyOpenRPA/Resources/Web/orpa/header.xhtml +++ b/Sources/pyOpenRPA/Resources/Web/orpa/header.xhtml @@ -1,21 +1,21 @@ - - + + - - - - - + + + + + - - - - - - - - + + + + + + + +
diff --git a/changelog.md b/changelog.md index f3c0b046..592ab500 100755 --- a/changelog.md +++ b/changelog.md @@ -29,7 +29,7 @@ AGT - AGENT - - Переработана система обработки AuthTokenStr==None. Теперь поднимается exception в случаях, когда авторизация производилась, но AuthTokenStr==None - - Добавлена новая функция - Orchestrator.OrchestratorIsCredentialsAsk. Определяет была ли произведена авторизация пользователя - - WebURLConnectFolder - переработано. Добавлен флаг обработки ошибки, позволяющий продолжить инициализацию оркестратора, если папки не существует -- - Переработана система авторизации. Добавлена форма, появляющаяся при неудачной попытке авторизации. +- - Переработана система авторизации. Добавлена стартовая страница оркестратора с формой для ввода пары логин / пароль - РОБОТ - - Убрали лишний print из Screen.BoxAnchorRuleCheck - - pyOpenRPA.Robot.UIWeb.BrowserChromeStart - добавлен флаг печати в PDF и директория для сохранения при инициализации браузера