/** * Метод проверяет права на выполнение операций над заданным документом. Проверяются операции 0 - просмотр данных рабочего потока, 1 - запуск рабочего потока, 2 - право изменять документ, 3 - право смотреть документ. * * @param int $operation - операция. * @param int $userId - код пользователя, для которого проверяется право на выполнение операции. * @param string $documentId - код документа, к которому применяется операция. * @param array $arParameters - ассициативный массив вспомогательных параметров. Используется для того, чтобы не рассчитывать заново те вычисляемые значения, которые уже известны на момент вызова метода. Стандартными являются ключи массива DocumentStates - массив состояний рабочих потоков данного документа, WorkflowId - код рабочего потока (если требуется проверить операцию на одном рабочем потоке). Массив может быть дополнен другими произвольными ключами. * @return bool */ function CanUserOperateDocument($operation, $userId, $documentId, $arParameters = array()) { $documentId = trim($documentId); if (strlen($documentId) <= 0) { return false; } $diskId = self::processGetDiskIdByDocId($documentId); if ($diskId !== null) { return self::proxyToDisk(__FUNCTION__, array($operation, $userId, $diskId, $arParameters)); } $userId = intval($userId); global $USER; if ($USER->IsAuthorized() && $USER->GetID() == $userId && CSocNetUser::IsCurrentUserModuleAdmin()) { return true; } if (array_key_exists("IBlockPermission", $arParameters) && false) { if ($arParameters["IBlockPermission"] < "R") { return false; } elseif ($arParameters["IBlockPermission"] >= "W") { return true; } } // Если мы оказались здесь, то либо не указан IBlockPermission, либо IBlockPermission == U // Если нам явно не сказали, а нам нужно, то узнаем код инфоблока, автора элемента, тип хранилища и владельца хранилища if ($documentId > 0 && (!array_key_exists("IBlockId", $arParameters) || !array_key_exists("CreatedBy", $arParameters) || !array_key_exists("OwnerType", $arParameters) || !array_key_exists("OwnerId", $arParameters)) || $operation == CBPWebDavCanUserOperateOperation::ReadDocument) { $db_res = CIBlockElement::GetList(array(), array("ID" => $documentId, "SHOW_NEW" => "Y", "SHOW_HISTORY" => "Y"), false, false, array("ID", "IBLOCK_ID", "CREATED_BY", "IBLOCK_SECTION_ID", "WF_STATUS_ID", "WF_PARENT_ELEMENT_ID")); $arElement = $db_res->Fetch(); if (!$arElement) { return false; } $arParameters["IBlockId"] = $arElement["IBLOCK_ID"]; $arParameters["CreatedBy"] = $arElement["CREATED_BY"]; if (!array_key_exists("OwnerType", $arParameters) || !array_key_exists("OwnerId", $arParameters)) { $dbSectionsChain = CIBlockSection::GetNavChain($arElement["IBLOCK_ID"], $arElement["IBLOCK_SECTION_ID"]); if ($arSect = $dbSectionsChain->Fetch()) { $arParameters["OwnerType"] = intVal($arSect["SOCNET_GROUP_ID"]) > 0 ? "group" : "user"; $arParameters["OwnerId"] = intVal($arSect["SOCNET_GROUP_ID"]) > 0 ? $arSect["SOCNET_GROUP_ID"] : $arSect["CREATED_BY"]; } } $arParameters["Published"] = intVal($arElement["WF_STATUS_ID"]) == 1 && intVal($arElement["WF_PARENT_ELEMENT_ID"]) <= 0 ? "Y" : "N"; } elseif (array_key_exists("DocumentType", $arParameters)) { $res = explode("_", is_array($arParameters["DocumentType"]) ? $arParameters["DocumentType"][2] : $arParameters["DocumentType"]); if (count($res) != 4) { return false; } $arParameters["IBlockId"] = intval($res[1]); $arParameters["OwnerType"] = $res[2]; $arParameters["OwnerId"] = intval($res[3]); } // Если нет необходимых параметров, то возвращаем false if (!in_array($arParameters["OwnerType"], array("user", "group")) || $arParameters["OwnerId"] <= 0 || $arParameters["IBlockId"] <= 0) { return false; // Если пользователь является владельцем хранилища, то возвращаем true } elseif ($arParameters["OwnerType"] == "user" && $arParameters["OwnerId"] == $userId) { return true; } // Если нам явно не сказали, то узнаем права пользователя на инфоблок if (!array_key_exists("IBlockPermission", $arParameters)) { $res = CIBlockWebdavSocnet::GetUserMaxPermission($arParameters["OwnerType"], $arParameters["OwnerId"], $userId, $arParameters["IBlockId"]); $arParameters["IBlockPermission"] = $res["PERMISSION"]; } if (CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_read") < "R") { return false; } elseif ($operation != CBPWebDavCanUserOperateOperation::DeleteDocument && CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") >= "W") { return true; } elseif ($operation == CBPWebDavCanUserOperateOperation::DeleteDocument && CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_delete") >= "X") { return true; } elseif ($operation == CBPWebDavCanUserOperateOperation::ReadDocument && $arParameters["Published"] == "Y") { return true; } // AllUserGroups if (!array_key_exists("AllUserGroups", $arParameters)) { $arParameters["AllUserGroups"] = CIBlockDocumentWebdavSocnet::GetUserGroups($arParameters["DocumentType"], $documentId, $userId); } // Если нам явно не сказали, то узнаем текущие статусы документа if (!array_key_exists("DocumentStates", $arParameters)) { $arParameters["DocumentStates"] = CBPDocument::GetDocumentStates(array("webdav", "CIBlockDocumentWebdavSocnet", "x"), array("webdav", "CIBlockDocumentWebdavSocnet", $documentId)); } if (array_key_exists("WorkflowId", $arParameters)) { if (array_key_exists($arParameters["WorkflowId"], $arParameters["DocumentStates"])) { $arParameters["DocumentStates"] = array($arParameters["WorkflowId"] => $arParameters["DocumentStates"][$arParameters["WorkflowId"]]); } else { return false; } } $arAllowableOperations = CBPDocument::GetAllowableOperations($userId, $arParameters["AllUserGroups"], $arParameters["DocumentStates"]); // $arAllowableOperations == null - поток не является автоматом // $arAllowableOperations == array() - в автомате нет допустимых операций // $arAllowableOperations == array("read", ...) - допустимые операции if (!is_array($arAllowableOperations)) { return false; } $r = false; switch ($operation) { case CBPWebDavCanUserOperateOperation::ViewWorkflow: // право на просмотр бизнес-процесса есть только у пользователей, которым разрешено читать $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_read") >= "U" && !empty($arAllowableOperations); break; case CBPWebDavCanUserOperateOperation::StartWorkflow: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_bizproc_start") > "U" || in_array("write", $arAllowableOperations); break; case CBPWebDavCanUserOperateOperation::CreateWorkflow: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") > "U"; break; case CBPWebDavCanUserOperateOperation::WriteDocument: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") > "U" || in_array("write", $arAllowableOperations); break; case CBPWebDavCanUserOperateOperation::DeleteDocument: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_delete") >= "X" || in_array("delete", $arAllowableOperations); break; case CBPWebDavCanUserOperateOperation::ReadDocument: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") > "U" || in_array("read", $arAllowableOperations) || in_array("write", $arAllowableOperations); break; default: $r = false; } return $r; }
/** * Метод проверяет права на выполнение операций над документами заданного * типа. Проверяются операции 4 - право изменять шаблоны рабочий потоков для * данного типа документа. * * @param int $operation - операция. * @param int $userId - код пользователя, для которого проверяется право на выполнение операции. * @param string $documentId - код типа документа, к которому применяется операция. * @param array $arParameters - ассициативный массив вспомогательных * параметров. Используется для того, чтобы не рассчитывать заново те * вычисляемые значения, которые уже известны на момент вызова метода. * Стандартными являются ключи массива DocumentStates - массив состояний * рабочих потоков данного документа, WorkflowId - код рабочего потока (если * требуется проверить операцию на одном рабочем потоке). Массив может быть * дополнен другими произвольными ключами. * @return bool */ function CanUserOperateDocumentType($operation, $userId, $documentType, $arParameters = array()) { $documentType = trim($documentType); if (strlen($documentType) <= 0) { return false; } if ($storage = self::needProxyToDiskByDocType($documentType)) { return self::proxyToDisk(__FUNCTION__, array($operation, $userId, \Bitrix\Disk\BizProcDocumentCompatible::generateDocumentType($storage->getId()), $arParameters)); } $iblockId = intval(substr($documentType, strlen("iblock_"))); if ($iblockId <= 0) { throw new CBPArgumentOutOfRangeException("documentType", $documentType); } $arParameters["IBlockId"] = intval(substr($documentType, strlen("iblock_"))); // Если нам явно не сказали, то узнаем инфоблочные права if (!array_key_exists("IBlockPermission", $arParameters)) { if (isset($arParameters['SectionId'])) { $arParameters['SectionId'] = intval($arParameters['SectionId']); $arParameters["IBlockPermission"] = CIBlockDocumentWebdav::GetIBRights('SECTION', $arParameters["IBlockId"], $arParameters['SectionId']); } else { $arParameters["IBlockPermission"] = CIBlockDocumentWebdav::GetIBRights('IBLOCK', $arParameters["IBlockId"]); } } if (CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_read") < "R") { return false; } elseif (CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") >= "W") { return true; } // Если мы тут, то инфоблочные права равны U // Если нам явно не сказали, то узнаем группы пользователя $userId = intval($userId); if (!array_key_exists("AllUserGroups", $arParameters)) { if (!array_key_exists("UserGroups", $arParameters)) { $arParameters["UserGroups"] = CUser::GetUserGroup($userId); } $arParameters["AllUserGroups"] = $arParameters["UserGroups"]; $arParameters["AllUserGroups"][] = "Author"; } // Если нам явно не сказали, то узнаем текущие статусы документа if (!array_key_exists("DocumentStates", $arParameters)) { $arParameters["DocumentStates"] = CBPDocument::GetDocumentStates(array("webdav", "CIBlockDocumentWebdav", "iblock_" . $arParameters["IBlockId"]), null); } // Если нужно проверить только для одного рабочего потока if (array_key_exists("WorkflowId", $arParameters) && !empty($arParameters["WorkflowId"])) { if (array_key_exists($arParameters["WorkflowId"], $arParameters["DocumentStates"])) { $arParameters["DocumentStates"] = array($arParameters["WorkflowId"] => $arParameters["DocumentStates"][$arParameters["WorkflowId"]]); } else { return false; } } $arAllowableOperations = CBPDocument::GetAllowableOperations($userId, $arParameters["AllUserGroups"], $arParameters["DocumentStates"]); // $arAllowableOperations == null - поток не является автоматом // $arAllowableOperations == array() - в автомате нет допустимых операций // $arAllowableOperations == array("read", ...) - допустимые операции if (!is_array($arAllowableOperations)) { return false; } $r = false; switch ($operation) { case CBPCanUserOperateOperation::ViewWorkflow: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_read") > "U" || in_array("read", $arAllowableOperations); break; case CBPCanUserOperateOperation::StartWorkflow: // право на запуск бизнес-процесса есть у имеющих право "W", $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_bizproc_start") > "U" || in_array("write", $arAllowableOperations); // если задан конкретный шаблон потока, то проверяем его if ($r && CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_bizproc_start") <= "U" && $arParameters["WorkflowTemplateId"] > 0) { // Выбираем все шаблоны для того, чтобы определить тип шаблона // так как для последовательных процессов мы даем право на запуск // бизнес-процесса без проверки прав на запись. if (!array_key_exists("WorkflowTemplateList" . $arParameters["IBlockId"], $GLOBALS["WEBDAV"]["CACHE"])) { if (array_key_exists("WorkflowTemplateList", $arParameters)) { $GLOBALS["WEBDAV"]["CACHE"]["WorkflowTemplateList" . $arParameters["IBlockId"]] = array(); foreach ($arParameters["WorkflowTemplateList"] as $res) { $GLOBALS["WEBDAV"]["CACHE"]["WorkflowTemplateList" . $arParameters["IBlockId"]][$res["ID"]] = $res; } } else { $res = array(); $db_res = CBPWorkflowTemplateLoader::GetList(array(), array("DOCUMENT_TYPE" => array("webdav", "CIBlockDocumentWebdav", "iblock_" . $arParameters["IBlockId"]), "ACTIVE" => "Y"), false, false, array("ID", "NAME", "DESCRIPTION", "TEMPLATE", "PARAMETERS")); while ($arWorkflowTemplate = $db_res->GetNext()) { $res[$arWorkflowTemplate["ID"]] = $arWorkflowTemplate; } $GLOBALS["WEBDAV"]["CACHE"]["WorkflowTemplateList" . $arParameters["IBlockId"]] = $res; } } $arWorkflowTemplateList = $GLOBALS["WEBDAV"]["CACHE"]["WorkflowTemplateList" . $arParameters["IBlockId"]]; if (array_key_exists($arParameters["WorkflowTemplateId"], $arWorkflowTemplateList)) { $arTemplate = $arWorkflowTemplateList[$arParameters["WorkflowTemplateId"]]; // Если это машина состояний, то проверяем первое состояние if ($arTemplate["TEMPLATE"][0]["Type"] == "StateMachineWorkflowActivity") { // Выбираем парметры конкретного шаблона рабочего потока if (array_key_exists($arParameters["WorkflowTemplateId"], $arParameters["DocumentStates"])) { $arDocumentStates = $arParameters["DocumentStates"][$arParameters["WorkflowTemplateId"]]; } else { if (!array_key_exists("WorkflowTemplate" . $arParameters["WorkflowTemplateId"], $GLOBALS["WEBDAV"]["CACHE"])) { $GLOBALS["WEBDAV"]["CACHE"]["WorkflowTemplate" . $arParameters["WorkflowTemplateId"]] = CBPWorkflowTemplateLoader::GetTemplateState($arParameters["WorkflowTemplateId"]); } $arDocumentStates = $GLOBALS["WEBDAV"]["CACHE"]["WorkflowTemplate" . $arParameters["WorkflowTemplateId"]]; } $arAllowableOperations = CBPDocument::GetAllowableOperations($userId, $arParameters["AllUserGroups"], array($arParameters["WorkflowTemplateId"] => $arDocumentStates)); $r = is_array($arAllowableOperations) && in_array("write", $arAllowableOperations); } } } break; case CBPCanUserOperateOperation::CreateWorkflow: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") > "U"; break; case CBPCanUserOperateOperation::WriteDocument: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") > "U" || in_array("write", $arAllowableOperations); break; case CBPWebDavCanUserOperateOperation::ReadDocument: $r = CWebDavIblock::CheckRight($arParameters["IBlockPermission"], "element_edit") > "U" || in_array("read", $arAllowableOperations); break; default: $r = false; } return $r; }
continue; } $ID = IntVal($ID); $d = CIBlockElement::GetByID($ID); if ($dr = $d->Fetch()) { if ($_REQUEST["action"] == "restore") { $DB->StartTransaction(); if (!CIBlockElement::WF_Restore($ID)) { $DB->Rollback(); } else { $options = array("element_id" => $arParams["ELEMENT_ID"]); $ob->UNLOCK($options); $DB->Commit(); } } elseif (strlen($dr["WF_PARENT_ELEMENT_ID"]) > 0) { if (CWebDavIblock::CheckRight($arResult["ELEMENT"]["PERMISSION"], "element_edit") < "W" && !($dr["WF_STATUS_ID"] > 1 && $arResult["WF_STATUSES_PERMISSION"][$dr["WF_STATUS_ID"]] >= 2)) { $DB->StartTransaction(); if (!CIBlockElement::Delete(intval($ID))) { $DB->Rollback(); } else { $DB->Commit(); } } } } } $url = isset($_REQUEST['back_url']) ? $_REQUEST['back_url'] : CComponentEngine::MakePathFromTemplate($arParams["~ELEMENT_HISTORY_URL"], array("ELEMENT_ID" => $arParams["ELEMENT_ID"])); LocalRedirect($url); } /******************************************************************** /Action
$popupWindow = new CJSPopup('', ''); if (!CModule::IncludeModule("iblock")) { return false; } elseif (!CModule::IncludeModule("webdav")) { return false; } elseif ($iblock_id <= 0) { $popupWindow->ShowError(GetMessage("WD_IBLOCK_ID_EMPTY")); } $ob = new CWebDavIblock($iblock_id, '/'); if ($ob->e_rights) { $permission = $ob->GetPermission('IBLOCK', $iblock_id); } else { $permission = CIBlock::GetPermission($iblock_id); } $arIBlock = CIBlock::GetArrayByID($iblock_id); if ($ob->CheckRight($permission, 'iblock_rights_edit') < "X" && !$GLOBALS['USER']->CanDoOperation('webdav_change_settings')) { $popupWindow->ShowError(GetMessage("WD_ACCESS_DENIED")); } $bWorkflow = CModule::IncludeModule("workflow"); $bBizproc = CModule::IncludeModule("bizproc"); /******************************************************************** Actions ********************************************************************/ //$GLOBALS["APPLICATION"]->SetFileAccessPermission($_REQUEST["library_FOLDER"], $_REQUEST["library_FOLDER_PERMISSION"]); if ($_SERVER["REQUEST_METHOD"] == "POST") { CUtil::JSPostUnescape(); $ib = new CIBlock(); if (!check_bitrix_sessid()) { $strWarning = GetMessage("WD_ERROR_BAD_SESSID"); } else { $bSetERights = isset($_REQUEST['IB_E_RIGHTS']) && $_REQUEST['IB_E_RIGHTS'] == 'Y';