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