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