From c16dde0fbbef4c87acc2d25cb389f2a9a9af10ae Mon Sep 17 00:00:00 2001 From: Vladislav Klychkov Date: Tue, 7 Mar 2023 12:12:29 +0300 Subject: [PATCH] fix UIDesktop Get_UIOList & UIWeb WebUserUACHierarchyGet --- Sources/pyOpenRPA/Orchestrator/Server.py | 4 +- .../Orchestrator/__Orchestrator__.py | 43 +++- Sources/pyOpenRPA/Robot/UIDesktop.py | 234 +++++++++--------- 3 files changed, 158 insertions(+), 123 deletions(-) diff --git a/Sources/pyOpenRPA/Orchestrator/Server.py b/Sources/pyOpenRPA/Orchestrator/Server.py index 23b1fd58..c01ff043 100755 --- a/Sources/pyOpenRPA/Orchestrator/Server.py +++ b/Sources/pyOpenRPA/Orchestrator/Server.py @@ -118,10 +118,10 @@ def IdentifyAuthorize(inRequest:Request, inResponse:Response, raise HTTPException(status_code=401, detail="Попытка авторизации не прошла успешно (неверная пара логин / пароль)", headers={}) ###################################### else: - raise HTTPException(status_code=401, detail="Попытка авторизации не прошла успешно (неполная пара логин / пароль)", headers={'Content-type':'text/html', 'WWW-Authenticate':'Basic'}) + raise HTTPException(status_code=401, detail="Попытка авторизации не прошла успешно (неполная пара логин / пароль)", headers={ 'WWW-Authenticate':'Basic'}) else: return None # Credentials are not required - return none - +#network.predictor.enabled lRouteList =[] diff --git a/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py b/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py index fba16897..85ad8f0c 100755 --- a/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py +++ b/Sources/pyOpenRPA/Orchestrator/__Orchestrator__.py @@ -623,6 +623,14 @@ def OrchestratorIsAdmin(): elif CrossOS.IS_LINUX_BOOL: return os.getuid()==0 else: return True +def OrchestratorIsCredentialsAsk(): + """L+,W+: Проверить, активирована ли авторизация при переходе к Оркестратору. + + :return: True - Активирована; False - Деактивирована + """ + inGSettings = GSettingsGet() + return inGSettings["ServerDict"]["AccessUsers"]["FlagCredentialsAsk"] + def OrchestratorIsInited() -> bool: """L+,W+: Проверить, было ли проинициализировано ядро Оркестратора @@ -1069,7 +1077,12 @@ def WebUserLoginGet(inAuthTokenStr: str=None) -> str: :return: Логин пользователя :rtype: str """ - if inAuthTokenStr is None: return None + + isCredentialAsk = OrchestratorIsCredentialsAsk() + if isCredentialAsk: + if inAuthTokenStr is None: raise ConnectionError("Не удается получить токен для авторизации") + else: + if inAuthTokenStr is None: return None inGS = GSettingsGet() # Get the global settings return inGS.get("ServerDict", {}).get("AccessUsers", {}).get("AuthTokensDict", {}).get(inAuthTokenStr, {}).get("User", None) @@ -1081,18 +1094,22 @@ def WebUserDomainGet(inAuthTokenStr: str=None) -> str: :return: Домен пользователя :rtype: str """ - - if inAuthTokenStr is None: return None + + isCredentialAsk = OrchestratorIsCredentialsAsk() + if isCredentialAsk: + if inAuthTokenStr is None: raise ConnectionError("Не удается получить токен для авторизации") + else: + if inAuthTokenStr is None: return None inGS = GSettingsGet() # Get the global settings return inGS.get("ServerDict", {}).get("AccessUsers", {}).get("AuthTokensDict", {}).get(inAuthTokenStr, {}).get("Domain", None) - def WebUserInfoGet(inAuthTokenStr=None): """L+,W+: Информация о пользователе, который отправил HTTP запрос. :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя :return: Сведения в формате {"DomainUpperStr": "PYOPENRPA", "UserNameUpperStr": "IVAN.MASLOV"} """ + try: lResultDict = { "DomainUpperStr": WebUserDomainGet(inAuthTokenStr=inAuthTokenStr).upper(), @@ -1109,6 +1126,7 @@ def WebUserIsSuperToken(inAuthTokenStr: str=None): :type inAuthTokenStr: str, опционально :return: True - является супертокеном; False - не является супертокеном; None - авторизация не производилась """ + if inAuthTokenStr is None: return None inGSettings = GSettingsGet() # Get the global settings lIsSuperTokenBool = False @@ -1123,7 +1141,13 @@ def WebUserUACHierarchyGet(inAuthTokenStr: str=None) -> dict: :type inAuthTokenStr: str, опционально :return: UAC словарь доступа или {}, что означает полный доступ """ - if inAuthTokenStr is None: return {} + + isCredentialAsk = OrchestratorIsCredentialsAsk() + if isCredentialAsk: + if inAuthTokenStr is None: raise ConnectionError("Не удается получить токен для авторизации") + else: + if inAuthTokenStr is None: return {} + lDomainUpperStr = WebUserDomainGet(inAuthTokenStr=inAuthTokenStr).upper() lUserUpperStr = WebUserLoginGet(inAuthTokenStr=inAuthTokenStr).upper() if lUserUpperStr is None: return {} @@ -1137,7 +1161,14 @@ def WebUserUACCheck(inAuthTokenStr:str=None, inKeyList:list=None) -> bool: :return: True - доступ имеется, False - доступа нет :rtype: bool """ - if inAuthTokenStr is None: return True # Если авторизации не происходило - супердоступ + + isCredentialAsk = OrchestratorIsCredentialsAsk() + # Если авторизации не происходило - супердоступ + if isCredentialAsk: + if inAuthTokenStr is None: return False + else: + if inAuthTokenStr is None: return True + lResult = True # Init flag lRoleHierarchyDict = WebUserUACHierarchyGet(inAuthTokenStr=inAuthTokenStr) # get the Hierarchy # Try to get value from key list diff --git a/Sources/pyOpenRPA/Robot/UIDesktop.py b/Sources/pyOpenRPA/Robot/UIDesktop.py index 73142128..c02a38d9 100755 --- a/Sources/pyOpenRPA/Robot/UIDesktop.py +++ b/Sources/pyOpenRPA/Robot/UIDesktop.py @@ -128,123 +128,127 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep inSpecificationList=copy.deepcopy(inSpecificationList) lResultList=[] lChildrenList=[] - #Получить родительский объект если на вход ничего не поступило - if inElement is None: - #сформировать спецификацию на получение элемента - lRootElementSpecification=[inSpecificationList[0]] - lRootElementList=PWASpecification_Get_UIO(lRootElementSpecification) - for lRootItem in lRootElementList: - if lRootItem is not None: - lChildrenList.append(lRootItem.wrapper_object()) - #Елемент на вход поступил - выполнить его анализ - else: - #Получить список элементов - lElementChildrenList=inElement.children() - #Поступил index - точное добавление - if 'index' in inSpecificationList[0]: - if inSpecificationList[0]['index']1: + lFlagGoCheck=False + #Циклический обход по детям, на предмет соответствия всем условиям + for lChildrenItem in lElementChildrenList: + #Обработка глубины depth (рекурсивный вызов для всех детей с занижением индекса глубины) + #По умолчанию значение глубины 1 + if 'depth_end' in inSpecificationList[0]: + if inSpecificationList[0]['depth_end']>1: + #Подготовка новой версии спецификации + lChildrenItemNewSpecificationList=inSpecificationList.copy() + lChildrenItemNewSpecificationList[0]=lChildrenItemNewSpecificationList[0].copy() + lChildrenItemNewSpecificationList[0]["depth_end"]=lChildrenItemNewSpecificationList[0]["depth_end"]-1 + if 'depth_start' in lChildrenItemNewSpecificationList[0]: + lChildrenItemNewSpecificationList[0]["depth_start"]=lChildrenItemNewSpecificationList[0]["depth_start"]-1 + #Циклический вызов для всех детей со скорректированной спецификацией + lResultList.extend(UIOSelector_Get_UIOList(lChildrenItemNewSpecificationList,lChildrenItem,inFlagRaiseException)) + #Фильтрация + #TODO Сделать поддержку этих атрибутов для первого уровня селектора + if lFlagGoCheck: + lFlagAddChild=True + #Фильтрация по title + if 'title' in inSpecificationList[0]: + if lChildrenItem.element_info.name != inSpecificationList[0]["title"]: + lFlagAddChild=False + #Фильтрация по title_re (regexp) + if 'title_re' in inSpecificationList[0]: + if re.fullmatch(inSpecificationList[0]["title_re"],lChildrenItem.element_info.name) is None: + lFlagAddChild=False + #Фильтрация по rich_text + if 'rich_text' in inSpecificationList[0]: + if lChildrenItem.element_info.rich_text != inSpecificationList[0]["rich_text"]: + lFlagAddChild=False + #Фильтрация по rich_text_re (regexp) + if 'rich_text_re' in inSpecificationList[0]: + if re.fullmatch(inSpecificationList[0]["rich_text_re"],lChildrenItem.element_info.rich_text) is None: + lFlagAddChild=False + #Фильтрация по class_name + if 'class_name' in inSpecificationList[0]: + if lChildrenItem.element_info.class_name != inSpecificationList[0]["class_name"]: + lFlagAddChild=False + #Фильтрация по class_name_re (regexp) + if 'class_name_re' in inSpecificationList[0]: + if re.fullmatch(inSpecificationList[0]["class_name_re"],lChildrenItem.element_info.class_name) is None: + lFlagAddChild=False + #Фильтрация по friendly_class_name + if 'friendly_class_name' in inSpecificationList[0]: + if lChildrenItem.friendly_class_name() != inSpecificationList[0]["friendly_class_name"]: + lFlagAddChild=False + #Фильтрация по friendly_class_name_re (regexp) + if 'friendly_class_name_re' in inSpecificationList[0]: + if re.fullmatch(inSpecificationList[0]["friendly_class_name_re"],lChildrenItem.friendly_class_name) is None: + lFlagAddChild=False + #Фильтрация по control_type + if 'control_type' in inSpecificationList[0]: + if lChildrenItem.element_info.control_type != inSpecificationList[0]["control_type"]: + lFlagAddChild=False + #Фильтрация по control_type_re (regexp) + if 'control_type_re' in inSpecificationList[0]: + if re.fullmatch(inSpecificationList[0]["control_type_re"],lChildrenItem.element_info.control_type) is None: + lFlagAddChild=False + #Фильтрация по is_enabled (bool) + if 'is_enabled' in inSpecificationList[0]: + if lChildrenItem.is_enabled()!=inSpecificationList[0]["is_enabled"]: + lFlagAddChild=False + #Фильтрация по is_visible (bool) + if 'is_visible' in inSpecificationList[0]: + if lChildrenItem.is_visible()!=inSpecificationList[0]["is_visible"]: + lFlagAddChild=False + ##### + #Все проверки пройдены - флаг добавления + if lFlagAddChild: + lChildrenList.append(lChildrenItem) + #Выполнить рекурсивный вызов (уменьшение количества спецификаций), если спецификация больше одного элемента + #????????Зачем в условии ниже is not None ??????????? + if len(inSpecificationList)>1 and len(lChildrenList)>0: + #Вызвать рекурсивно функцию получения следующего объекта, если в спецификации есть следующий объект + for lChildElement in lChildrenList: + lResultList.extend(UIOSelector_Get_UIOList(inSpecificationList[1:],lChildElement,inFlagRaiseException)) else: - lFlagGoCheck=True - #Учесть поле depth_start (если указано) - if 'depth_start' in inSpecificationList[0]: - if inSpecificationList[0]["depth_start"]>1: - lFlagGoCheck=False - #Циклический обход по детям, на предмет соответствия всем условиям - for lChildrenItem in lElementChildrenList: - #Обработка глубины depth (рекурсивный вызов для всех детей с занижением индекса глубины) - #По умолчанию значение глубины 1 - if 'depth_end' in inSpecificationList[0]: - if inSpecificationList[0]['depth_end']>1: - #Подготовка новой версии спецификации - lChildrenItemNewSpecificationList=inSpecificationList.copy() - lChildrenItemNewSpecificationList[0]=lChildrenItemNewSpecificationList[0].copy() - lChildrenItemNewSpecificationList[0]["depth_end"]=lChildrenItemNewSpecificationList[0]["depth_end"]-1 - if 'depth_start' in lChildrenItemNewSpecificationList[0]: - lChildrenItemNewSpecificationList[0]["depth_start"]=lChildrenItemNewSpecificationList[0]["depth_start"]-1 - #Циклический вызов для всех детей со скорректированной спецификацией - lResultList.extend(UIOSelector_Get_UIOList(lChildrenItemNewSpecificationList,lChildrenItem,inFlagRaiseException)) - #Фильтрация - #TODO Сделать поддержку этих атрибутов для первого уровня селектора - if lFlagGoCheck: - lFlagAddChild=True - #Фильтрация по title - if 'title' in inSpecificationList[0]: - if lChildrenItem.element_info.name != inSpecificationList[0]["title"]: - lFlagAddChild=False - #Фильтрация по title_re (regexp) - if 'title_re' in inSpecificationList[0]: - if re.fullmatch(inSpecificationList[0]["title_re"],lChildrenItem.element_info.name) is None: - lFlagAddChild=False - #Фильтрация по rich_text - if 'rich_text' in inSpecificationList[0]: - if lChildrenItem.element_info.rich_text != inSpecificationList[0]["rich_text"]: - lFlagAddChild=False - #Фильтрация по rich_text_re (regexp) - if 'rich_text_re' in inSpecificationList[0]: - if re.fullmatch(inSpecificationList[0]["rich_text_re"],lChildrenItem.element_info.rich_text) is None: - lFlagAddChild=False - #Фильтрация по class_name - if 'class_name' in inSpecificationList[0]: - if lChildrenItem.element_info.class_name != inSpecificationList[0]["class_name"]: - lFlagAddChild=False - #Фильтрация по class_name_re (regexp) - if 'class_name_re' in inSpecificationList[0]: - if re.fullmatch(inSpecificationList[0]["class_name_re"],lChildrenItem.element_info.class_name) is None: - lFlagAddChild=False - #Фильтрация по friendly_class_name - if 'friendly_class_name' in inSpecificationList[0]: - if lChildrenItem.friendly_class_name() != inSpecificationList[0]["friendly_class_name"]: - lFlagAddChild=False - #Фильтрация по friendly_class_name_re (regexp) - if 'friendly_class_name_re' in inSpecificationList[0]: - if re.fullmatch(inSpecificationList[0]["friendly_class_name_re"],lChildrenItem.friendly_class_name) is None: - lFlagAddChild=False - #Фильтрация по control_type - if 'control_type' in inSpecificationList[0]: - if lChildrenItem.element_info.control_type != inSpecificationList[0]["control_type"]: - lFlagAddChild=False - #Фильтрация по control_type_re (regexp) - if 'control_type_re' in inSpecificationList[0]: - if re.fullmatch(inSpecificationList[0]["control_type_re"],lChildrenItem.element_info.control_type) is None: - lFlagAddChild=False - #Фильтрация по is_enabled (bool) - if 'is_enabled' in inSpecificationList[0]: - if lChildrenItem.is_enabled()!=inSpecificationList[0]["is_enabled"]: - lFlagAddChild=False - #Фильтрация по is_visible (bool) - if 'is_visible' in inSpecificationList[0]: - if lChildrenItem.is_visible()!=inSpecificationList[0]["is_visible"]: - lFlagAddChild=False - ##### - #Все проверки пройдены - флаг добавления - if lFlagAddChild: - lChildrenList.append(lChildrenItem) - #Выполнить рекурсивный вызов (уменьшение количества спецификаций), если спецификация больше одного элемента - #????????Зачем в условии ниже is not None ??????????? - if len(inSpecificationList)>1 and len(lChildrenList)>0: - #Вызвать рекурсивно функцию получения следующего объекта, если в спецификации есть следующий объект - for lChildElement in lChildrenList: - lResultList.extend(UIOSelector_Get_UIOList(inSpecificationList[1:],lChildElement,inFlagRaiseException)) - else: - lResultList.extend(lChildrenList) - #Условие, если результирующий список пустой и установлен флаг создания ошибки (и inElement is None - не следствие рекурсивного вызова) - if inElement is None and len(lResultList)==0 and inFlagRaiseException: - raise pywinauto.findwindows.ElementNotFoundError("Robot can't find element by the UIOSelector") - return lResultList + lResultList.extend(lChildrenList) + #Условие, если результирующий список пустой и установлен флаг создания ошибки (и inElement is None - не следствие рекурсивного вызова) + if inElement is None and len(lResultList)==0 and inFlagRaiseException: + raise pywinauto.findwindows.ElementNotFoundError("Robot can't find element by the UIOSelector") + return lResultList + except Exception: + if inFlagRaiseException: raise ValueError("Не удается получить UIOList") + else: return [] #old:PywinautoExtElementGet def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException=True):