File modules/cms/model/Permission.class.php

Last commit: Sat Nov 27 22:28:51 2021 +0100	Jan Dankert	UI-Cleanup for the permission list. Now this is much better for small displays.
1 <?php 2 3 namespace cms\model; 4 5 use cms\base\DB as Db; 6 7 8 /** 9 * A Permssion. 10 * If there are more Permissions for an object, the flags are added. 11 * 12 * @author Jan Dankert 13 */ 14 class Permission extends ModelBase 15 { 16 /** 17 * Permission to read 18 */ 19 const ACL_READ = 1; 20 /** 21 * Permission to write 22 */ 23 const ACL_WRITE = 2; 24 /** 25 * Permission to edit the properties 26 */ 27 const ACL_PROP = 4; 28 /** 29 * Permission to delete 30 */ 31 const ACL_DELETE = 8; 32 /** 33 * Permission to release 34 */ 35 const ACL_RELEASE = 16; 36 /** 37 * Permission to publish 38 */ 39 const ACL_PUBLISH = 32; 40 /** 41 * Permission to create new folders 42 */ 43 const ACL_CREATE_FOLDER = 64; 44 /** 45 * Permission to create files 46 */ 47 const ACL_CREATE_FILE = 128; 48 /** 49 * Permission to create links and urls 50 */ 51 const ACL_CREATE_LINK = 256; 52 /** 53 * Permission to create pages 54 */ 55 const ACL_CREATE_PAGE = 512; 56 /** 57 * Permission to grant permissions 58 */ 59 const ACL_GRANT = 1024; 60 /** 61 * Permission to transmit permissions 62 */ 63 const ACL_TRANSMIT = 2048; 64 65 const ACL_ALL = 4095; 66 67 /** 68 * Permission type: User-related permission 69 */ 70 const TYPE_USER = 1; 71 72 /** 73 * Permission type: Group-related permission 74 */ 75 const TYPE_GROUP = 2; 76 77 /** 78 * Permission type: Permission for authenticated users 79 */ 80 const TYPE_AUTH = 3; 81 82 /** 83 * Permission type: Permission for non-authenticated users (guests) 84 */ 85 const TYPE_GUEST = 4; 86 87 /** 88 * eindeutige ID dieser ACL 89 * @type Integer 90 */ 91 public $aclid; 92 93 94 /** 95 * one of the TYPE_* constants 96 * @var int 97 */ 98 public $type; 99 100 /** 101 * ID des Objektes, f?r das diese Berechtigung gilt 102 * @type Integer 103 */ 104 public $objectid = 0; 105 106 /** 107 * ID des Benutzers 108 * ( = 0 falls die Berechtigung f?r eine Gruppe gilt) 109 * @type Integer 110 */ 111 public $userid = 0; 112 113 /** 114 * ID der Gruppe 115 * ( = 0 falls die Berechtigung f?r einen Benutzer gilt) 116 * @type Integer 117 */ 118 public $groupid = 0; 119 120 /** 121 * ID der Sprache 122 * @type Integer 123 */ 124 public $languageid = 0; 125 126 /** 127 * Name der Sprache 128 * @type String 129 */ 130 public $languagename = ''; 131 132 /** 133 * Es handelt sich um eine Standard-Berechtigung 134 * (Falls false, dann Zugriffs-Berechtigung) 135 * @type Boolean 136 * @deprecated 137 */ 138 public $isDefault = false; 139 140 /** 141 * Name des Benutzers, f?r den diese Berechtigung gilt 142 * @type String 143 */ 144 public $username = ''; 145 146 /** 147 * Name der Gruppe, f?r die diese Berechtigung gilt 148 * @type String 149 */ 150 public $groupname = ''; 151 152 /** 153 * Inhalt lesen (ist immer wahr) 154 * @type Boolean 155 */ 156 public $read = true; 157 158 /** 159 * Contains all permission flags. 160 * This is a bitmask with the class constants ACL_* 161 * 162 * @var int 163 */ 164 private $flags = 0; 165 /** 166 * Inhalt bearbeiten 167 * @type Boolean 168 */ 169 public $write = false; 170 171 /** 172 * Eigenschaften bearbeiten 173 * @type Boolean 174 */ 175 public $prop = false; 176 177 /** 178 * Objekt l?schen 179 * @type Boolean 180 */ 181 public $delete = false; 182 183 /** 184 * Objektinhalt freigeben 185 * @type Boolean 186 */ 187 public $release = false; 188 189 /** 190 * Objekt ver?ffentlichen 191 * @type Boolean 192 */ 193 public $publish = false; 194 195 /** 196 * Unterordner anlegen 197 * @type Boolean 198 */ 199 public $create_folder = false; 200 201 /** 202 * Datei anlegen (bzw. hochladen) 203 * @type Boolean 204 */ 205 public $create_file = false; 206 207 /** 208 * Verknuepfung anlegen 209 * @type Boolean 210 */ 211 public $create_link = false; 212 213 /** 214 * Seite anlegen 215 * @type Boolean 216 */ 217 public $create_page = false; 218 219 /** 220 * Berechtigungen vergeben 221 * @type Boolean 222 */ 223 public $grant = false; 224 225 /** 226 * Berechtigungen an Unterobjekte vererben 227 * @type Boolean 228 */ 229 public $transmit = false; 230 231 232 public $projectid; 233 234 235 /** 236 * Konstruktor. 237 * 238 * @param Integer Acl-ID 239 */ 240 public function __construct( $aclid = 0 ) 241 { 242 if ( $aclid != 0 ) 243 $this->aclid = $aclid; 244 } 245 246 247 /** 248 * Laden einer ACL inklusive Benutzer-, Gruppen- und Sprachbezeichnungen. 249 * Zum einfachen Laden sollte #loadRaw() benutzt werden. 250 */ 251 public function load() 252 { 253 $sql = Db::sql( 'SELECT {{acl}}.*,{{user}}.name as username,{{group}}.name as groupname,{{language}}.name as languagename'. 254 ' FROM {{acl}} '. 255 ' LEFT JOIN {{user}} ON {{user}}.id = {{acl}}.userid '. 256 ' LEFT JOIN {{group}} ON {{group}}.id = {{acl}}.groupid '. 257 ' LEFT JOIN {{language}} ON {{language}}.id = {{acl}}.languageid '. 258 ' WHERE {{acl}}.id={aclid}' ); 259 260 $sql->setInt('aclid',$this->aclid); 261 262 $row = $sql->getRow(); 263 264 $this->setDatabaseRow( $row ); 265 266 if ( intval($this->languageid)==0 ) 267 $this->languagename = \cms\base\Language::lang('ALL_LANGUAGES'); 268 else $this->languagename = $row['languagename']; 269 $this->username = $row['username' ]; 270 $this->groupname = $row['groupname' ]; 271 } 272 273 274 /** 275 * Laden einer ACL (ohne verknuepfte Namen). 276 * Diese Methode ist schneller als #load(). 277 */ 278 public function loadRaw() 279 { 280 $sql = Db::sql( 'SELECT * '. 281 ' FROM {{acl}} '. 282 ' WHERE {{acl}}.id={aclid}' ); 283 284 $sql->setInt('aclid',$this->aclid); 285 286 $row = $sql->getRow(); 287 288 $this->setDatabaseRow( $row ); 289 } 290 291 292 /** 293 * Setzt die Eigenschaften des Objektes mit einer Datenbank-Ergebniszeile. 294 * 295 * @param array row Ergebniszeile aus ACL-Datenbanktabelle 296 */ 297 public function setDatabaseRow( $row ) 298 { 299 $this->aclid = $row['id' ]; 300 $this->type = $row['type']; 301 $this->flags = $row['flags']; 302 303 $this->objectid = intval($row['objectid' ]); 304 $this->languageid = intval($row['languageid']); 305 $this->userid = intval($row['userid' ]); 306 $this->groupid = intval($row['groupid' ]); 307 308 $this->updatePermissionBitsFromFlags(); 309 } 310 311 312 /** 313 * Erzeugt eine Liste aller Berechtigungsbits dieser ACL. 314 * 315 * @return array (Schluessel=Berechtigungstyp, Wert=boolean) 316 */ 317 public function getProperties() 318 { 319 return Array( 'read' => true, 320 'write' => $this->flags & self::ACL_WRITE, 321 'prop' => $this->flags & self::ACL_PROP, 322 'create_folder'=> $this->flags & self::ACL_CREATE_FOLDER, 323 'create_file' => $this->flags & self::ACL_CREATE_FILE, 324 'create_link' => $this->flags & self::ACL_CREATE_LINK, 325 'create_page' => $this->flags & self::ACL_CREATE_PAGE, 326 'delete' => $this->flags & self::ACL_DELETE, 327 'release' => $this->flags & self::ACL_RELEASE, 328 'publish' => $this->flags & self::ACL_PUBLISH, 329 'grant' => $this->flags & self::ACL_GRANT, 330 'transmit' => $this->flags & self::ACL_TRANSMIT, 331 'is_default' => $this->isDefault, 332 'userid' => $this->userid, 333 'username' => $this->username, 334 'groupid' => $this->groupid, 335 'groupname' => $this->groupname, 336 'name' => $this->type==self::TYPE_GROUP?$this->groupname:($this->type==self::TYPE_USER?$this->username:''), 337 'languageid' => $this->languageid, 338 'languagename' => $this->languagename, 339 'objectid' => $this->objectid, 340 'type' => $this->type ); 341 342 } 343 344 345 /** 346 * Erzeugt eine Liste aller möglichen Berechtigungstypen. 347 * 348 * @return 0..n-Array 349 */ 350 public static function getAvailableRights() 351 { 352 return array( 'read', 353 'write', 354 'prop', 355 'create_folder', 356 'create_file', 357 'create_link', 358 'create_page', 359 'delete', 360 'release', 361 'publish', 362 'grant', 363 'transmit' ); 364 365 } 366 367 368 /** 369 * Get the bitmask with all permission flags. 370 * 371 * @return int permission flags as bitmask 372 */ 373 public function getMask() { 374 return $this->flags; 375 } 376 377 378 /** 379 * Erzeugt eine Liste aller gesetzten Berechtigungstypen. 380 * Beispiel: Array (0:'read',1:'write',2:'transmit') 381 * 382 * @return 0..n-Array 383 */ 384 public function getTrueProperties() 385 { 386 $erg = array('read'); 387 if ( $this->write ) $erg[] = 'write'; 388 if ( $this->prop ) $erg[] = 'prop'; 389 if ( $this->create_folder ) $erg[] = 'create_folder'; 390 if ( $this->create_file ) $erg[] = 'create_file'; 391 if ( $this->create_link ) $erg[] = 'create_link'; 392 if ( $this->create_page ) $erg[] = 'create_page'; 393 if ( $this->delete ) $erg[] = 'delete'; 394 if ( $this->release ) $erg[] = 'release'; 395 if ( $this->publish ) $erg[] = 'publish'; 396 if ( $this->grant ) $erg[] = 'grant'; 397 if ( $this->transmit ) $erg[] = 'transmit'; 398 399 return $erg; 400 } 401 402 403 404 /** 405 * ACL unwiderruflich loeschen. 406 */ 407 public function delete() 408 { 409 $sql = Db::sql( 'DELETE FROM {{acl}} '. 410 ' WHERE id = {aclid} '. 411 ' AND objectid= {objectid}' ); 412 413 $sql->setInt('aclid' ,$this->aclid ); 414 $sql->setInt('objectid',$this->objectid); 415 416 $sql->execute(); 417 418 $this->aclid = 0; 419 } 420 421 422 public function save() { 423 // TODO updating the ACL is not implemented. 424 } 425 426 /** 427 * ACL der Datenbank hinzufügen. 428 */ 429 public function add() 430 { 431 $this->updateFlagsFromPermissionBits(); 432 433 // Pruefen, ob die ACL schon existiert 434 $user_comp = intval($this->userid )>0?'={userid}':'IS NULL'; 435 $group_comp = intval($this->groupid )>0?'={groupid}':'IS NULL'; 436 $language_comp = intval($this->languageid)>0?'={languageid}':'IS NULL'; 437 438 $stmt = Db::sql( <<<SQL 439 SELECT id FROM {{acl}} 440 WHERE userid $user_comp AND 441 groupid $group_comp AND 442 languageid $language_comp AND 443 objectid = {objectid} AND 444 flags = {flags} 445 SQL 446 ); 447 448 if ( intval($this->userid) > 0 ) 449 $stmt->setInt ('userid',$this->userid); 450 451 if ( intval($this->groupid) > 0 ) 452 $stmt->setInt ('groupid',$this->groupid); 453 454 if ( intval($this->languageid) > 0 ) 455 $stmt->setInt ('languageid',$this->languageid); 456 457 $stmt->setInt('objectid',$this->objectid); 458 $stmt->setInt('flags' ,$this->flags ); 459 460 461 $aclid = intval($stmt->getOne()); 462 if ( $aclid > 0 ) 463 { 464 // Eine ACL existiert bereits, wir übernehmen diese ID 465 $this->aclid = $aclid; 466 return; 467 } 468 469 470 471 472 $stmt = Db::sql('SELECT MAX(id) FROM {{acl}}'); 473 $this->aclid = intval($stmt->getOne())+1; 474 475 $stmt = Db::sql( <<<SQL 476 INSERT INTO {{acl}} 477 (id,type,userid,groupid,objectid,flags,languageid) 478 VALUES( {aclid},{type},{userid},{groupid},{objectid},{flags},{languageid} ) 479 SQL 480 ); 481 482 $stmt->setInt('aclid' ,$this->aclid ); 483 $stmt->setInt('type' ,$this->type ); 484 485 if ( intval($this->userid) == 0 ) 486 $stmt->setNull('userid'); 487 else 488 $stmt->setInt ('userid',$this->userid); 489 490 if ( intval($this->groupid) == 0 ) 491 $stmt->setNull('groupid'); 492 else 493 $stmt->setInt ('groupid',$this->groupid); 494 495 $stmt->setInt('objectid',$this->objectid); 496 $stmt->setInt('flags' ,$this->flags ); 497 498 if ( intval($this->languageid) == 0 ) 499 $stmt->setNull('languageid'); 500 else 501 $stmt->setInt ('languageid',$this->languageid); 502 503 $stmt->execute(); 504 505 506 } 507 508 /** 509 * Liefert das Projekt-Objekt. 510 * 511 * @return Project 512 * @throws \util\exception\ObjectNotFoundException 513 */ 514 public function getProject() { 515 return Project::create( $this->projectid ); 516 } 517 518 519 public function getName() 520 { 521 return ''; 522 } 523 524 525 public function getId() 526 { 527 return $this->aclid; 528 } 529 530 /** 531 * Sets the boolean properties in this instance. 532 */ 533 protected function updatePermissionBitsFromFlags() 534 { 535 $this->write = $this->flags & self::ACL_WRITE; 536 $this->prop = $this->flags & self::ACL_PROP; 537 $this->create_folder= $this->flags & self::ACL_CREATE_FOLDER; 538 $this->create_file = $this->flags & self::ACL_CREATE_FILE; 539 $this->create_link = $this->flags & self::ACL_CREATE_LINK; 540 $this->create_page = $this->flags & self::ACL_CREATE_PAGE; 541 $this->delete = $this->flags & self::ACL_DELETE; 542 $this->release = $this->flags & self::ACL_RELEASE; 543 $this->publish = $this->flags & self::ACL_PUBLISH; 544 $this->grant = $this->flags & self::ACL_GRANT; 545 $this->transmit = $this->flags & self::ACL_TRANSMIT; 546 } 547 548 549 /** 550 * Calculates the permission flags from the properties. 551 */ 552 protected function updateFlagsFromPermissionBits() 553 { 554 $this->flags = self::ACL_READ; 555 $this->flags += self::ACL_WRITE * intval($this->write ); 556 $this->flags += self::ACL_PROP * intval($this->prop ); 557 $this->flags += self::ACL_CREATE_FOLDER * intval($this->create_folder); 558 $this->flags += self::ACL_CREATE_FILE * intval($this->create_file ); 559 $this->flags += self::ACL_CREATE_LINK * intval($this->create_link ); 560 $this->flags += self::ACL_CREATE_PAGE * intval($this->create_page ); 561 $this->flags += self::ACL_DELETE * intval($this->delete ); 562 $this->flags += self::ACL_RELEASE * intval($this->release ); 563 $this->flags += self::ACL_PUBLISH * intval($this->publish ); 564 $this->flags += self::ACL_GRANT * intval($this->grant ); 565 $this->flags += self::ACL_TRANSMIT * intval($this->transmit ); 566 } 567 568 569 }
Download modules/cms/model/Permission.class.php
History Sat, 27 Nov 2021 22:28:51 +0100 Jan Dankert UI-Cleanup for the permission list. Now this is much better for small displays. Sat, 27 Nov 2021 19:46:57 +0100 Jan Dankert Fix: Removed superfluous permission check. Sun, 7 Mar 2021 00:10:20 +0100 Jan Dankert Refactoring: Hopefully more performance while accessing the database resultsets. Sat, 6 Mar 2021 21:45:42 +0100 Jan Dankert Refactoring: Storing all permission bits in a bitmask value Sat, 6 Mar 2021 02:09:25 +0100 Jan Dankert New: Allow permissions for guests only. Mon, 4 Jan 2021 19:03:18 +0100 Jan Dankert Refactoring: ACL class is renamed to Permission, because most RBAC/DMAC concepts are calling it a permission.