ich hab mal (weil das Core Acl viel zu mächtig und umfangreich ist - und 3MB (!) mehr an Memory frisst - was im Prinzip bei mir fast das ganze restliche Script überbietet^^) ne eigene Authentifierung gebastelt.
Übigens:
das CoreACL ist (trotz ALLEM was es kann), nicht in der Lage, ohne mehrere Hacks mit mehreren Rollen (HABTM users/roles) statt nur role_id in users auszukommen.
Das war auch ein Anliegen
Jedenfalls schaut euch doch ma bitte an, ob die abgewandelten Functions so an sich Sinn machen:
Ist noch in der BetaPhase
- Code: Alles auswählen
- // override this to find the right aro/aco
function isAuthorized($type = null, $object = null, $user = null) {
$valid = false;
if($type == 'tiny_actions') { // && $this->user($this->parentModel) # not needed
# Multiple Roles
# get the roles from the Session, and set the proper Aro path
$otherRoles = $this->user($this->parentModel);
if (!empty($otherRoles)) {
# action: e.g. Users/admin_listing, Users/listing, ... | roles: e.g. '0'=>'4', '1'=>'9', ...
//pr ($this->action()); pr ($otherRoles);
# for more than one role:
//core: $valid = $this->Acl->check(array($this->parentModel => array('id' => $otherRoles)), $this->action());
# my own one
$valid = $this->check($otherRoles, $this->action());
}
} elseif(!empty($type)) {
if ($this->user($this->parentModel)) {
# If you only use single role auth - create a role_id field in users table!!!
$valid = parent::isAuthorized($type, $object, $user);
}
} else {
trigger_error(sprintf(__('Could not find validation type - validation skipped', true), get_class($object)), E_USER_WARNING);
}
return $valid;
}
private $testRoles = array(
'Users' => array(
'home' => array(
4, 5, 6
),
'admin_listing' => array(
15
),
),
'Messages' => array(
'show' => array(
4, 5, 6
),
'admin_index' => array(
15
),
),
);
function check($roles, $action) {
$actions = explode('/',$action);
if (!empty($actions[0]) && !empty($actions[1])) {
if (array_key_exists($actions[0],$this->testRoles) && !empty($this->testRoles[$actions[0]][$actions[1]])) {
$testRoles = $this->testRoles[$actions[0]][$actions[1]];
//pr ($testRoles);
foreach ($roles as $role) {
if (in_array($role, $testRoles)) {
return true;
}
}
}
}
return false;
}
wie ihr seht, ist alles sehr kompakt in einem Array gespeichert, das dann später in /tmp etc irgendwo gecached werden könnte, nachdem
es aus der Datenbank (und dem Aro/Aco Table) generiert worden ist. Momentan ist es zum Testen eben noch direkt hier eingebaut
Jedenfalls werden alle Rollen aus Session Auth.User.roles ausgelesen, und daraufhin mit dem Array verglichen.
Sobald eine Übereinstimmung gefunden wurde, wird true returned
Bisher scheint es sicher und extrem schnell zu funktionieren, selbst mit 5 rollen pro User (User, Moderator, Admin, Chat-Admin, SpecialRole) etc.
Das einzige was ich eben noch rausfinden muss ist, wie man nun effizient alles im Backend verwaltet, also dass neue actions rollen bekommen, das kaskadierende Editieren (BaumStruktur) von Rollen-Zuweisungen etc. und dann eben das "exportieren" in ein solches CacheFile, das dann von meiner AuthFunction benutzt wird (und wenn es nicht existiert, warum auch immer, dass es eben angelegt wird).
Ich habe mich bewusst für die Speicherung "Controller"-> "Action" -> array(IDs) entschieden, weil damit seehr schnell Berechtigungen gefunden werden können, mit einem minimalen Platzverbrauch in der Datei - die ja sehr groß werden kann, wenn es mal genug Controller/Actions gibt...