1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26: 27: 28: 29: 30: 31: 32: 33:
34: class AclComponent extends Object {
35: 36: 37: 38: 39: 40:
41: var $_Instance = null;
42: 43: 44: 45:
46: function __construct() {
47: $name = Inflector::camelize(strtolower(Configure::read('Acl.classname')));
48: if (!class_exists($name)) {
49: if (App::import('Component', $name)) {
50: if (strpos($name, '.') !== false) {
51: list($plugin, $name) = explode('.', $name);
52: }
53: $name .= 'Component';
54: } else {
55: trigger_error(sprintf(__('Could not find %s.', true), $name), E_USER_WARNING);
56: }
57: }
58: $this->_Instance =& new $name();
59: $this->_Instance->initialize($this);
60: }
61: 62: 63: 64: 65: 66: 67:
68: function startup(&$controller) {
69: return true;
70: }
71: 72: 73: 74: 75:
76: function _initACL() {
77: }
78: 79: 80: 81: 82: 83: 84: 85: 86:
87: function check($aro, $aco, $action = "*") {
88: return $this->_Instance->check($aro, $aco, $action);
89: }
90: 91: 92: 93: 94: 95: 96: 97: 98:
99: function allow($aro, $aco, $action = "*") {
100: return $this->_Instance->allow($aro, $aco, $action);
101: }
102: 103: 104: 105: 106: 107: 108: 109: 110:
111: function deny($aro, $aco, $action = "*") {
112: return $this->_Instance->deny($aro, $aco, $action);
113: }
114: 115: 116: 117: 118: 119: 120: 121: 122:
123: function inherit($aro, $aco, $action = "*") {
124: return $this->_Instance->inherit($aro, $aco, $action);
125: }
126: 127: 128: 129: 130: 131: 132: 133: 134:
135: function grant($aro, $aco, $action = "*") {
136: return $this->_Instance->grant($aro, $aco, $action);
137: }
138: 139: 140: 141: 142: 143: 144: 145: 146:
147: function revoke($aro, $aco, $action = "*") {
148: return $this->_Instance->revoke($aro, $aco, $action);
149: }
150: }
151: 152: 153: 154: 155: 156: 157: 158:
159: class AclBase extends Object {
160: 161: 162: 163:
164: function __construct() {
165: if (strcasecmp(get_class($this), "AclBase") == 0 || !is_subclass_of($this, "AclBase")) {
166: trigger_error(__("[acl_base] The AclBase class constructor has been called, or the class was instantiated. This class must remain abstract. Please refer to the Cake docs for ACL configuration.", true), E_USER_ERROR);
167: return NULL;
168: }
169: }
170: 171: 172: 173: 174: 175: 176: 177:
178: function check($aro, $aco, $action = "*") {
179: }
180: 181: 182: 183: 184: 185:
186: function initialize(&$component) {
187: }
188: }
189: 190: 191: 192: 193: 194:
195: class DbAcl extends AclBase {
196: 197: 198: 199:
200: function __construct() {
201: parent::__construct();
202: if (!class_exists('AclNode')) {
203: uses('model' . DS . 'db_acl');
204: }
205: $this->Aro =& ClassRegistry::init(array('class' => 'Aro', 'alias' => 'Aro'));
206: $this->Aco =& ClassRegistry::init(array('class' => 'Aco', 'alias' => 'Aco'));
207: }
208: 209: 210: 211: 212: 213: 214:
215: function initialize(&$component) {
216: $component->Aro = $this->Aro;
217: $component->Aco = $this->Aco;
218: }
219: 220: 221: 222: 223: 224: 225: 226: 227:
228: function check($aro, $aco, $action = "*") {
229: if ($aro == null || $aco == null) {
230: return false;
231: }
232:
233: $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
234: $aroPath = $this->Aro->node($aro);
235: $acoPath = $this->Aco->node($aco);
236:
237: if (empty($aroPath) || empty($acoPath)) {
238: trigger_error("DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: " . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
239: return false;
240: }
241:
242: if ($acoPath == null || $acoPath == array()) {
243: trigger_error("DbAcl::check() - Failed ACO node lookup in permissions check. Node references:\nAro: " . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
244: return false;
245: }
246:
247: $aroNode = $aroPath[0];
248: $acoNode = $acoPath[0];
249:
250: if ($action != '*' && !in_array('_' . $action, $permKeys)) {
251: trigger_error(sprintf(__("ACO permissions key %s does not exist in DbAcl::check()", true), $action), E_USER_NOTICE);
252: return false;
253: }
254:
255: $inherited = array();
256: $acoIDs = Set::extract($acoPath, '{n}.' . $this->Aco->alias . '.id');
257:
258: $count = count($aroPath);
259: for ($i = 0 ; $i < $count; $i++) {
260: $permAlias = $this->Aro->Permission->alias;
261:
262: $perms = $this->Aro->Permission->find('all', array(
263: 'conditions' => array(
264: "{$permAlias}.aro_id" => $aroPath[$i][$this->Aro->alias]['id'],
265: "{$permAlias}.aco_id" => $acoIDs
266: ),
267: 'order' => array($this->Aco->alias . '.lft' => 'desc'),
268: 'recursive' => 0
269: ));
270:
271: if (empty($perms)) {
272: continue;
273: } else {
274: $perms = Set::extract($perms, '{n}.' . $this->Aro->Permission->alias);
275: foreach ($perms as $perm) {
276: if ($action == '*') {
277:
278: foreach ($permKeys as $key) {
279: if (!empty($perm)) {
280: if ($perm[$key] == -1) {
281: return false;
282: } elseif ($perm[$key] == 1) {
283: $inherited[$key] = 1;
284: }
285: }
286: }
287:
288: if (count($inherited) === count($permKeys)) {
289: return true;
290: }
291: } else {
292: switch ($perm['_' . $action]) {
293: case -1:
294: return false;
295: case 0:
296: continue;
297: break;
298: case 1:
299: return true;
300: break;
301: }
302: }
303: }
304: }
305: }
306: return false;
307: }
308: 309: 310: 311: 312: 313: 314: 315: 316: 317:
318: function allow($aro, $aco, $actions = "*", $value = 1) {
319: $perms = $this->getAclLink($aro, $aco);
320: $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
321: $save = array();
322:
323: if ($perms == false) {
324: trigger_error(__('DbAcl::allow() - Invalid node', true), E_USER_WARNING);
325: return false;
326: }
327: if (isset($perms[0])) {
328: $save = $perms[0][$this->Aro->Permission->alias];
329: }
330:
331: if ($actions == "*") {
332: $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
333: $save = array_combine($permKeys, array_pad(array(), count($permKeys), $value));
334: } else {
335: if (!is_array($actions)) {
336: $actions = array('_' . $actions);
337: }
338: if (is_array($actions)) {
339: foreach ($actions as $action) {
340: if ($action{0} != '_') {
341: $action = '_' . $action;
342: }
343: if (in_array($action, $permKeys)) {
344: $save[$action] = $value;
345: }
346: }
347: }
348: }
349: list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']);
350:
351: if ($perms['link'] != null && !empty($perms['link'])) {
352: $save['id'] = $perms['link'][0][$this->Aro->Permission->alias]['id'];
353: } else {
354: unset($save['id']);
355: $this->Aro->Permission->id = null;
356: }
357: return ($this->Aro->Permission->save($save) !== false);
358: }
359: 360: 361: 362: 363: 364: 365: 366: 367:
368: function deny($aro, $aco, $action = "*") {
369: return $this->allow($aro, $aco, $action, -1);
370: }
371: 372: 373: 374: 375: 376: 377: 378: 379:
380: function inherit($aro, $aco, $action = "*") {
381: return $this->allow($aro, $aco, $action, 0);
382: }
383: 384: 385: 386: 387: 388: 389: 390: 391: 392:
393: function grant($aro, $aco, $action = "*") {
394: return $this->allow($aro, $aco, $action);
395: }
396: 397: 398: 399: 400: 401: 402: 403: 404: 405:
406: function revoke($aro, $aco, $action = "*") {
407: return $this->deny($aro, $aco, $action);
408: }
409: 410: 411: 412: 413: 414: 415: 416:
417: function getAclLink($aro, $aco) {
418: $obj = array();
419: $obj['Aro'] = $this->Aro->node($aro);
420: $obj['Aco'] = $this->Aco->node($aco);
421:
422: if (empty($obj['Aro']) || empty($obj['Aco'])) {
423: return false;
424: }
425:
426: return array(
427: 'aro' => Set::extract($obj, 'Aro.0.'.$this->Aro->alias.'.id'),
428: 'aco' => Set::extract($obj, 'Aco.0.'.$this->Aco->alias.'.id'),
429: 'link' => $this->Aro->Permission->find('all', array('conditions' => array(
430: $this->Aro->Permission->alias . '.aro_id' => Set::extract($obj, 'Aro.0.'.$this->Aro->alias.'.id'),
431: $this->Aro->Permission->alias . '.aco_id' => Set::extract($obj, 'Aco.0.'.$this->Aco->alias.'.id')
432: )))
433: );
434: }
435: 436: 437: 438: 439: 440: 441:
442: function _getAcoKeys($keys) {
443: $newKeys = array();
444: $keys = array_keys($keys);
445: foreach ($keys as $key) {
446: if (!in_array($key, array('id', 'aro_id', 'aco_id'))) {
447: $newKeys[] = $key;
448: }
449: }
450: return $newKeys;
451: }
452: }
453: 454: 455: 456: 457: 458:
459: class IniAcl extends AclBase {
460: 461: 462: 463: 464: 465:
466: var $config = null;
467: 468: 469: 470:
471: function __construct() {
472: }
473: 474: 475: 476: 477: 478: 479: 480: 481: 482:
483: function check($aro, $aco, $aco_action = null) {
484: if ($this->config == null) {
485: $this->config = $this->readConfigFile(CONFIGS . 'acl.ini.php');
486: }
487: $aclConfig = $this->config;
488:
489: if (isset($aclConfig[$aro]['deny'])) {
490: $userDenies = $this->arrayTrim(explode(",", $aclConfig[$aro]['deny']));
491:
492: if (array_search($aco, $userDenies)) {
493: return false;
494: }
495: }
496:
497: if (isset($aclConfig[$aro]['allow'])) {
498: $userAllows = $this->arrayTrim(explode(",", $aclConfig[$aro]['allow']));
499:
500: if (array_search($aco, $userAllows)) {
501: return true;
502: }
503: }
504:
505: if (isset($aclConfig[$aro]['groups'])) {
506: $userGroups = $this->arrayTrim(explode(",", $aclConfig[$aro]['groups']));
507:
508: foreach ($userGroups as $group) {
509: if (array_key_exists($group, $aclConfig)) {
510: if (isset($aclConfig[$group]['deny'])) {
511: $groupDenies=$this->arrayTrim(explode(",", $aclConfig[$group]['deny']));
512:
513: if (array_search($aco, $groupDenies)) {
514: return false;
515: }
516: }
517:
518: if (isset($aclConfig[$group]['allow'])) {
519: $groupAllows = $this->arrayTrim(explode(",", $aclConfig[$group]['allow']));
520:
521: if (array_search($aco, $groupAllows)) {
522: return true;
523: }
524: }
525: }
526: }
527: }
528: return false;
529: }
530: 531: 532: 533: 534: 535: 536:
537: function readConfigFile($fileName) {
538: $fileLineArray = file($fileName);
539:
540: foreach ($fileLineArray as $fileLine) {
541: $dataLine = trim($fileLine);
542: $firstChar = substr($dataLine, 0, 1);
543:
544: if ($firstChar != ';' && $dataLine != '') {
545: if ($firstChar == '[' && substr($dataLine, -1, 1) == ']') {
546: $sectionName = preg_replace('/[\[\]]/', '', $dataLine);
547: } else {
548: $delimiter = strpos($dataLine, '=');
549:
550: if ($delimiter > 0) {
551: $key = strtolower(trim(substr($dataLine, 0, $delimiter)));
552: $value = trim(substr($dataLine, $delimiter + 1));
553:
554: if (substr($value, 0, 1) == '"' && substr($value, -1) == '"') {
555: $value = substr($value, 1, -1);
556: }
557:
558: $iniSetting[$sectionName][$key]=stripcslashes($value);
559: } else {
560: if (!isset($sectionName)) {
561: $sectionName = '';
562: }
563:
564: $iniSetting[$sectionName][strtolower(trim($dataLine))]='';
565: }
566: }
567: }
568: }
569:
570: return $iniSetting;
571: }
572: 573: 574: 575: 576: 577: 578:
579: function arrayTrim($array) {
580: foreach ($array as $key => $value) {
581: $array[$key] = trim($value);
582: }
583: array_unshift($array, "");
584: return $array;
585: }
586: }
587: ?>