Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL][PHP] Projekt systemu ACL
mentoos
post
Post #1





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 5.09.2009

Ostrzeżenie: (0%)
-----


Chciałbym napisać swój system ACL. Zastanawiam się jak go zaprojektować by był elastyczny. Bazę danych chcę zaprojektować tak:

acl_resources - zasoby
id | resource

acl_roles -> role
id | role_name

acl_permissions - tabela wiążąca 2 poprzednie, w permission określany jest dostęp lub nie
id | resource_id | role_id | permission

i jeszcze tabela users normalnie wykorzystywana do logowania

Co powinien mieć dobry system ACL?
Czy powinien mieć też możliwość przypisywania uprawnień konkretnemu użytkownikowi?

Ten post edytował mentoos 19.08.2010, 11:41:33
Go to the top of the page
+Quote Post
erix
post
Post #2





Grupa: Moderatorzy
Postów: 15 467
Pomógł: 1451
Dołączył: 25.04.2005
Skąd: Szczebrzeszyn/Rzeszów




Cytat
Czy powinien mieć też możliwość przypisywania uprawnień konkretnemu użytkownikowi?

Oczywiście. Rzadko, ale się przydaje; nie ma sensu tworzenia osobnej grupy dla zmiany tylko jednego uprawnienia.
Go to the top of the page
+Quote Post
mentoos
post
Post #3





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 5.09.2009

Ostrzeżenie: (0%)
-----


W takim razie zrobię też obsługę uprawnień dla konkretnego użytkownika.

Czy struktura bazy, którą dałem pod taki system jest prawidłowa?
Co polecałbyś dorzucić jeszcze?
Go to the top of the page
+Quote Post
phpion
post
Post #4





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Ja w swoim systemie ACL mam 3-poziomowe sprawdzanie uprawnień. Uprawnienia przypisuję na poziomie zasobu, roli użytkownika oraz samego użytkownika. Mam napisaną funkcję w plsql, która dla podanego ID użytkownika zwraca mi listę uprawnień/zakazów. Jeżeli określenie uprawnienia występuje na kilku poziomach (np. dla roli jest odebrane, ale dla samego użytkownika przyznane) to, nadając priorytety uprawnieniom, zwraca wartość końcową (tj. w opisanym przypadku nadanie uprawnienia).

Co jeszcze byłoby przydatne? "Przestrzenie nazw" - tak to nazwałem - czyli po prostu typy zasobów. U mnie generalnie występują 3 typy: action (dla akcji, czyli kliknięcia), field (pozwala/zabrania modyfikacji pola w formularzu oraz w bazie danych - za jednym zamachem) oraz image (wyświetlanie obrazka).

Mając zdefiniowane wspomniane typy zasobów możesz zrobić fajny myk. Ja osobiście pracuję z frameworkiem Kohana i wstrzyknąłem się bezpośrednio w helpery do budowy linków oraz tworzenia formularzy. Dzięki temu już podczas tworzenia linku (helperem html::anchor()) sprawdzam czy użytkownik ma uprawnienia do danej akcji. Jeśli tak - tworzę link, jeśli nie - wyświetlam go jako span class="access_denied". Do tego mam plugin w jQuery, który wszystkie elementy o klasie access_denied wyszarza tj. np. obrazki przekształca do skali szarości. W całości daje to bardzo fajny efekt.
Go to the top of the page
+Quote Post
mentoos
post
Post #5





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 5.09.2009

Ostrzeżenie: (0%)
-----


@phpion

Extra masz zrobiony system ACL. Sam używam Kohan'y, tyle że v3.0 (IMG:style_emoticons/default/smile.gif) . Zastanawiam się też czy nie napisać systemu ACL dla Kohana, ale jest już chyba wersja Kohana ACL dla wersji v3.0.

Jak wygląda struktura bazy danych w Twoim systemie ACL? Podobna do tej co pokazałem?
Go to the top of the page
+Quote Post
phpion
post
Post #6





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Poniżej zrzuty tabel (w kolejności alfabetycznej, nie zakładania - powycinałem ze zrzutu bazy):
  1. CREATE TABLE acl_resource_groups (
  2. id integer NOT NULL,
  3. name character varying(50) NOT NULL,
  4. description text,
  5. priority smallint DEFAULT 0 NOT NULL
  6. );
  7. CREATE TABLE acl_resource_groups_acl_resources (
  8. acl_resource_group_id integer NOT NULL,
  9. acl_resource_id integer NOT NULL,
  10. permission BOOLEAN DEFAULT false NOT NULL
  11. );
  12.  
  13. CREATE TABLE acl_resource_groups_acl_roles (
  14. acl_resource_group_id integer NOT NULL,
  15. acl_role_id integer NOT NULL
  16. );
  17.  
  18. CREATE TABLE acl_resource_groups_auth_users (
  19. acl_resource_group_id integer NOT NULL,
  20. auth_user_id integer NOT NULL
  21. );
  22.  
  23. CREATE TABLE acl_resource_namespaces (
  24. id integer NOT NULL,
  25. name character varying(255) NOT NULL
  26. );
  27.  
  28. CREATE TABLE acl_resources (
  29. id integer NOT NULL,
  30. name character varying(255) NOT NULL,
  31. acl_resource_namespace_id integer NOT NULL,
  32. permission BOOLEAN DEFAULT false NOT NULL
  33. );
  34.  
  35. CREATE TABLE acl_resources_acl_roles (
  36. acl_resource_id integer NOT NULL,
  37. acl_role_id integer NOT NULL,
  38. permission BOOLEAN DEFAULT false NOT NULL
  39. );
  40.  
  41. CREATE TABLE acl_resources_auth_users (
  42. acl_resource_id integer NOT NULL,
  43. auth_user_id integer NOT NULL,
  44. permission BOOLEAN DEFAULT false NOT NULL
  45. );
  46.  
  47. CREATE TABLE acl_roles (
  48. id integer NOT NULL,
  49. name character varying(25) NOT NULL,
  50. priority smallint DEFAULT 0 NOT NULL
  51. );
  52.  
  53. CREATE TABLE acl_roles_auth_users (
  54. auth_user_id integer NOT NULL,
  55. acl_role_id integer NOT NULL
  56. );

Do tego wspomniana funkcja, a do niej potrzebny nowy typ danych:
  1. CREATE TYPE acl_user_resurces_permissions AS (
  2. resource_id integer,
  3. permission BOOLEAN,
  4. level integer
  5. );
  6.  
  7. CREATE FUNCTION f_get_acl_user_resources_permissions(_user_id integer) RETURNS SETOF acl_user_resurces_permissions
  8. AS $$
  9. DECLARE
  10. row record;
  11. BEGIN
  12. FOR row IN
  13. SELECT
  14. DISTINCT ON (resource_id) resource_id, permission, level
  15. FROM
  16. (
  17. -- Pobranie uprawnien przypisanych bezposrednio do uzytkownika (priorytet = 5)
  18. (SELECT
  19. acl_resource_id AS resource_id, permission AS permission, 5 AS level
  20. FROM
  21. acl_resources_auth_users
  22. WHERE
  23. auth_user_id=_user_id)
  24. UNION
  25. -- Pobranie uprawnien przypisanych do grupy ACL uzytkownika (priorytet = 4)
  26. (SELECT
  27. DISTINCT ON (resource_id) b.acl_resource_id AS resource_id, permission AS permission, 4 AS level
  28. FROM
  29. acl_resource_groups_auth_users AS a
  30. JOIN acl_resource_groups_acl_resources b USING (acl_resource_group_id)
  31. JOIN acl_resource_groups c ON (c.id = b.acl_resource_group_id)
  32. WHERE
  33. a.auth_user_id=_user_id
  34. GROUP BY
  35. resource_id, permission, level, priority
  36. ORDER BY
  37. resource_id ASC, c.priority DESC)
  38. UNION
  39. -- Pobranie uprawnien przypisanych do rol uzytkownika (priorytet = 3)
  40. (SELECT
  41. DISTINCT ON (resource_id) b.acl_resource_id AS resource_id, permission AS permission, 3 AS level
  42. FROM
  43. acl_roles_auth_users AS a
  44. JOIN acl_resources_acl_roles b USING (acl_role_id)
  45. JOIN acl_roles c ON (c.id = b.acl_role_id)
  46. WHERE
  47. a.auth_user_id=_user_id
  48. GROUP BY
  49. resource_id, permission, level, priority
  50. ORDER BY
  51. resource_id ASC, c.priority DESC)
  52. UNION
  53. -- Pobranie uprawnien przypisanych do roli ACL uzytkownika (priorytet = 2)
  54. (SELECT
  55. DISTINCT ON (resource_id) c.acl_resource_id AS resource_id, permission AS permission, 2 AS level
  56. FROM
  57. acl_roles_auth_users AS a
  58. JOIN acl_resource_groups_acl_roles AS b USING (acl_role_id)
  59. JOIN acl_resource_groups_acl_resources AS c USING (acl_resource_group_id )
  60. JOIN acl_resource_groups d ON (d.id = b.acl_resource_group_id)
  61. WHERE
  62. a.auth_user_id=_user_id
  63. GROUP BY
  64. resource_id, permission, level, priority
  65. ORDER BY
  66. resource_id ASC, d.priority DESC)
  67. UNION
  68. -- Pobranie uprawnien przypisanych bezposrednio do zasobow (priorytet = 1)
  69. (SELECT
  70. id AS resource_id, permission AS permission, 1 AS level
  71. FROM
  72. acl_resources)
  73. ) AS t
  74. GROUP BY
  75. resource_id, permission, level
  76. ORDER BY
  77. resource_id ASC, level DESC
  78. LOOP
  79. RETURN NEXT row;
  80. END LOOP;
  81. END;
  82. $$
  83. LANGUAGE plpgsql;

(IMG:style_emoticons/default/smile.gif)

PS: Okazuje się jednak, że działa to na 5, a nie 3 poziomach (IMG:style_emoticons/default/smile.gif) hehehe.
Go to the top of the page
+Quote Post
mentoos
post
Post #7





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 5.09.2009

Ostrzeżenie: (0%)
-----


Dzięki. Wezmę się za robotę systemu, bo się bardzo przydaje ogólnie.
Go to the top of the page
+Quote Post
phpowiec84
post
Post #8





Grupa: Zarejestrowani
Postów: 101
Pomógł: 2
Dołączył: 10.12.2010

Ostrzeżenie: (0%)
-----


w jaki sposób należy zmodyfikowac zapytanie do bazy aby działała na MYSQL ?
Go to the top of the page
+Quote Post
gothye
post
Post #9





Grupa: Zarejestrowani
Postów: 702
Pomógł: 65
Dołączył: 16.03.2009

Ostrzeżenie: (0%)
-----


phpion

do czego służy tabela : acl_resource_namespaces , skoro nie jet wykorzystana w zapytaniu SQL
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 23:33