]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/006.schema.permissions.sql
logical division of some data/schema stuff; adding a pkey to the audit tables (easing...
[Evergreen.git] / Open-ILS / src / sql / Pg / 006.schema.permissions.sql
1 DROP SCHEMA permission CASCADE;
2
3 BEGIN;
4 CREATE SCHEMA permission;
5
6 CREATE TABLE permission.perm_list (
7         id              SERIAL  PRIMARY KEY,
8         code            TEXT    NOT NULL UNIQUE,
9         description     TEXT
10 );
11 CREATE INDEX perm_list_code_idx ON permission.perm_list (code);
12
13 CREATE TABLE permission.grp_tree (
14         id                      SERIAL  PRIMARY KEY,
15         name                    TEXT    NOT NULL UNIQUE,
16         parent                  INT     REFERENCES permission.grp_tree (id) ON DELETE RESTRICT,
17         usergroup               BOOL    NOT NULL DEFAULT TRUE,
18         perm_interval           INTERVAL DEFAULT '3 years'::interval NOT NULL,
19         description             TEXT,
20         application_perm        TEXT
21 );
22 CREATE INDEX grp_tree_parent_idx ON permission.grp_tree (parent);
23
24 CREATE TABLE permission.grp_perm_map (
25         id              SERIAL  PRIMARY KEY,
26         grp             INT     NOT NULL REFERENCES permission.grp_tree (id) ON DELETE CASCADE,
27         perm            INT     NOT NULL REFERENCES permission.perm_list (id) ON DELETE CASCADE,
28         depth           INT     NOT NULL,
29         grantable       BOOL    NOT NULL DEFAULT FALSE,
30                 CONSTRAINT perm_grp_once UNIQUE (grp,perm)
31 );
32
33 CREATE TABLE permission.usr_perm_map (
34         id              SERIAL  PRIMARY KEY,
35         usr             INT     NOT NULL REFERENCES actor.usr (id) ON DELETE CASCADE,
36         perm            INT     NOT NULL REFERENCES permission.perm_list (id) ON DELETE CASCADE,
37         depth           INT     NOT NULL,
38         grantable       BOOL    NOT NULL DEFAULT FALSE,
39                 CONSTRAINT perm_usr_once UNIQUE (usr,perm)
40 );
41
42 CREATE TABLE permission.usr_grp_map (
43         id      SERIAL  PRIMARY KEY,
44         usr     INT     NOT NULL REFERENCES actor.usr (id) ON DELETE CASCADE,
45         grp     INT     NOT NULL REFERENCES permission.grp_tree (id) ON DELETE CASCADE,
46                 CONSTRAINT usr_grp_once UNIQUE (usr,grp)
47 );
48
49 CREATE OR REPLACE FUNCTION permission.grp_ancestors ( INT ) RETURNS SETOF permission.grp_tree AS $$
50         SELECT  a.*
51         FROM    connectby('permission.grp_tree','parent','id','name',$1,'100','.')
52                         AS t(keyid text, parent_keyid text, level int, branch text,pos int)
53                 JOIN permission.grp_tree a ON a.id = t.keyid
54         ORDER BY
55                 CASE WHEN a.parent IS NULL
56                         THEN 0
57                         ELSE 1
58                 END, a.name;
59 $$ LANGUAGE SQL STABLE;
60
61 CREATE OR REPLACE FUNCTION permission.usr_perms ( INT ) RETURNS SETOF permission.usr_perm_map AS $$
62         SELECT  DISTINCT ON (usr,perm) *
63           FROM  (
64                         (SELECT * FROM permission.usr_perm_map WHERE usr = $1)
65                                         UNION ALL
66                         (SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
67                           FROM  permission.grp_perm_map p
68                           WHERE p.grp IN (
69                                 SELECT  (permission.grp_ancestors(
70                                                 (SELECT profile FROM actor.usr WHERE id = $1)
71                                         )).id
72                                 )
73                         )
74                                         UNION ALL
75                         (SELECT -p.id, $1 AS usr, p.perm, p.depth, p.grantable
76                           FROM  permission.grp_perm_map p 
77                           WHERE p.grp IN (SELECT (permission.grp_ancestors(m.grp)).id FROM permission.usr_grp_map m WHERE usr = $1))
78                 ) AS x
79           ORDER BY 2, 3, 1 DESC, 5 DESC ;
80 $$ LANGUAGE SQL STABLE;
81
82 CREATE OR REPLACE FUNCTION permission.usr_can_grant_perm ( iuser INT, tperm TEXT, target_ou INT ) RETURNS BOOL AS $$
83 DECLARE
84         r_usr   actor.usr%ROWTYPE;
85         r_perm  permission.usr_perm_map%ROWTYPE;
86 BEGIN
87
88         SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;
89
90         IF r_usr.active = FALSE THEN
91                 RETURN FALSE;
92         END IF;
93
94         IF r_usr.super_user = TRUE THEN
95                 RETURN TRUE;
96         END IF;
97
98
99         FOR r_perm IN   SELECT  *
100                           FROM  permission.usr_perms(iuser) p
101                                 JOIN permission.perm_list l
102                                         ON (l.id = p.perm)
103                           WHERE (l.code = tperm AND p.grantable IS TRUE)
104                 LOOP
105
106                 PERFORM *
107                   FROM  actor.org_unit_descendants(target_ou,r_perm.depth)
108                   WHERE id = r_usr.home_ou;
109
110                 IF FOUND THEN
111                         RETURN TRUE;
112                 ELSE
113                         RETURN FALSE;
114                 END IF;
115         END LOOP;
116
117         RETURN FALSE;
118 END;
119 $$ LANGUAGE PLPGSQL;
120
121 CREATE OR REPLACE FUNCTION permission.usr_has_perm ( iuser INT, tperm TEXT, target_ou INT ) RETURNS BOOL AS $$
122 DECLARE
123         r_usr   actor.usr%ROWTYPE;
124         r_perm  permission.usr_perm_map%ROWTYPE;
125 BEGIN
126
127         SELECT * INTO r_usr FROM actor.usr WHERE id = iuser;
128
129         IF r_usr.active = FALSE THEN
130                 RETURN FALSE;
131         END IF;
132
133         IF r_usr.super_user = TRUE THEN
134                 RETURN TRUE;
135         END IF;
136
137
138         FOR r_perm IN   SELECT  *
139                           FROM  permission.usr_perms(iuser) p
140                                 JOIN permission.perm_list l
141                                         ON (l.id = p.perm)
142                           WHERE l.code = tperm
143                                 OR p.perm = -1 LOOP
144
145                 PERFORM *
146                   FROM  actor.org_unit_descendants(target_ou,r_perm.depth)
147                   WHERE id = r_usr.home_ou;
148
149                 IF FOUND THEN
150                         RETURN TRUE;
151                 ELSE
152                         RETURN FALSE;
153                 END IF;
154         END LOOP;
155
156         RETURN FALSE;
157 END;
158 $$ LANGUAGE PLPGSQL;
159
160 COMMIT;
161