xref: /plugin/bez/mdl/Acl.php (revision 8a6381983135ed7de69b33e64aa0c1b16dbf69b0)
1<?php
2
3//if(!defined('DOKU_INC')) die('meh.');
4//
5//include_once DOKU_PLUGIN."bez/models/tokens.php";
6
7namespace dokuwiki\plugin\bez\mdl;
8
9//ACL level defines
10use dokuwiki\plugin\bez\meta\PermissionDeniedException;
11
12define('BEZ_AUTH_NONE', 0);
13define('BEZ_AUTH_VIEWER', 2);
14define('BEZ_AUTH_USER', 5);
15define('BEZ_AUTH_LEADER', 10);
16define('BEZ_AUTH_ADMIN', 20);
17
18define('BEZ_PERMISSION_UNKNOWN', -1);
19define('BEZ_PERMISSION_NONE', 0);
20define('BEZ_PERMISSION_VIEW', 1);
21define('BEZ_PERMISSION_CHANGE', 2);
22define('BEZ_PERMISSION_DELETE', 3);
23
24class Acl {
25    /** @var  Model */
26    private $model;
27
28    private $level = BEZ_AUTH_NONE;
29
30//    private $threads = array();
31//    private $commcauses = array();
32//    private $tasks = array();
33
34    private function update_level($level) {
35		if ($level > $this->level) {
36			$this->level = $level;
37		}
38	}
39
40    public function get_level() {
41        return $this->level;
42    }
43
44    public function __construct(Model $model) {
45        $this->model = $model;
46
47		$userd = $this->model->dw_auth->getUserData($this->model->user_nick);
48		if ($userd !== false && is_array($userd['grps'])) {
49			$grps = $userd['grps'];
50			if (in_array('admin', $grps ) || in_array('bez_admin', $grps )) {
51				$this->update_level(BEZ_AUTH_ADMIN);
52            } elseif (in_array('bez_leader', $grps )) {
53                $this->update_level(BEZ_AUTH_LEADER);
54			} else {
55				$this->update_level(BEZ_AUTH_USER);
56			}
57        } elseif (isset($_GET['t'])) {
58//            $page_id = $this->model->action->page_id();
59//            $toko = new Tokens();
60//
61//            if ($toko->check(trim($_GET['t']), $page_id)) {
62//                $this->update_level(BEZ_AUTH_VIEWER);
63//            }
64        }
65    }
66
67    private function static_thread() {
68        $acl = array_fill_keys(Thread::get_columns(), BEZ_PERMISSION_NONE);
69
70        //virtual columns
71        $acl['participants'] = BEZ_PERMISSION_NONE;
72        $acl['labels'] = BEZ_PERMISSION_NONE;
73
74        //BEZ_AUTH_VIEWER is also token viewer
75        if ($this->level >= BEZ_AUTH_VIEWER) {
76            //user can display everythig
77            $acl = array_map(function($value) {
78                return BEZ_PERMISSION_VIEW;
79            }, $acl);
80        }
81
82        if ($this->level >= BEZ_AUTH_ADMIN) {
83            //user can edit everythig
84            $acl = array_map(function($value) {
85                return BEZ_PERMISSION_DELETE;
86            }, $acl);
87
88            return $acl;
89        }
90    }
91
92
93    private function check_thread(Thread $thread) {
94        $acl = $this->static_thread();
95
96        //we create new issue
97        if ($thread->id === NULL) {
98            if ($this->level >= BEZ_AUTH_USER) {
99                $acl['title'] = BEZ_PERMISSION_CHANGE;
100                $acl['content'] = BEZ_PERMISSION_CHANGE;
101                //$acl['type'] = BEZ_PERMISSION_CHANGE;
102            }
103
104            if ($this->level >= BEZ_AUTH_LEADER) {
105                $acl['coordinator'] = BEZ_PERMISSION_CHANGE;
106            }
107
108            return $acl;
109        }
110
111        if ($thread->state === 'proposal' &&
112            $thread->original_poster === $this->model->user_nick) {
113            $acl['title'] = BEZ_PERMISSION_CHANGE;
114            $acl['content'] = BEZ_PERMISSION_CHANGE;
115            //$acl['type'] = BEZ_PERMISSION_CHANGE;
116        }
117
118        if ($thread->coordinator === $this->model->user_nick) {
119            $acl['title'] = BEZ_PERMISSION_CHANGE;
120            $acl['content'] = BEZ_PERMISSION_CHANGE;
121            //$acl['type'] = BEZ_PERMISSION_CHANGE;
122
123            //coordinator can change coordinator
124            $acl['coordinator'] = BEZ_PERMISSION_CHANGE;
125
126            $acl['state'] = BEZ_PERMISSION_CHANGE;
127            //$acl['opinion'] = BEZ_PERMISSION_CHANGE;
128        }
129
130        return $acl;
131    }
132
133    private function static_task() {
134        $acl = array_fill_keys(Task::get_columns(), BEZ_PERMISSION_NONE);
135
136        //BEZ_AUTH_VIEWER is also token viewer
137        if ($this->level >= BEZ_AUTH_VIEWER) {
138            //user can display everythig
139            $acl = array_map(function($value) {
140                return BEZ_PERMISSION_VIEW;
141            }, $acl);
142        }
143
144        if ($this->level >= BEZ_AUTH_ADMIN) {
145            //user can edit everythig
146            $acl = array_map(function($value) {
147                return BEZ_PERMISSION_DELETE;
148            }, $acl);
149
150            return $acl;
151        }
152    }
153
154    //if user can chante id => he can delete record
155    private function check_task($task) {
156        $acl = $this->static_task();
157
158        //we create new task
159        if ($task->id === NULL) {
160
161            if ($task->thread != null && $task->thread->coordinator == $this->model->user_nick ||
162               ($task->thread_id == '' && $this->level >= BEZ_AUTH_LEADER)) {
163                $acl['content'] = BEZ_PERMISSION_CHANGE;
164                $acl['task_program_id'] = BEZ_PERMISSION_CHANGE;
165                $acl['assignee'] = BEZ_PERMISSION_CHANGE;
166                $acl['cost'] = BEZ_PERMISSION_CHANGE;
167                $acl['plan_date'] = BEZ_PERMISSION_CHANGE;
168                $acl['all_day_event'] = BEZ_PERMISSION_CHANGE;
169                $acl['start_time'] = BEZ_PERMISSION_CHANGE;
170                $acl['finish_time'] = BEZ_PERMISSION_CHANGE;
171            }
172
173            //przypisujemy zadanie programowe samemu sobie
174            //no assignee
175            if ($task->thread_id == '') {
176                $acl['content'] = BEZ_PERMISSION_CHANGE;
177                $acl['task_program_id'] = BEZ_PERMISSION_CHANGE;
178                $acl['cost'] = BEZ_PERMISSION_CHANGE;
179                $acl['plan_date'] = BEZ_PERMISSION_CHANGE;
180                $acl['all_day_event'] = BEZ_PERMISSION_CHANGE;
181                $acl['start_time'] = BEZ_PERMISSION_CHANGE;
182                $acl['finish_time'] = BEZ_PERMISSION_CHANGE;
183            }
184
185            return $acl;
186        }
187
188        //user can change state
189//        if ($task->assignee == $this->model->user_nick) {
190////            $acl['reason'] = BEZ_PERMISSION_CHANGE;
191//            $acl['state'] = BEZ_PERMISSION_CHANGE;
192//        }
193
194        //reporters can add subscribents to programme task
195//        if ($task->original_poster === $this->model->user_nick) {
196//            $acl['subscribents'] = BEZ_PERMISSION_CHANGE;
197//        }
198
199        if ($task->thread != null && $task->thread->coordinator == $this->model->user_nick ||
200            ($task->thread_id == '' && $this->level >= BEZ_AUTH_LEADER)) {
201
202//            $acl['reason'] = BEZ_PERMISSION_CHANGE;
203            //$acl['state'] = BEZ_PERMISSION_CHANGE;
204
205            //we can chante cause
206            $acl['thread_comment_id'] =  BEZ_PERMISSION_CHANGE;
207
208            $acl['content'] = BEZ_PERMISSION_CHANGE;
209            $acl['task_program_id'] = BEZ_PERMISSION_CHANGE;
210            $acl['assignee'] = BEZ_PERMISSION_CHANGE;
211            $acl['cost'] = BEZ_PERMISSION_CHANGE;
212            //$acl['reason'] = BEZ_PERMISSION_CHANGE;
213            $acl['plan_date'] = BEZ_PERMISSION_CHANGE;
214            $acl['all_day_event'] = BEZ_PERMISSION_CHANGE;
215            $acl['start_time'] = BEZ_PERMISSION_CHANGE;
216            $acl['finish_time'] = BEZ_PERMISSION_CHANGE;
217
218
219            //leaders can add subscribents to programme tasks
220            //$acl['subscribents'] = BEZ_PERMISSION_CHANGE;
221        }
222
223        if ($task->thread_id == '' &&
224            $task->original_poster == $this->model->user_nick &&
225            $task->assignee == $this->model->user_nick) {
226            //$acl['reason'] = BEZ_PERMISSION_CHANGE;
227            //$acl['state'] = BEZ_PERMISSION_CHANGE;
228
229            $acl['content'] = BEZ_PERMISSION_CHANGE;
230            $acl['task_program_id'] = BEZ_PERMISSION_CHANGE;
231            //no executor
232            $acl['cost'] = BEZ_PERMISSION_CHANGE;
233            //$acl['reason'] = BEZ_PERMISSION_CHANGE;
234            $acl['plan_date'] = BEZ_PERMISSION_CHANGE;
235            $acl['all_day_event'] = BEZ_PERMISSION_CHANGE;
236            $acl['start_time'] = BEZ_PERMISSION_CHANGE;
237            $acl['finish_time'] = BEZ_PERMISSION_CHANGE;
238        }
239
240
241        return $acl;
242
243    }
244
245    private function static_thread_comment() {
246        $acl = array_fill_keys(Thread_comment::get_columns(), BEZ_PERMISSION_NONE);
247
248        //virtual columns
249
250        //BEZ_AUTH_VIEWER is also token viewer
251        if ($this->level >= BEZ_AUTH_VIEWER) {
252            //user can display everythig
253            $acl = array_map(function($value) {
254                return BEZ_PERMISSION_VIEW;
255            }, $acl);
256        }
257
258        if ($this->level >= BEZ_AUTH_ADMIN) {
259            //user can edit everythig
260            $acl = array_map(function($value) {
261                return BEZ_PERMISSION_DELETE;
262            }, $acl);
263
264            return $acl;
265        }
266    }
267
268    private function check_thread_comment(Thread_comment $thread_comment) {
269        $acl = $this->static_thread_comment();
270
271        //we create new commcause
272        if ($thread_comment->id === NULL) {
273            if ($this->level >= BEZ_USER) {
274                $acl['content'] = BEZ_PERMISSION_CHANGE;
275            }
276
277            if ($thread_comment->coordinator === $this->model->user_nick) {
278                $acl['type'] = BEZ_PERMISSION_CHANGE;
279                $acl['content'] = BEZ_PERMISSION_CHANGE;
280            }
281
282            return $acl;
283        }
284
285
286        if ($thread_comment->coordinator === $this->model->user_nick) {
287            $acl['type'] = BEZ_PERMISSION_CHANGE;
288            $acl['content'] = BEZ_PERMISSION_CHANGE;
289
290            //we can only delete records when there is no tasks subscribed to issue
291            if ($thread_comment->task_count === 0) {
292                 $acl['id'] = BEZ_PERMISSION_CHANGE;
293            }
294
295        }
296
297        //jeżeli ktoś zmieni typ z komentarza na przyczynę, tracimy możliwość edycji
298        if ($thread_comment->author === $this->model->user_nick &&
299            $thread_comment->type == '0') {
300            $acl['content'] = BEZ_PERMISSION_CHANGE;
301
302            //we can only delete records when there is no tasks subscribed to issue
303            if ($thread_comment->task_count === 0) {
304                 $acl['id'] = BEZ_PERMISSION_CHANGE;
305            }
306        }
307
308        return $acl;
309
310    }
311
312    private function static_label() {
313        $acl = array_fill_keys(Label::get_columns(), BEZ_PERMISSION_NONE);
314
315        if ($this->level >= BEZ_AUTH_USER) {
316            //user can display everythig
317            $acl = array_map(function($value) {
318                return BEZ_PERMISSION_VIEW;
319            }, $acl);
320        }
321
322        if ($this->level >= BEZ_AUTH_ADMIN) {
323            //admin can edit everythig
324            $acl = array_map(function($value) {
325                return BEZ_PERMISSION_DELETE;
326            }, $acl);
327        }
328
329        return $acl;
330    }
331
332    private function check_label(Label $label) {
333        return $this->static_label();
334    }
335
336   private function check_tasktype($tasktype) {
337        $acl = array(
338            'id'            => BEZ_PERMISSION_NONE,
339            'pl'         => BEZ_PERMISSION_NONE,
340            'en'      => BEZ_PERMISSION_NONE
341        );
342
343        if ($this->level >= BEZ_AUTH_USER) {
344            //user can display everythig
345            $acl = array_map(function($value) {
346                return BEZ_PERMISSION_VIEW;
347            }, $acl);
348        }
349
350        if ($this->level >= BEZ_AUTH_ADMIN) {
351            //admin can edit everythig
352            $acl = array_map(function($value) {
353                return BEZ_PERMISSION_CHANGE;
354            }, $acl);
355        }
356
357        return $acl;
358    }
359
360    /*returns array */
361    public function check(Entity $obj) {
362        $method = 'check_'.$obj->get_table_name();
363        if (!method_exists($this, $method)) {
364            throw new \Exception('no acl rules set for table: '.$obj->get_table_name());
365        }
366        return $this->$method($obj);
367    }
368
369    public function check_field(Entity $obj, $field) {
370        $acl = $this->check($obj);
371
372        if (isset($acl[$field])) {
373            return $acl[$field];
374        }
375        return BEZ_PERMISSION_UNKNOWN;
376    }
377
378    public function check_static($table) {
379        $method = 'static_'.$table;
380        if (!method_exists($this, $method)) {
381            throw new \Exception('no acl rules set for table: '.$table);
382        }
383        return $this->$method($table);
384    }
385
386    public function check_static_field($table, $field) {
387        $acl = $this->check_static($table);
388        return $acl[$field];
389    }
390
391
392    public function can(Entity $obj, $field, $what=BEZ_PERMISSION_CHANGE) {
393        if ($this->check_field($obj, $field) < $what) {
394            $table = $obj->get_table_name();
395            $id = $obj->id;
396            throw new PermissionDeniedException('user cannot change field "'.$field.'" in table "'.$table.', rowid: "'.$id.'"');
397        }
398    }
399}
400