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