Часть 5. Разделение прав посетителей при помощи механизма ролей
БУС предоставляет широкую систему прав на модули и файлы сайта. В большинстве случаев хватает банальных разрешений типа «Чтение», «Запись», «Изменение», но как нам кажется, в бизнес моделях проще и удобнее использовать Роли. Так сделано, например, в модуле «Поддержка», где введены роли «Клиент поддержки», «Сотрудник поддержки» и «Администратор поддержки». Их смысл намного очевиднее, чем попытка распределить права на «чтение» и «запись» тикетов.
Аналогичным образом попробуем ввести роли для наших гостевых книг. Представляется удобным ввести всего три роли – «Доступ закрыт», «Пользователь» и «Модератор». Названия ролей мы уже описали в файле «ix_guestbook/lang/ru/options.php», а для подключения их в раздел настроек модуля необходимо добавить следующий метод:
function GetModuleRightList()
{
$arr = array(
"reference_id" => array("D","R","W"),
"reference" => array(
GetMessage("IX_GB_DENIED"),
GetMessage("IX_GB_ADD_RECORD"),
GetMessage("IX_GB_MODERATOR"))
);
return $arr;
}
в класс ix_guestbook, описанный в файле «/ix_guestbook/install/index.php». После этих изменений можно будет указывать конкретные роли для отдельных групп пользователей в настройках модуля:
Рис. 4. Распределение прав по ролям.
Для реального использования этих ролей придется делать проверку прав пользователей в своем коде самостоятельно. Поскольку хочется свой код в дальнейшем максимально упростить, мы распишем распределение прав в классе CIX_Guestbook в файле «/ix_guestbook/classes/general/ix_guestbook.php»:
<?
class CIX_Guestbook {
/*****************************************************************
Группа функций по работе с ролями на модуль
Идентификаторы ролей:
D - доступ закрыт
R - пользователь
W - модератор
*****************************************************************/
function GetDeniedRoleID()
{
return "D";
}
function GetUserRoleID()
{
return "R";
}
function GetModeratorRoleID()
{
return "W";
}
// возвращает true если заданный пользователь имеет заданную роль на модуль
function HaveRole($role, $USER_ID=false)
{
global $DB, $USER, $APPLICATION;
if (!is_object($USER)) $USER = new CUser;
if ($USER_ID===false && is_object($USER)) $USER_ID = $USER->GetID();
$USER_ID=intval($USER_ID);
if ($USER_ID>0)
{
$arrGroups = array();
$arrGroups = CUser::GetUserGroup($USER_ID);
if (count($arrGroups)<=0) $arrGroups[] = 2;
$arRoles = $APPLICATION->GetUserRoles("ix_guestbook", $arrGroups);
if (in_array($role, $arRoles)) return true;
}
return false;
}
// true - если пользователь имеет роль "модератор"
// false - в противном случае
function IsModerator($USER_ID=false)
{
if ($USER_ID===false && is_object($USER))
{
if ($USER->IsAdmin()) return true;
}
return CIX_Guestbook::HaveRole(CIX_Guestbook::GetModeratorRoleID(), $USER_ID);
}
// true - если пользователь имеет роль "пользователь"
// false - в противном случае
function IsUser($USER_ID=false)
{
return CIX_Guestbook::HaveRole(CIX_Guestbook::GetUserRoleID(), $USER_ID);
}
// возвращает массив ID групп для которых задана роль
// $role - идентификатор роли
function GetGroupsByRole($role)
{
global $APPLICATION, $USER;
if (!is_object($USER)) $USER = new CUser;
$arGroups = array();
$z = CGroup::GetList($v1, $v2, array("ACTIVE" => "Y"));
while($zr = $z->Fetch())
{
$arRoles = $APPLICATION->GetUserRoles("ix_guestbook", array(intval($zr["ID"])), "Y", "N");
if (in_array($role, $arRoles)) $arGroups[] = intval($zr["ID"]);
}
return array_unique($arGroups);
}
// возвращает массив групп с ролью "модератор"
function GetModeratorGroups()
{
return CIX_Guestbook::GetGroupsByRole(CIX_Guestbook::GetModeratorRoleID());
}
// возвращает массив групп с ролью "пользователь"
function GetUserGroups()
{
return CIX_Guestbook::GetGroupsByRole(CIX_Guestbook::GetUserRoleID());
}
// возвращает массив EMail адресов всех пользователей, имеющих заданную роль
function GetEmailsByRole($role)
{
global $DB, $APPLICATION, $USER;
if (!is_object($USER)) $USER = new CUser;
$arrEMail = array();
$arGroups = CIX_Guestbook::GetGroupsByRole($role);
if (is_array($arGroups) && count($arGroups)>0)
{
$rsUser = CUser::GetList($v1="id", $v2="desc", array("ACTIVE" => "Y", "GROUPS_ID" => $arGroups));
while ($arUser = $rsUser->Fetch()) $arrEMail[$arUser["EMAIL"]] = $arUser["EMAIL"];
}
return array_unique($arrEMail);
}
// возвращает массив EMail'ов всех пользователей, имеющих роль "модератор"
function GetModeratorEmails()
{
return CIX_Guestbook::GetEmailsByRole(CIX_Guestbook::GetModeratorRoleID());
}
}
?>
Смысл кода очевиден, и для своих целей вам понадобится лишь заменить обращения к “ix_guestbook” на свои модули, а также возможно описать свои методы типа function GetModeratorRoleID(), function IsModerator($USER_ID=false), function GetModeratorGroups() и function GetModeratorEmails(). Они все реализуются по методике copy/paste, что не может не радовать.
Теперь в своем коде мы сможем реализовывать проверки прав конкретного пользователя при помощи конструкций вида:
$bModerator = (CIX_Guestbook::IsModerator()) ? "Y" : "N";
$bUser = (CIX_Guestbook::IsUser()) ? "Y" : "N";
if($bModerator!="Y" && $bUser!="Y") $APPLICATION->AuthForm(GetMessage("ACCESS_DENIED"));
Фактически, реализация модуля «Гостевые книги» уже сделана. Нам остается только подготовить компоненты для публичной части сайта, чтобы упростить использование модуля на реальном сайте.