Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [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
 
Start new topic
Odpowiedzi
phpion
post
Post #2





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

Posty w temacie


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: 8.10.2025 - 01:01