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 check_commcause($commcause) { 278 $acl = array( 279 'id' => BEZ_PERMISSION_NONE, 280 'issue' => BEZ_PERMISSION_NONE, 281 'datetime' => BEZ_PERMISSION_NONE, 282 'reporter' => BEZ_PERMISSION_NONE, 283 'type' => BEZ_PERMISSION_NONE, 284 'content' => BEZ_PERMISSION_NONE, 285 'content_cache' => BEZ_PERMISSION_NONE 286 ); 287 288 if ($this->level >= BEZ_AUTH_VIEWER) { 289 //user can display everythig 290 $acl = array_map(function($value) { 291 return BEZ_PERMISSION_VIEW; 292 }, $acl); 293 } 294 295 if ($this->level >= BEZ_AUTH_ADMIN) { 296 //admin can edit everythig 297 $acl = array_map(function($value) { 298 return BEZ_PERMISSION_CHANGE; 299 }, $acl); 300 301 return $acl; 302 } 303 //we create new commcause 304 if ($commcause->id === NULL) { 305 if ($this->level >= BEZ_USER) { 306 $acl['content'] = BEZ_PERMISSION_CHANGE; 307 } 308 309 if ($commcause->coordinator === $this->model->user_nick) { 310 $acl['type'] = BEZ_PERMISSION_CHANGE; 311 $acl['content'] = BEZ_PERMISSION_CHANGE; 312 } 313 314 return $acl; 315 } 316 317 318 if ($commcause->coordinator === $this->model->user_nick) { 319 $acl['type'] = BEZ_PERMISSION_CHANGE; 320 $acl['content'] = BEZ_PERMISSION_CHANGE; 321 322 //we can only delete records when there is no tasks subscribed to issue 323 if ($commcause->tasks_count === 0) { 324 $acl['id'] = BEZ_PERMISSION_CHANGE; 325 } 326 327 } 328 329 //jeżeli ktoś zmieni typ z komentarza na przyczynę, tracimy możliwość edycji 330 if ($commcause->reporter === $this->model->user_nick && 331 $commcause->type === '0') { 332 $acl['content'] = BEZ_PERMISSION_CHANGE; 333 334 //we can only delete records when there is no tasks subscribed to issue 335 if ($commcause->tasks_count === 0) { 336 $acl['id'] = BEZ_PERMISSION_CHANGE; 337 } 338 } 339 340 return $acl; 341 342 } 343 344 private function static_label() { 345 $acl = array_fill_keys(Label::get_columns(), BEZ_PERMISSION_NONE); 346 347 if ($this->level >= BEZ_AUTH_USER) { 348 //user can display everythig 349 $acl = array_map(function($value) { 350 return BEZ_PERMISSION_VIEW; 351 }, $acl); 352 } 353 354 if ($this->level >= BEZ_AUTH_ADMIN) { 355 //admin can edit everythig 356 $acl = array_map(function($value) { 357 return BEZ_PERMISSION_CHANGE; 358 }, $acl); 359 } 360 361 return $acl; 362 } 363 364 private function check_label(Label $label) { 365 return $this->static_label(); 366 } 367 368 private function check_tasktype($tasktype) { 369 $acl = array( 370 'id' => BEZ_PERMISSION_NONE, 371 'pl' => BEZ_PERMISSION_NONE, 372 'en' => BEZ_PERMISSION_NONE 373 ); 374 375 if ($this->level >= BEZ_AUTH_USER) { 376 //user can display everythig 377 $acl = array_map(function($value) { 378 return BEZ_PERMISSION_VIEW; 379 }, $acl); 380 } 381 382 if ($this->level >= BEZ_AUTH_ADMIN) { 383 //admin can edit everythig 384 $acl = array_map(function($value) { 385 return BEZ_PERMISSION_CHANGE; 386 }, $acl); 387 } 388 389 return $acl; 390 } 391 392 /*returns array */ 393 public function check(Entity $obj) { 394 $method = 'check_'.$obj->get_table_name(); 395 if (!method_exists($this, $method)) { 396 throw new \Exception('no acl rules set for table: '.$obj->get_table_name()); 397 } 398 return $this->$method($obj); 399 } 400 401 public function check_field(Entity $obj, $field) { 402 $acl = $this->check($obj); 403 404 if (isset($acl[$field])) { 405 return $acl[$field]; 406 } 407 return BEZ_PERMISSION_UNKNOWN; 408 } 409 410 public function check_static($table) { 411 $method = 'static_'.$table; 412 if (!method_exists($this, $method)) { 413 throw new \Exception('no acl rules set for table: '.$table); 414 } 415 return $this->$method($table); 416 } 417 418 public function check_static_field($table, $field) { 419 $acl = $this->check_static($table); 420 return $acl[$field]; 421 } 422 423 424 public function can_change(Entity $obj, $field) { 425 if ($this->check_field($obj, $field) < BEZ_PERMISSION_CHANGE) { 426 $table = $obj->get_table_name(); 427 $id = $obj->id; 428 throw new PermissionDeniedException('user cannot change field "'.$field.'" in table "'.$table.', rowid: "'.$id.'"'); 429 } 430 } 431} 432