Система распределения прав пользовательских групп

30 Май
2012

Здравствуйте.
У меня появилась неплохая (ИМХО) идея по реализации системы распределения прав между группами пользователей. Я не очень продвинутый программист, с ООП не знаком и мне нужна помощь гуру, которые смогли бы помочь мне советами. И так:

Теория

Все мы знаем такую вещь как массивы. Их я и решил задействовать в моей «системе».
Не знаю, можно ли назвать это системой, так как реализация очень проста (даже непривычно как-то).

Ситуация такова: на сайте есть объекты, которые будут доступны только определенным группам пользователей. В моем примере это будет группа «Администратор». Каждый такой объект будет иметь свой идентификатор (имя).
Что дальше? А дальше вот что: мы пишем функцию, которой в качестве аргумента будем передавать имя нашего объекта. В моем примере имя объекта будет «admin_edit_button». Далее функция лезет в базу данных, в таблицу, в которой есть такие поля: `obj_id`, `obj_name`. Я назову эту таблицу objects. Функция проверяет наличие строки, в которой obj_name будет равняться переданному функции аргументу, т.е. имени нашего объекта, и выбирает её (если она существует).
В нашей базе данных так же должны присутствовать еще две таблицы:
  • Таблица users, в которой будет поле, содержащее id группы пользователя.
  • Таблица usergroups, в которой будут поля group_id и rights.


Таблица usergroups

В ней то и есть та самая изюминка, которая, по моему мнению, довольно сладкая.
Если быть более точным, то изюминка в поле rights, которое будет содержать список obj_id, перечисленных через запятую. Каждый obj_id соответствует одному obj_name из таблицы objects.

Далее всё просто:
Функция берет значение поля rights из таблицы usergroups и разбивает её на массив функцией explode.
Далее наша функция берет obj_id, соответствующий нашему obj_name и проверяет, есть ли наш obj_id в массиве, полученном из поля rights. Если такой элемент присутствует в массиве, то функция возвращает true. Во всех остальных случаях она возвращает false.

Вот и всё, теперь мы запросто можем использовать нашу функцию в качестве условия.

Теперь перейдем к написанию кода.
Практика

Я не буду детально описывать структуру наших таблиц, сейчас я разберу только нашу функцию.

И так:
Шаг 1: создаем функцию.
function check_rights($obj_name) {
}

Шаг 2: объявляем переменную $user глобальной (у меня $user->data — это массив с данными текущего пользователя).
Наш код становится таким:

function check_rights($obj_name) {
global $user;
}


Шаг 3: ищем наш объект в таблице objects:

$object = mysql_query("SELECT * FROM objects WHERE obj_name='$obj_name'");
$num_rows = mysql_num_rows($object);


И ставим условие:

if($num_rows != 0) {
...
}


Ниже добавляем:
return false;


В итоге у нас получается вот что:

function check_rights($obj_name) {
global $user;
$object = mysql_query("SELECT * FROM objects WHERE obj_name='$obj_name'");
$num_rows = mysql_num_rows($object);
if($num_rows != 0) {
....
}
return false;
}


Шаг 4: проверяем группу пользователя на существование и загоняем данные в массив:

 $group_id = $user->data['group_id'];
$usergroup = mysql_query("SELECT * FROM usergroups WHERE id='$group_id'");
$check_group = mysql_num_rows($usergroup);
$usergroup = mysql_fetch_array($usergroup);


Ставим условие и добавляем ‘return false;’:

if($check_group != 0) {
...
}
return false;


Сейчас наша функция выглядит так:

function check_rights($obj_name) {
global $user;
$object = mysql_query("SELECT * FROM objects WHERE obj_name='$obj_name'");
$num_rows = mysql_num_rows($object);
if($num_rows != 0) {
$group_id = $user->data['group_id'];
$usergroup = mysql_query("SELECT * FROM usergroups WHERE id='$group_id'");
$check_group = mysql_num_rows($usergroup);
$usergroup = mysql_fetch_array($usergroup);
if($check_group != 0) {
...
}
return false;
}
return false;
}


Шаг 5: разбиваем переменную $rights на массив и ищем наш obj_id среди элементов массива:

 $object = mysql_fetch_array($object);
$rights = explode(",", $usergroup['rights']);
if(in_array($object['id'], $rights)) {
return true; // Элемент массива найден
}
return false;


И в итоге получаем такую функцию:

function check_rights($obj_name) {
global $user;
$object = mysql_query("SELECT * FROM objects WHERE obj_name='$obj_name'");
$num_rows = mysql_num_rows($object);
if($num_rows != 0) {
$group_id = $user->data['group_id'];
$usergroup = mysql_query("SELECT * FROM usergroups WHERE id='$group_id'");
$check_group = mysql_num_rows($usergroup);
$usergroup = mysql_fetch_array($usergroup);
if($check_group != 0) {
$object = mysql_fetch_array($object);
$rights = explode(",", $usergroup['rights']);
if(in_array($object['id'], $rights)) {
return true;
}
return false;
}
return false;
}
return false;
}


Если немного подумать, то можно уменьшить кол-во запросов к БД, например, единожды запрашивать поле rights, соответствующее группе пользователя ( делать это вне функции ).

Я далеко не профи и мне очень интересно будет почитать конструктивную критику знающих людей. Так же буду рад если мне помогут упростить и оптимизировать код, предложат свои идеи.

Спасибо за внимание.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх