1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: App::uses('AclInterface', 'Controller/Component/Acl');
16:
17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
36: class DbAcl extends Object implements AclInterface {
37:
38: 39: 40: 41:
42: public function __construct() {
43: parent::__construct();
44: App::uses('AclNode', 'Model');
45: $this->Aro = ClassRegistry::init(array('class' => 'Aro', 'alias' => 'Aro'));
46: $this->Aco = ClassRegistry::init(array('class' => 'Aco', 'alias' => 'Aco'));
47: }
48:
49: 50: 51: 52: 53: 54:
55: public function initialize(Component $component) {
56: $component->Aro = $this->Aro;
57: $component->Aco = $this->Aco;
58: }
59:
60: 61: 62: 63: 64: 65: 66: 67: 68:
69: public function check($aro, $aco, $action = "*") {
70: if ($aro == null || $aco == null) {
71: return false;
72: }
73:
74: $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
75: $aroPath = $this->Aro->node($aro);
76: $acoPath = $this->Aco->node($aco);
77:
78: if (empty($aroPath) || empty($acoPath)) {
79: trigger_error(__d('cake_dev', "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);
80: return false;
81: }
82:
83: if ($acoPath == null || $acoPath == array()) {
84: trigger_error(__d('cake_dev', "DbAcl::check() - Failed ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
85: return false;
86: }
87:
88: if ($action != '*' && !in_array('_' . $action, $permKeys)) {
89: trigger_error(__d('cake_dev', "ACO permissions key %s does not exist in DbAcl::check()", $action), E_USER_NOTICE);
90: return false;
91: }
92:
93: $inherited = array();
94: $acoIDs = Set::extract($acoPath, '{n}.' . $this->Aco->alias . '.id');
95:
96: $count = count($aroPath);
97: for ($i = 0; $i < $count; $i++) {
98: $permAlias = $this->Aro->Permission->alias;
99:
100: $perms = $this->Aro->Permission->find('all', array(
101: 'conditions' => array(
102: "{$permAlias}.aro_id" => $aroPath[$i][$this->Aro->alias]['id'],
103: "{$permAlias}.aco_id" => $acoIDs
104: ),
105: 'order' => array($this->Aco->alias . '.lft' => 'desc'),
106: 'recursive' => 0
107: ));
108:
109: if (empty($perms)) {
110: continue;
111: } else {
112: $perms = Set::extract($perms, '{n}.' . $this->Aro->Permission->alias);
113: foreach ($perms as $perm) {
114: if ($action == '*') {
115:
116: foreach ($permKeys as $key) {
117: if (!empty($perm)) {
118: if ($perm[$key] == -1) {
119: return false;
120: } elseif ($perm[$key] == 1) {
121: $inherited[$key] = 1;
122: }
123: }
124: }
125:
126: if (count($inherited) === count($permKeys)) {
127: return true;
128: }
129: } else {
130: switch ($perm['_' . $action]) {
131: case -1:
132: return false;
133: case 0:
134: continue;
135: break;
136: case 1:
137: return true;
138: break;
139: }
140: }
141: }
142: }
143: }
144: return false;
145: }
146:
147: 148: 149: 150: 151: 152: 153: 154: 155: 156:
157: public function allow($aro, $aco, $actions = "*", $value = 1) {
158: $perms = $this->getAclLink($aro, $aco);
159: $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
160: $save = array();
161:
162: if ($perms == false) {
163: trigger_error(__d('cake_dev', 'DbAcl::allow() - Invalid node'), E_USER_WARNING);
164: return false;
165: }
166: if (isset($perms[0])) {
167: $save = $perms[0][$this->Aro->Permission->alias];
168: }
169:
170: if ($actions == "*") {
171: $permKeys = $this->_getAcoKeys($this->Aro->Permission->schema());
172: $save = array_combine($permKeys, array_pad(array(), count($permKeys), $value));
173: } else {
174: if (!is_array($actions)) {
175: $actions = array('_' . $actions);
176: }
177: if (is_array($actions)) {
178: foreach ($actions as $action) {
179: if ($action{0} != '_') {
180: $action = '_' . $action;
181: }
182: if (in_array($action, $permKeys)) {
183: $save[$action] = $value;
184: }
185: }
186: }
187: }
188: list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']);
189:
190: if ($perms['link'] != null && !empty($perms['link'])) {
191: $save['id'] = $perms['link'][0][$this->Aro->Permission->alias]['id'];
192: } else {
193: unset($save['id']);
194: $this->Aro->Permission->id = null;
195: }
196: return ($this->Aro->Permission->save($save) !== false);
197: }
198:
199: 200: 201: 202: 203: 204: 205: 206: 207:
208: public function deny($aro, $aco, $action = "*") {
209: return $this->allow($aro, $aco, $action, -1);
210: }
211:
212: 213: 214: 215: 216: 217: 218: 219:
220: public function inherit($aro, $aco, $action = "*") {
221: return $this->allow($aro, $aco, $action, 0);
222: }
223:
224: 225: 226: 227: 228: 229: 230: 231: 232:
233: public function grant($aro, $aco, $action = "*") {
234: return $this->allow($aro, $aco, $action);
235: }
236:
237: 238: 239: 240: 241: 242: 243: 244: 245:
246: public function revoke($aro, $aco, $action = "*") {
247: return $this->deny($aro, $aco, $action);
248: }
249:
250: 251: 252: 253: 254: 255: 256:
257: public function getAclLink($aro, $aco) {
258: $obj = array();
259: $obj['Aro'] = $this->Aro->node($aro);
260: $obj['Aco'] = $this->Aco->node($aco);
261:
262: if (empty($obj['Aro']) || empty($obj['Aco'])) {
263: return false;
264: }
265:
266: return array(
267: 'aro' => Set::extract($obj, 'Aro.0.' . $this->Aro->alias . '.id'),
268: 'aco' => Set::extract($obj, 'Aco.0.' . $this->Aco->alias . '.id'),
269: 'link' => $this->Aro->Permission->find('all', array('conditions' => array(
270: $this->Aro->Permission->alias . '.aro_id' => Set::extract($obj, 'Aro.0.' . $this->Aro->alias . '.id'),
271: $this->Aro->Permission->alias . '.aco_id' => Set::extract($obj, 'Aco.0.' . $this->Aco->alias . '.id')
272: )))
273: );
274: }
275:
276: 277: 278: 279: 280: 281:
282: protected function _getAcoKeys($keys) {
283: $newKeys = array();
284: $keys = array_keys($keys);
285: foreach ($keys as $key) {
286: if (!in_array($key, array('id', 'aro_id', 'aco_id'))) {
287: $newKeys[] = $key;
288: }
289: }
290: return $newKeys;
291: }
292:
293: }
294: