Forums / National / Russian / Тех. поддержка / дожились? или права пользователей

12>>>

esclkm
#1 2010-02-04 17:39
ис покон седа права пользователей абсолютно не поменялись.
таже таблица теже значения - 1 - 255
в практике плагино писательства - если честно это очень неудобно.
обычно это свобится или постоянному sed_auth или запросу с IN
и то и то я не считаю рациональным.
А если надо прочитать права другой группы (пример плагин стена пользователей) тут вообще начинается романтика.
может всетаки лучше эту таблицу упростить до вида
tinyint и граф (R, W, A, D, 1, 2, 3, 4, 5) - 0 недоступно , 1 доступно...

изначальная цель этого явления кратного 8(?) мне непонятна.
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
jcrush
#2 2010-02-04 17:44
Двумя руками за!
SEO блог: http://blog.stfw.ru/
Sergeich
#3 2010-02-04 19:01
Согласен.
Gunslinger
#4 2010-02-04 21:07
Вот это было бы очень полезной доработкой. Запланированная модификация системы прав до возможности их выставлять по отдельному юзеру остается в силе?
Sergey
#5 2010-02-04 23:25
Очень даже против. И вот почему, если переходить к расширению возможностей сotonti, например к системе продаж, к системе многопользовательского владения частями (например информации), придется делать нечто похожее на римское право http://www.allpravo.ru/library/doc2527p/instrum3503/item3604.html владею и распоряжаюсь + наследую. Учитывая характер операции дублирования, то появляется право дублирования. Т.е. фактически вся шкала прав уже занята. По крайней мере, я уже год, как проектирую такую систему. Конечно, это достигается плагинами, но система уже сделана правильно и позволяет применять всю возможную гумму прав на отдельные компоненты и информацию. Например, вы желаете подключить плагин, который предусматривает право платного его использования на ресурсе, следовательно, если вы оплатите работу этого плагина, то для вас будет выставлено право его распоряжения. Вы, решили продать, какую-то часть ресурса в аренду, вот вам право владения.
www.cotonti.mobi
Gunslinger
#6 2010-02-04 23:39
Sergey, тоесть основная причина отказа с вашей точки зрения от такой наработки исключительно в сложности ее реализации? (просто уточняю правильно ли я понял)
Sergey
#7 2010-02-04 23:51
По крайней мере мне не понятна и выборка у esclkm? Вот моя выборка с правами в листе
$guest_read = (isset($cfg['plugin']['userseditpage']['auth_user']))?$cfg['plugin']['userseditpage']['auth_user']:RIGHTS_EMPTY; //переходный переиод
			$guest_read = (($guest_read & $rights_r) ==$rights_r);
			sed_die(empty($sed_cat[$c]['maker']) and !$usr['isadmin']);
			$id_el=$pag['page_id'];
			$link_code=$struc_link['structure_id'].':'.$pag['page_id'];
			$link_code_ex='-'.$struc_link['structure_id'].':'.$pag['page_id'];
			$link_code_want='+'.$struc_link['structure_id'].':'.$pag['page_id'];
			//echo $link_code."=link_code <br/>";
        
			$sql = sed_sql_query("SELECT COUNT(*)  FROM $db_pages
				WHERE (FIND_IN_SET('$c',page_cat)
				OR FIND_IN_SET('$c',page_cat_extending))
				AND (page_state=0 OR page_state=2)
				AND (page_id != $id_el)
				AND (NOT FIND_IN_SET('$link_code',page_cat_extending))
				AND (NOT FIND_IN_SET('$link_code_ex',page_cat_extending))
				AND (NOT FIND_IN_SET('$link_code_want',page_cat_extending))
				AND (page_ownerid = {$usr['id']}
				OR ((page_rights & $rights_r)=$rights_r)
				OR IFNULL(NOT page_rights,('$guest_read')))");
				$totallines = sed_sql_result($sql, 0, 0); //echo "totallines=".$totallines."<br/>";
				$sql = sed_sql_query("SELECT p.*, u.user_name ".$join_ratings_columns."
				FROM $db_pages as p ".$join_ratings_condition."
				LEFT JOIN $db_users AS u ON u.user_id=p.page_ownerid
				WHERE (FIND_IN_SET('$c',page_cat)
				OR FIND_IN_SET('$c',page_cat_extending))
				AND (page_state=0 OR page_state=2)
				AND (page_id != $id_el)
				AND (NOT FIND_IN_SET('$link_code',page_cat_extending))
				AND (NOT FIND_IN_SET('$link_code_ex',page_cat_extending))
				AND (NOT FIND_IN_SET('$link_code_want',page_cat_extending))
				AND (page_ownerid = {$usr['id']}
				OR ((page_rights & $rights_r)=$rights_r)
				OR IFNULL(NOT page_rights,('$guest_read')))
				ORDER BY page_$s $w LIMIT $d,".$cfg['maxrowsperpage']);
www.cotonti.mobi
esclkm
#8 2010-02-04 23:54
не совсем понял - а почему мой вариант не сможет оное реализовать?

и я не нашел позиции или ее не понял с налета - где идет чтение прав?
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
Sergey
#9 2010-02-04 23:58
# Gunslinger : Sergey, тоесть основная причина отказа с вашей точки зрения от такой наработки исключительно в сложности ее реализации? (просто уточняю правильно ли я понял)
Скорее всего не в сложности, сколь в слепом копировании чужих успехов, но не заложенных ресурсов, а результатов текущего момента.
Добавлено 4 Минуты спустя:

Правильно, что не поняли. Это мой, реальный проект, который я сейчас испытываю с правами на все и вся в системе. Действительно, размер программных модулей уже превышает размер движка.
а вот выражение:

$rights_r = 1; //Read - чтение
$guest_read = (($guest_read & $rights_r) ==$rights_r);


есть стандартная операция получения права, когда код прав чего-либо маскируется маской соответствующего права, в данном случае, права на чтение отдельной страницы.
www.cotonti.mobi
Trustmaster
#10 2010-02-05 04:03
Побитовые операции над байтами (0-255) - это не шаманство, а основы информатики. В случае с правами - это способ упаковки матрицы доступа.

Существует две модели политики безопасности:
  1. Избирательная политика безопасности. Как правило, реализуется с помощью матрицы доступа (МД). В такой матрице строки - это объекты, права доступа к которым предоставляются, а столбцы - субъекты, которым предоставляется доступ. На пересечении - права, которые доступны (в примитивном случае - это просто разрешение "да/нет"). Знаменитые ACL (Access Control Lists) - это та же самая МД. В Seditio используется МД, где объект - некая область на сайте, а субъект - это группа пользователей. В ячейках один байт, в котором сжаты все привилегии. Такая модель относительно компактна. Если мы реализуем доступ на уровне каждого пользователя, и на уровне каждого элемента таблиц, и расширяем набор возможных прав, то размер матрицы увеличивается многократно (а именно, в N_пользвателей x N_строк раз). И значительно падает скорость алгоритмов авторизации (предоставления доступа).
  2. Полномочная политика безопасности. Как правило, каждый объект в системе (категория, страница, форум) имеет свою метку критичности (число или токен), которая определяет важность информации. Каждый субъект имеет уровень прозрачности (число или токен), который определяет ширину полномочий. Если коротко, то субъект может получить доступ к объекту, если его уровень прозрачности не ниже метки важности объекта. Другое правило гласит, что субъект может изменять объект, если его текущий уровень безопасности (число от 0 до уровня прозрачности) не выше метки важности объекта. Это позволяет строить строгую иерархию при движении данных.
Реализация комбинированных систем авторизации - не такая уж простая задача алгоритмически, особенно если учесть, что объектов на крупных сайтах сотни тысяч и миллионы. Так что маханием шашкой тут не обойдёшься.

Размышляя над этой проблемой, я однозначно отказался от расширения матрицы доступа (причина выше). Возможно "уточнение" имеющейся матрицы в индивидуальном порядке в качестве исключений (скажем, добавлять новые объекты и субъекты по явному требованию администратора), но тут тоже свои трудности с "массовой" обработкой данных для групп субъектов и объектов. Более интересной выглядит разработка системы, подобой той, что упоминает Sergey, однако меня пугает её сложность и громоздкость.
May the Source be with you!
esclkm
#11 2010-02-05 04:10
все это прекрасно... но расскажи: как обдъединить 2 таблицы?
в тестовом виде я понимаю - но вот как сделать запрос... чтобы проверить есть ли у глуппы права на чтение, а не делать начала - проверку по группам, а потом IN()
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
Sergey
#12 2010-02-05 05:34
Давайте рассмотрим мой вариант нашей функции sed_auth_getvalue из модуля functions.admin.php
function mobil_auth_getvalue($mask)  
{
$mn['0'] = 0;
$mn['R'] = 1;
$mn['W'] = 2;
$mn['L'] = 2;
$mn['1'] = 4;
$mn['2'] = 8;
$mn['3'] = 16;
$mn['4'] = 32;
$mn['5'] = 64;
$mn['A'] = 128;

$masks = str_split($mask);

foreach($mn as $k => $v)
 {
 if (in_array($k, $masks)) { $res += $mn[$k]; }
 }
return($res);
}
Что делает эта функция? Она берет пользовательское обозначение прав и превращает их в компактную форму. Например, $mask =RW, функция str_split превращает входное значение в массив состоящий из двух элементов R и W, другая функция in_array($k, $masks) ищет перебирая массив $mn ассоциативные коды в $masks. В нашем случае это будут коды R и W со значениями $mn['R'] = 1; и $mn['W'] = 2; Найденные значения суммируются. Получится 3. Т.е. число 3 это есть битовое указание на R и W. Обратите внимание, в функции есть и эквивалент $mn['W'] = 2; это $mn['L'] = 2;
Теперь давайте выстроим массив $mn так:

бит 1 $mn['R'] = 1;
бит 2 $mn['W'] = 2;
бит 3 $mn['1'] = 4;
бит 4 $mn['2'] = 8;
бит 5 $mn['3'] = 16;
бит 6 $mn['4'] = 32;
бит 7 $mn['5'] = 64;
бит 8 $mn['A'] = 128;

Для того, чтобы получить значение бита из сгруппированного кода прав (записываемого в поле таблице для строки) необходимо проделать следующую операцию:
$бит = (($код_прав & $маска_бита(ов)) == $маска_бита(ов));

$бит будет иметь, в такой операции два состояния: FALSE или TRUE. Следовательно если маска_бита (например) равна 2, то мы сразу выясним. может ли в данную строку что-либо записано т.е. если W в е правах. Однако можно проверить и сумму прав, достаточно сложить нужные биты. Например RA (имеем право читать и администрировать) этот код будет = 1+128=129.
В MySQL имеется и соответственная функция (6.3.6.1 Битовые функции) функция побитового сложения т.е. &
которая, как раз и предназначена для этих целей: выборке строк соответствующих функции побитового сложения, в нашем случае поиску строк с определенными правами. Эта функция выполняется на самом низком операционном уровне процессора, практически мгновенно. В 3 шага микропроцессора. Придумывать другой механизм, это значит увеличивать количество машинных кодов в сотни (тысячи раз) вместо 3. (я так гипотически, может и 2 шага, все в особенностях куда маска на какой регистр улетела, но это уже не нашего ума дела)
www.cotonti.mobi
esclkm
#13 2010-02-05 05:55
стоп.. стоп.. начало я впринципе освоил и сам когда копаллся в этой функции...
а теперь пример если можно с sql (вот это для меня загадка - начало то я понял давно)))
например выборку техже новостей
ну нас есть 2 подкатегории av - доступная для всех nv - недоступная.
как сделать запрос чтобы бралось то что надо)

Добавлено 3 Минуты спустя:

ну или комментариии к только доступным страницам. с учетом полученныз знаний?
или проще занарее просчитать возможные значение - где есть чтение?
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
Sergey
#14 2010-02-05 06:23
Это как раз и обозначает, что в таблице sed_pages я добавил поле page_rights в котором и записываю код доступа к строке. Обозначив соответственно биты, как нам надо, можно и будет производить такую выборку.

Однако в котонти осуществлен только групповой доступ к категории. Для этого надо сформировать по правам доступа некоторый массив допусти $all_cat, в котором будут перечислены все категории где данный юзер может читать страницы (имеет нужное право доступа). Затем, этот массив превратить в строку типа Len_cat=cat1,cat2,...catn. в MySQL есть замечательная функция
FIND_IN_SET(str,strlist) 
Возвращает значение от 1 до N, 
если строка str присутствует в списке strlist, состоящем из N подстрок. 
Список строк представляет собой строку, состоящую из подстрок, разделенных символами `,'. 
Если первый аргумент представляет собой строку констант, 
а второй является столбцом типа SET, функция FIND_IN_SET() 
оптимизируется для использования двоичной арифметики! Возвращает 0, 
если str отсутствует в списке strlist или если strlist является пустой строкой. 
Если один из аргументов равен NULL, возвращается 0. 
Данная функция не будет корректно работать, 
если первый аргумент содержит символ `,':
в strlist загоняем Len_cat, а str наше поле page_cat . Это я так гипотетически. Следует принять во внимание, что возвращает номер cat из Len_cat

Добавлено 17 Минут спустя:

Кстати в функции function sed_auth($area, $option, $mask = 'RWA') есть замечательный фрагмент:
			if(is_array($usr['auth'][$area]))
			{
				foreach($usr['auth'][$area] as $k => $g)
				{
					$cnt += (($g & $mn[$ml]) == $mn[$ml]);
				}
			}
где как раз можно и подобрать эти категории $area.
Как быть со всей толпой, соответственно и для толпы есть категория гость.
www.cotonti.mobi
This post was edited by Sergey (2010-02-05 06:45, 15 years ago)
Trustmaster
#15 2010-02-05 16:19
# esclkm : стоп.. стоп.. начало я впринципе освоил и сам когда копаллся в этой функции...
а теперь пример если можно с sql (вот это для меня загадка - начало то я понял давно)))
например выборку техже новостей
ну нас есть 2 подкатегории av - доступная для всех nv - недоступная.
как сделать запрос чтобы бралось то что надо)

Добавлено 3 Минуты спустя:

ну или комментариии к только доступным страницам. с учетом полученныз знаний?
или проще занарее просчитать возможные значение - где есть чтение?
Допустим, нам известны $groupids пользователя и $c категории, тогда:
SELECT * FROM
	sed_pages AS pg
		LEFT JOIN sed_auth AS a
			ON (a.auth_code = 'page' AND a.auth_option = '{$c}')
	WHERE
		pg.page_cat = '{$c}' AND a.auth_groupid IN ({$groupids}) AND a.auth_rights & {$mn['R']} = {$mn['R']}
	GROUP BY pg.page_id;
Но надо сказать, запрос довольно тяжёлый для базы.
May the Source be with you!

12>>>