Права пользователей/модераторов

Активист

Активист
Команда форума
в первом посте тс поддерживаю)


почему же все делают роли, классы ACL и т.п., есть же старые добрые бинарные операции (битовые в PHP), 31 (63) превилегия достаточно для любого действия, стандартные битовые операции <<, >>, &, ~ достаточно для ВСЕХ вариаций.

Для хранения информации о правах пользователей достаточно обычное unsigned int (longint) поле.


Если гововорить о форуме (самое большое на мой взгяд разделение прав).

Использую схему битовых операций и правильную ООП архитектуру: root->forums->forum->threads->thread->posts->post

Есть констатны типа
const READ = 0x01;
const WRITE = 0x01 << 1;
const LOCK = 0x01 << 2;
const STICK = 0x01 << 3;
const VOTE = 0x01 << 4;

и пожалуйста, получаете:

A) Глобальные права (админ)
Модертор:
Б) Права на отдельный форум (например, для юзера можно хранить в БД права доступа к разным формам), т.к., юзер заходит в определенный тред
В) Права доступа на темы (глобальные темы) отдельные темы
Г) Можно организовать и права и на определенные сообщения.

В случае опять же правильного ООП, в памяти веб приложения будет храниться максимум 2 атрибута - глобальные права, и текущие права пользователя (в зависимости от того, где он сейчас).

4 байта в бд для одного разграничения прав, это того стоит, скорость бинарных операций естественно большая (1 такт CPU).

В топку все ваши getRole и т.п. ))
 

korchasa

LIMB infected
Активист
Да храни их хоть на отдельном сервисе и получай через корбу. Причем тут хранение?
 

Активист

Активист
Команда форума
korchasa
Я здесь описал все, не только хранение, но и использование, додумаем дальше сами.

Допустим, мы смотрим тред на форуме, объект:

Гараздо удобнее:

PHP:
<?php
class objThread extends threads {
private $posts;
private $REMOVE;

// ..
// Таблица маски прав, можно вынести в базовый класс
// ..
private function setPermissionsMask() {
	$this->VIEW = 0x01 << 1;
        //...
	$this->REMOVE = 0x01 << 4;
}

public function fetch() {
	$return = '';
	
	foreach ($this->posts as $post) {
		$return .= $post->fetch(); // Там аналогично проверяем права
	}
	
	$return .= ($this->userGlobalPermission | $this->userLocalPermission) & $this->REMOVE  ? 'удалить' : 'не удалишь' ;
	}
}

?>
 

Вурдалак

Продвинутый новичок
Автор оригинала: korchasa
Зачем отдельная роль на каждого пользователя?
— у каждого пользователя может быть своя комбинация ролей. Не хранить же все комбинации в БД, когда есть наследование ролей (почти твои слова, кстати). Ну а своё имя во избежание конфликта имён, если вдруг будет два объекта класса User.
 

korchasa

LIMB infected
Ну и в чем преимущество?

-~{}~ 01.10.10 11:10:

Автор оригинала: Вурдалак
— у каждого пользователя может быть своя комбинация ролей. Не хранить же все комбинации в БД, когда есть наследование ролей (почти твои слова, кстати). Ну а своё имя во избежание конфликта имён, если вдруг будет два объекта класса User.
Ты резолвишь пользователя в контексте определенного ресурса, там не может быть ни комбинаций, ни конфликтов. Для конкретного ресурса пользователь имеет только одну роль.
 

Вурдалак

Продвинутый новичок
Автор оригинала: Активист
Для хранения информации о правах пользователей достаточно обычное unsigned int (longint) поле.
— у меня около 100 таких привелегий, т.е. даже bigint не хватает, надо в tinyblob хранить. Заепался, если честно.

-~{}~ 01.10.10 11:21:

Автор оригинала: korchasa
Ты резолвишь пользователя в контексте определенного ресурса, там не может быть ни комбинаций, ни конфликтов. Для конкретного ресурса пользователь имеет только одну роль.
— ты опять про свой RoleResolver интерфейс? Я его не использую.
 

korchasa

LIMB infected
Автор оригинала: Вурдалак — ты опять про свой RoleResolver интерфейс? Я его не использую.
Нет, я про общую логику. Если у тебя есть наследование, то нет смысла в множественности ролей, для отдельного ресурса.
 

Вурдалак

Продвинутый новичок
korchasa, я понятия не имею для какого ресурса вызывается getRole(). Для того или иного. Не понимаю твоей мысли.
 

Активист

Активист
Команда форума
Вурдалак
100 комбинаций? Что-то не так в архитектуре, имхо, либо они у тебя все сверх глобальные и ты не разнес из по объект, либо ооп не ооп.




korchasa
То что над твоим кодом могут работать разные люди, не ты один, и чем более логична и линейнее код, тем лучше, а остальные плюсы я описал выше.

Вот кстати, все разграничение прав, никакой запутанной логики, ясной только автору системы ролей.

<?php
class objThread extends threads {
private $posts;
private $REMOVE;

PHP:
// ..
// Таблица маски прав, можно вынести в базовый класс
// ..
private function setPermissionsMask() {
    $this->VIEW = 0x01 << 1;
        //...
    $this->REMOVE = 0x01 << 4;
}

public function fetch() {
    $return = '';
    
    foreach ($this->posts as $post) {
        $return .= $post->fetch(); // Там аналогично проверяем права
    }
    
    $return .= ($this->userGlobalPermission | $this->userLocalPermission) & $this->REMOVE  ? 'удалить' : 'не удалишь' ;
    }


private function loadCurrentUserPermission() {
	/**
	 * Условный код, для понимание логики.
	 */
	$userId = isset($_SESSION['auth']['userId']) ? $_SESSION['auth']['userId'] : -1;
	
	// далее
	
	$userObj = new users($userId);
	$this->userGlobalPermission = $userObj->getGlobalPermission();
	
	/* условно, например, все права юзера можно записывать в объект текущего юзера, ссылку на который можно хранить в каком-нибудь синглтон объекте  */
	$storageEnenginear = new storage();
	$storageEnenginear->query("SELECT `permission` FROM `permissions` WHERE `userId` = '".(int)$userId."' && `threadId` = '".(int)$this->id."'");
	
	if ($storageEnenginear->isUniqueResult()) {
		// Простое наследование.
		$this->userLocalPermission = $storageEnenginear->field('permission') | $this->parent->userLocalPermission; 
		} else {
			$this->userLocalPermission = 0x01; // default
		}
	}

}
?>


PHP:
 

Вурдалак

Продвинутый новичок
Активист, не 100 комбинаций, а 100 привелегий. Есть портал, где есть чат, форум, файлообменник etc. Пользователи и группы общие. Фишечек много, каждую из них хочется иметь возможность назначать той или иной группе прямо из панели администратора.
 

korchasa

LIMB infected
Активист
Да забудь ты о хранении прав. Отличие твоего подхода только в том, что ресурс возвращает конечный результат. И все. Ты точно так же определяешь права внутри самого ресурса, в зависимости от пользователя. Именно это отсутствует у Вурдалака. Поэтому и big int не хватает.

Вурдалак
Ну собственно отсюда нехватка big int.
 

Активист

Активист
Команда форума
korchasa
Спорить не собираюсь

Вурдалак
Вспомни юниксовое хранение прав, и по аналогии, или же
<?php
// levels
define("READ", 0x01);
define("WRITE", 0x01 << 1);
define("DELETE", 0x01 << 2);

// sections
define("FORUM", 0x01);
define("THREAD", 0x01 << 1);
define("POST", 0x01 << 2);
define("CHAT", 0x01 << 3);
define("BOOK", 0x01 << 4);

// etc
// ...
// ...
?>

-~{}~ 01.10.10 17:02:

> 100 привелегий
Не верю, например?
 

Вурдалак

Продвинутый новичок
Активист, я не понимаю что ты от меня хочешь.

Автор оригинала: Активист
Не верю, например?
— возможность позвать модера в чате, возможность написать жирным, возможность написать курсивом, ..., возможность кикнуть, возможность заблокировать никнейм, возможность забанить по IP, возможность забанить по UserAgent, возможность забанить по связке IP+UserAgent, возможность забанить по маске IP, возможность редактировать данные ботов в чате, возможность создавать голосования, возможность очищать комнаты. Продолжать?
 

Boriso

Новичок
Зачем возвращаться к 1970 году с полномочиями UNIX и битовой маской? Сейчас нет смысла экономить пару байт, тем более в вопросах безопасности.

Есть два различных подхода к проверке прав:
а) Получить роль в рамках некоторого ресурса, а потом уже в коде сравнивать полномочия роли и действие. Например, getRole() вернёт для текущего форума "Moderator", в этом случае всё можно делать.
б) Создавать комбинации "объект+полномочие" и присваивать их пользователям, объединяя роли. В этом случае надо определиться с наследованием (более строгое полномочие на лист перекрывает или нет более широкое на предка) и проверять каждый ресурс с помощью hasRight(<resourse>, <right>), причём сам метод должен правильно подниматься по дереву. Метод можно даже расширить, чтобы он искал по сразу по массиву полномочий. Что касается хранения, то это уже не так важно, можно даже через serialize($rights_hash) хранить в базе.

P.S. Если реализуете с помощью класса, то потом всегда сможете легко переписать всю систему полномочий. Возможно, что такое количество привилегий будет реально использоваться лишь у тестовых пользователей.
 
Сверху