База данни с различни роли и ниво на достъп

vinsbg

Registered
Здравейте,

Имам задача да направя един бекенд с 4 различни роли и нива за достъп:

1. Super Admin
2. Admin
3. Manager
4. User

Съответно права:

SuperAdmin - пълни права на създаване/редактиране/триене на Admins, Manager, User и разни други неща.

Admin - права създаване/редактиране/триене на Manager, User и някои други неща

Manager - качване на информация от форма

User - качване на информация от форма

Моля, за малко помощ как би изглеждала базата данни и примери при логин как да проверява вече правата т.е. как когато всички имат достъп до файл createAdmin.php само SuperAdmin ще вижда формата за създаване на админ, а другите ще си виждат стандартно съобщение, че нямат права.

Не ми се е налагало до сега да правя това с различните роли и права.. Намерих информация в гугъл, но е малко по адвансед за мен и затова първо искам нещо по-просто и от там да започна да градя.

Благодаря :?:
 
Честно казано за най-оптимален вариант, трябва да кажеш как са ти отделени логически различните действия.

Но най-базовото е да имаш:

Код:
roles таблица:
 - id
 - name

Код:
role_permissions таблица
 - id
 - role_id
 - namespace
 - action
И да кажем ги нареждаш по-следния начин

Ако потребителите ти могат само да публикуват новини:
User role:
Код:
    namespace = news
    action = insert
    namespace = news
    action = update
    namespace = news
    action = delete

И спрямо role-а на потребителя проверяваш на определното място дали има права да направи това действие.

А има и много добри варианти:
http://phprbac.net/ :)
 
Добре да вземем за пример SuperAdmin и Admin.

SuperAdmin има права да създава всички останали групи потребители: Admin, Manager, User.
Admin има права да създава по-ниските от него само: Manager, User

Значи в таблица roles ще имам нещо такова?
roles
1, SuperAdmin
2, Admin
3, Manager
4, User

roles_permissions
1, 1, Admin, create
2, 1, Admin, delete
3, 1, Admin, update
4, 1, Manager, create
5, 1, Manager, delete
6, 1, Manager, update
4, 1, User, create
5, 1, User, delete
6, 1, User, update
4, 2, Manager, create
5, 2, Manager, delete
6, 2, Manager, update
4, 2, User, create
5, 2, User, delete
6, 2, User, update

ако правилно съм разбрал така би трябвало да изглеждат правата на SuperAdmin и Admin?

След това логин формата се логва Admin(не SuperAdmin) и след проверка редиректва към някакъв Dashboard и натисне на 'Създай потребител' той би следвали да вижда само - Manager и User като възможност за създаване?

Може ли пример на страницата след логин и редирект как би изглеждала заявката или проверката, кой се е логнал?
 
Да, точно така.

А за redirect-a след логин, ако имат различни dashboards и линкове, където да бъдат редиректнати, може направо да сложиш в roles таблицата допълнителни полета, които да описват различни атрибути като redirect_path.

Който може да ползваш след като fetch-неш потребителя.
 
Fakeheal каза:
Да, точно така.

А за redirect-a след логин, ако имат различни dashboards и линкове, където да бъдат редиректнати, може направо да сложиш в roles таблицата допълнителни полета, които да описват различни атрибути като redirect_path.

Който може да ползваш след като fetch-неш потребителя.

A принципно има ли смисъл да са различни дашборди? В смисъл не е ли по-добре да е един и в зависимост от правата да се показват различните бутони?

А ако са различни дашборди това означава, че трябва да имам в случая 4 страници за дашборди... за всяка група?
 
Аз ще ти предложа нещо по-семпло, според мен.
Направи си колона role(byte(4)) и оттам примерно 0001 ти е едната роля, 0010 е другата и т.н, ако искаш можеш и с int и тогава задаваш с числа някакви роли и ги проверяваш после в кода с decbin/hex2bin и бит маска можеш да провериш дали потребителя има достъп

Примерно потребителя има role 5, което означава, че може да редактира, създава, изтрива.
Код:
<?php
$canedit = bindec(2);
$role = bindec(5);
if($role & canedit) {//user can edit}


Прегледай и това
http://alanhollis.com/a-quick-guide-to-using-bitmasks-for-permissions-in-php/
 
vinsbg каза:
Fakeheal каза:
Да, точно така.

А за redirect-a след логин, ако имат различни dashboards и линкове, където да бъдат редиректнати, може направо да сложиш в roles таблицата допълнителни полета, които да описват различни атрибути като redirect_path.

Който може да ползваш след като fetch-неш потребителя.

A принципно има ли смисъл да са различни дашборди? В смисъл не е ли по-добре да е един и в зависимост от правата да се показват различните бутони?

А ако са различни дашборди това означава, че трябва да имам в случая 4 страници за дашборди... за всяка група?

Не е задължително, много зависи от това дали ще има много разлики в тези dashboard-и. Ако са прекалено много разликите и трябва да пишеш 1000 ифове, по-добре е да ги изнесеш в отделни логически единици. Ако са малко (2-3 бутона на страница, една форма, etc), мисля, че не е задължително. Може да направиш нещо като:
Код:
<?php

// Да кажем, че това са възможните действия на страницата
$page_actions = [
    'User' => ['create'],
    'Manager' => ['create'],
    'Admin' => ['create' ]
];

//Но потребителя ни няма достъп до Admin Create
$role_permissions = [
    'User' => ['create'],
    'Manager' =>[ 'create']
];

foreach($page_actions as $namespace => $actions) {
    if(isset($role_permissions[$namespace])) {
        foreach($actions as $action) {
            if(in_array($action, $role_permissions[$namespace])) {
                echo '<a href="#">You can '. $action.' '.$namespace. '</a><br />';
            }
        }
    }
}

Това е само идея за логиката. Не трябва да го пишеш всеки път по този начин. Направи си един клас, на който да му подаваш user-a, той да си фетчне пермишъните и да си прави проверки и да връща кое какво може да се прави. :)
 
Разликите наистина ще са в 2-3-4 бутона. Нищо фрапантно .. просто различните групи ще могат да създават различни хора(потребители) и няколко дребни допълнителни неща, като ъплоуд на документ, преглед и даунлоуд.

@lam3r4370, благодаря .. ще погледна и твоя пример..
 
Fakeheal каза:
Код:
<?php

// Да кажем, че това са възможните действия на страницата
$page_actions = [
    'User' => ['create'],
    'Manager' => ['create'],
    'Admin' => ['create' ]
];

//Но потребителя ни няма достъп до Admin Create
$role_permissions = [
    'User' => ['create'],
    'Manager' =>[ 'create']
];

foreach($page_actions as $namespace => $actions) {
    if(isset($role_permissions[$namespace])) {
        foreach($actions as $action) {
            if(in_array($action, $role_permissions[$namespace])) {
                echo '<a href="#">You can '. $action.' '.$namespace. '</a><br />';
            }
        }
    }
}

А как би изглеждал подобен клас? И след това там където искам само инклудвам класа ли?
Примерно имам меню в хедъра. Супер админ има бутони : button, button_1, button_2 . админ ще има: button_1, button_2
За да не правя 2 страници и само да изтрия бутона от едната предполагам там ще трябва да инклудна класа. Как точно?
 
vinsbg каза:
А как би изглеждал подобен клас? И след това там където искам само инклудвам класа ли?
Примерно имам меню в хедъра. Супер админ има бутони : button, button_1, button_2 . админ ще има: button_1, button_2
За да не правя 2 страници и само да изтрия бутона от едната предполагам там ще трябва да инклудна класа. Как точно?

Какво ще кажеш за това:

PHP:
abstract class Menu {

final static loadForUser (User $user) {
    $instance;
    switch($user->role) {
    case 'superAdmin': $instance = new SuperAdminMenu(); break;
    case 'standardAdmin': $instance = new AdminMenu(); break;
    case 'moderator': $instance = new ModeratorMenu(); break;
    case 'standardUser': $instance = new StandardUserMenu(); break;
    default: /* @todo */
    }
    return $instance;
}

}

PHP:
class UserMenu extends Menu { private function __construct() {} }
class ModeratorMenu extends UserMenu { private function __construct(){} }
class AdminMenu extends ModeratorMenu { private function __construct(){} }
class SuperAdminMenu extends AdminMenu { private function __construct(){} }

Класовете ще ги ползваш така:

PHP:
$user = new User(..); // отнякъде идва user
$menu = Menu::loadForUser($user);
$menu->print();

Като метода print() ще го имплементираш във всеки Menu клас .
 

Back
Горе