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->id(); 59 60 $user_tok = trim($_GET['t']); 61 if ($this->model->authentication_tokenFactory->get_token($page_id) == $user_tok) { 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 //virtual columns 137 $acl['participants'] = BEZ_PERMISSION_NONE; 138 139 //BEZ_AUTH_VIEWER is also token viewer 140 if ($this->level >= BEZ_AUTH_VIEWER) { 141 //user can display everythig 142 $acl = array_map(function($value) { 143 return BEZ_PERMISSION_VIEW; 144 }, $acl); 145 } 146 147 if ($this->level >= BEZ_AUTH_ADMIN) { 148 //user can edit everythig 149 $acl = array_map(function($value) { 150 return BEZ_PERMISSION_DELETE; 151 }, $acl); 152 153 return $acl; 154 } 155 } 156 157 //if user can chante id => he can delete record 158 private function check_task($task) { 159 $acl = $this->static_task(); 160 161 //we create new task 162 if ($task->id === NULL) { 163 164 if ($task->coordinator == $this->model->user_nick || 165 ($task->thread_id == '' && $this->level >= BEZ_AUTH_LEADER)) { 166 $acl['content'] = BEZ_PERMISSION_CHANGE; 167 $acl['task_program_id'] = BEZ_PERMISSION_CHANGE; 168 $acl['assignee'] = BEZ_PERMISSION_CHANGE; 169 $acl['cost'] = BEZ_PERMISSION_CHANGE; 170 $acl['plan_date'] = BEZ_PERMISSION_CHANGE; 171 $acl['all_day_event'] = BEZ_PERMISSION_CHANGE; 172 $acl['start_time'] = BEZ_PERMISSION_CHANGE; 173 $acl['finish_time'] = BEZ_PERMISSION_CHANGE; 174 } 175 176 //przypisujemy zadanie programowe samemu sobie 177 //no assignee 178 if ($task->thread_id == '') { 179 $acl['content'] = BEZ_PERMISSION_CHANGE; 180 $acl['task_program_id'] = BEZ_PERMISSION_CHANGE; 181 $acl['cost'] = BEZ_PERMISSION_CHANGE; 182 $acl['plan_date'] = BEZ_PERMISSION_CHANGE; 183 $acl['all_day_event'] = BEZ_PERMISSION_CHANGE; 184 $acl['start_time'] = BEZ_PERMISSION_CHANGE; 185 $acl['finish_time'] = BEZ_PERMISSION_CHANGE; 186 } 187 188 return $acl; 189 } 190 191 //user can change state 192// if ($task->assignee == $this->model->user_nick) { 193//// $acl['reason'] = BEZ_PERMISSION_CHANGE; 194// $acl['state'] = BEZ_PERMISSION_CHANGE; 195// } 196 197 //reporters can add subscribents to programme task 198// if ($task->original_poster === $this->model->user_nick) { 199// $acl['subscribents'] = BEZ_PERMISSION_CHANGE; 200// } 201 202 if ($task->coordinator == $this->model->user_nick || 203 ($task->thread_id == '' && $this->level >= BEZ_AUTH_LEADER)) { 204 205// $acl['reason'] = BEZ_PERMISSION_CHANGE; 206 //$acl['state'] = BEZ_PERMISSION_CHANGE; 207 208 //we can chante cause 209 $acl['thread_comment_id'] = BEZ_PERMISSION_CHANGE; 210 211 $acl['content'] = BEZ_PERMISSION_CHANGE; 212 $acl['task_program_id'] = BEZ_PERMISSION_CHANGE; 213 $acl['assignee'] = BEZ_PERMISSION_CHANGE; 214 $acl['cost'] = BEZ_PERMISSION_CHANGE; 215 //$acl['reason'] = BEZ_PERMISSION_CHANGE; 216 $acl['plan_date'] = BEZ_PERMISSION_CHANGE; 217 $acl['all_day_event'] = BEZ_PERMISSION_CHANGE; 218 $acl['start_time'] = BEZ_PERMISSION_CHANGE; 219 $acl['finish_time'] = BEZ_PERMISSION_CHANGE; 220 221 222 //leaders can add subscribents to programme tasks 223 //$acl['subscribents'] = BEZ_PERMISSION_CHANGE; 224 } 225 226 if ($task->thread_id == '' && 227 $task->original_poster == $this->model->user_nick && 228 $task->assignee == $this->model->user_nick) { 229 //$acl['reason'] = BEZ_PERMISSION_CHANGE; 230 //$acl['state'] = BEZ_PERMISSION_CHANGE; 231 232 $acl['content'] = BEZ_PERMISSION_CHANGE; 233 $acl['task_program_id'] = BEZ_PERMISSION_CHANGE; 234 //no executor 235 $acl['cost'] = BEZ_PERMISSION_CHANGE; 236 //$acl['reason'] = BEZ_PERMISSION_CHANGE; 237 $acl['plan_date'] = BEZ_PERMISSION_CHANGE; 238 $acl['all_day_event'] = BEZ_PERMISSION_CHANGE; 239 $acl['start_time'] = BEZ_PERMISSION_CHANGE; 240 $acl['finish_time'] = BEZ_PERMISSION_CHANGE; 241 } 242 243 244 return $acl; 245 246 } 247 248 private function static_thread_comment() { 249 $acl = array_fill_keys(Thread_comment::get_columns(), BEZ_PERMISSION_NONE); 250 251 //virtual columns 252 253 //BEZ_AUTH_VIEWER is also token viewer 254 if ($this->level >= BEZ_AUTH_VIEWER) { 255 //user can display everythig 256 $acl = array_map(function($value) { 257 return BEZ_PERMISSION_VIEW; 258 }, $acl); 259 } 260 261 if ($this->level >= BEZ_AUTH_ADMIN) { 262 //user can edit everythig 263 $acl = array_map(function($value) { 264 return BEZ_PERMISSION_DELETE; 265 }, $acl); 266 267 return $acl; 268 } 269 } 270 271 private function check_thread_comment(Thread_comment $thread_comment) { 272 $acl = $this->static_thread_comment(); 273 274 //we create new commcause 275 if ($thread_comment->id === NULL) { 276 if ($this->level >= BEZ_AUTH_USER) { 277 $acl['content'] = BEZ_PERMISSION_CHANGE; 278 } 279 280 if ($thread_comment->coordinator === $this->model->user_nick) { 281 $acl['type'] = BEZ_PERMISSION_CHANGE; 282 $acl['content'] = BEZ_PERMISSION_CHANGE; 283 } 284 285 return $acl; 286 } 287 288 289 if ($thread_comment->coordinator === $this->model->user_nick) { 290 $acl['type'] = BEZ_PERMISSION_CHANGE; 291 $acl['content'] = BEZ_PERMISSION_CHANGE; 292 293 //we can only delete records when there is no tasks subscribed to issue 294 if ($thread_comment->task_count === 0) { 295 $acl['id'] = BEZ_PERMISSION_CHANGE; 296 } 297 298 } 299 300 //jeżeli ktoś zmieni typ z komentarza na przyczynę, tracimy możliwość edycji 301 if ($thread_comment->author === $this->model->user_nick && 302 $thread_comment->type == '0') { 303 $acl['content'] = BEZ_PERMISSION_CHANGE; 304 305 //we can only delete records when there is no tasks subscribed to issue 306 if ($thread_comment->task_count === 0) { 307 $acl['id'] = BEZ_PERMISSION_CHANGE; 308 } 309 } 310 311 return $acl; 312 313 } 314 315 private function static_label() { 316 $acl = array_fill_keys(Label::get_columns(), BEZ_PERMISSION_NONE); 317 318 if ($this->level >= BEZ_AUTH_USER) { 319 //user can display everythig 320 $acl = array_map(function($value) { 321 return BEZ_PERMISSION_VIEW; 322 }, $acl); 323 } 324 325 if ($this->level >= BEZ_AUTH_ADMIN) { 326 //admin can edit everythig 327 $acl = array_map(function($value) { 328 return BEZ_PERMISSION_DELETE; 329 }, $acl); 330 } 331 332 return $acl; 333 } 334 335 private function check_label(Label $label) { 336 return $this->static_label(); 337 } 338 339 private function static_task_program() { 340 $acl = array_fill_keys(Task_program::get_columns(), BEZ_PERMISSION_NONE); 341 342 if ($this->level >= BEZ_AUTH_USER) { 343 //user can display everythig 344 $acl = array_map(function($value) { 345 return BEZ_PERMISSION_VIEW; 346 }, $acl); 347 } 348 349 if ($this->level >= BEZ_AUTH_ADMIN) { 350 //admin can edit everythig 351 $acl = array_map(function($value) { 352 return BEZ_PERMISSION_DELETE; 353 }, $acl); 354 } 355 356 return $acl; 357 } 358 359 private function check_task_program(Task_program $task_program) { 360 return $this->static_label(); 361 } 362 363 private function static_task_comment() { 364 $acl = array_fill_keys(Task_comment::get_columns(), BEZ_PERMISSION_NONE); 365 366 //BEZ_AUTH_VIEWER is also token viewer 367 if ($this->level >= BEZ_AUTH_VIEWER) { 368 //user can display everythig 369 $acl = array_map(function($value) { 370 return BEZ_PERMISSION_VIEW; 371 }, $acl); 372 } 373 374 if ($this->level >= BEZ_AUTH_ADMIN) { 375 //user can edit everything 376 $acl = array_map(function($value) { 377 return BEZ_PERMISSION_DELETE; 378 }, $acl); 379 380 return $acl; 381 } 382 } 383 384 private function check_task_comment(Task_comment $task_comment) { 385 $acl = $this->static_task_comment(); 386 387 //we create new comment 388 if ($task_comment->id == NULL) { 389 if ($this->level >= BEZ_AUTH_USER) { 390 $acl['content'] = BEZ_PERMISSION_CHANGE; 391 } 392 393 return $acl; 394 } 395 396 397 if ($this->level >= BEZ_AUTH_LEADER) { 398 $acl['id'] = BEZ_PERMISSION_DELETE; 399 $acl['content'] = BEZ_PERMISSION_CHANGE; 400 } 401 402 403 if ($task_comment->author === $this->model->user_nick) { 404 $acl['content'] = BEZ_PERMISSION_CHANGE; 405 $acl['id'] = BEZ_PERMISSION_DELETE; 406 } 407 408 return $acl; 409 410 } 411 412// private function check_tasktype($tasktype) { 413// $acl = array( 414// 'id' => BEZ_PERMISSION_NONE, 415// 'pl' => BEZ_PERMISSION_NONE, 416// 'en' => BEZ_PERMISSION_NONE 417// ); 418// 419// if ($this->level >= BEZ_AUTH_USER) { 420// //user can display everythig 421// $acl = array_map(function($value) { 422// return BEZ_PERMISSION_VIEW; 423// }, $acl); 424// } 425// 426// if ($this->level >= BEZ_AUTH_ADMIN) { 427// //admin can edit everythig 428// $acl = array_map(function($value) { 429// return BEZ_PERMISSION_CHANGE; 430// }, $acl); 431// } 432// 433// return $acl; 434// } 435 436 /*returns array */ 437 public function check(Entity $obj) { 438 $method = 'check_'.$obj->get_table_name(); 439 if (!method_exists($this, $method)) { 440 throw new \Exception('no acl rules set for table: '.$obj->get_table_name()); 441 } 442 return $this->$method($obj); 443 } 444 445 public function check_field(Entity $obj, $field) { 446 $acl = $this->check($obj); 447 448 if (isset($acl[$field])) { 449 return $acl[$field]; 450 } 451 return BEZ_PERMISSION_UNKNOWN; 452 } 453 454 public function check_static($table) { 455 $method = 'static_'.$table; 456 if (!method_exists($this, $method)) { 457 throw new \Exception('no acl rules set for table: '.$table); 458 } 459 return $this->$method($table); 460 } 461 462 public function check_static_field($table, $field) { 463 $acl = $this->check_static($table); 464 return $acl[$field]; 465 } 466 467 468 public function can(Entity $obj, $field, $what=BEZ_PERMISSION_CHANGE) { 469 if ($this->check_field($obj, $field) < $what) { 470 $table = $obj->get_table_name(); 471 $id = $obj->id; 472 throw new PermissionDeniedException('user cannot change field "'.$field.'" in table "'.$table.', rowid: "'.$id.'"'); 473 } 474 } 475} 476