["string", null, "nom d'utilisateur"], "password" => ["?string", null, "mot de passe"], "mail" => ["?string", null, "mail de l'utilisateur"], "role" => ["?string", null, "role principal de l'utilisateur"], "perms" => ["?array", null, "permissions attribuées à l'utilisateur"], "groups" => ["?array", null, "groupes dont l'utilisateur fait partie"], "display_name" => ["?string", null, "nom d'affichage long"], "short_name" => ["?string", null, "nom d'affichage court"], "disabled" => ["bool", false, "ce compte est-il désactivé?"], ]; const GROUP_SCHEMA = [ "groupname" => ["string", null, "identifiant", "required" => true], "lib" => ["?string", null, "libellé"], "role" => ["?string", null, "rôle par défaut attribué aux membres de ce groupe"], "perms" => ["?array", null, "permissions supplémentaires associées à ce groupe"], ]; const OVERRIDES_SCHEMA = [ "cas_attrs" => ["?array", null, "attributs CAS"], ]; private static $user_md; protected static function user_md(): Metadata { if (self::$user_md === null) self::$user_md = new Metadata(self::USER_SCHEMA); return self::$user_md; } function _getUser(string $username): ?array { return config::k("users.$username"); } function getUser(string $username, ?array $overrides, ?bool &$found=null): array { $user = $this->_getUser($username); $found = $user !== null; self::user_md()->ensureSchema($user, $username); # support des attributs CAS $cas_attrs = A::get($overrides, "cas_attrs"); if ($cas_attrs !== null) { # nom et prénom $sn = A::first(explode(",", A::get($cas_attrs, "sn"))); $givenName = A::get($cas_attrs, "givenname"); if ($sn !== null && $givenName !== null) { $sn = txt::upperw($sn); $givenName = txt::upperw($givenName); $parts = preg_split('/[- ]+/', $givenName); $gn = ""; foreach ($parts as $part) { $gn .= mb_substr($part, 0, 1); } $gn = txt::upper($gn); $displayName = "$givenName $sn"; $shortName = "$gn.$sn"; A::replace_n($user, "display_name", $displayName); A::replace_n($user, "short_name", $shortName); } # mail A::replace_n($user, "mail", A::get($cas_attrs, "mail")); } return $user; } private static $group_md; protected static function group_md(): Metadata { if (self::$group_md === null) self::$group_md = new Metadata(self::GROUP_SCHEMA); return self::$group_md; } function _getGroup(string $groupname): ?array { return config::k("groups.$groupname"); } function getGroup(string $groupname, ?array $overrides, ?bool &$found=null): array { $group = $this->_getGroup($groupname); $found = $group !== null; self::group_md()->ensureSchema($group, $groupname); # support des attributs CAS $cas_attrs = A::get($overrides, "cas_attrs"); if ($cas_attrs !== null) { } return $group; } protected function getDefaultRole(): ?string { return config::k("default_role"); } /** retourner la liste des permissions de l'utilisateur */ protected function getUserPerms(array $user): array { $perms = $user["perms"]; A::merge($perms, config::k("user_perms.$user[username]")); return $perms; } /** retourner le rôle de l'utilisateur */ protected function getUserRole(array $user): ?string { $role = $user["role"]; base::update_n($role, config::k("user_role.$user[username]")); return $role; } /** retourner les noms des groupes dont fait partie l'utilisateur */ protected function getUserGroupnames(array $user): array { $groups = $user["groups"]; A::merge($groups, config::k("user_groups.$user[username]")); return $groups; } /** retourner le rôle par défaut attribué aux membres du groupe */ protected function getGroupRole(array $group): ?string { $role = $group["role"]; base::update_n($role, config::k("group_role.$group[groupname]")); return $role; } /** retourner les permissions supplémentaires attribuées aux membres du groupe */ protected function getGroupPerms(array $group): ?array { $perms = $group["perms"]; A::merge($perms, config::k("group_perms.$group[groupname]")); return $perms; } /** retourner les permissions associées au rôle */ protected function getRolePerms(string $role): ?array { return config::k("role_perms.$role"); } protected function mergePerms(array &$userPerms, ?array $perms): void { if ($perms === null) return; foreach ($perms as $perm) { $userPerms[$perm] = true; } } protected function mergeRolePerms(array &$userPerms, ?string $role): void { if ($role === null) return; $perms = $this->getRolePerms($role); if ($perms === null) return; foreach ($perms as $perm) { $userPerms[$perm] = true; } } function getAuthzUser(string $username, ?array $overrides): ?IAuthzUser { $user = $this->getUser($username, $overrides, $founduser); $role = null; # permissions par défaut, ajoutées uniquement si l'utilisateur a déjà des # permissions explicites $defaultPerms = ["^$username" => true]; # tout d'abord calculer les permissions et rôles associées à l'utilisateur $perms = array_fill_keys($this->getUserPerms($user), true); $userRole = $this->getUserRole($user); if ($role === null) $role = $userRole; $this->mergeRolePerms($perms, $userRole); # puis calculer les permissions et rôles associés aux groupes $groupnames = $this->getUserGroupnames($user); foreach ($groupnames as $groupname) { # permission automatique basée sur le groupe A::merge($defaultPerms, ["@$groupname" => true]); $group = $this->getGroup($groupname, $overrides, $foundgroup); $this->mergePerms($perms, $this->getGroupPerms($group)); $groupRole = $this->getGroupRole($group); if ($role === null) $role = $groupRole; $this->mergeRolePerms($perms, $groupRole); # rôle automatique du fait de l'appartenance au groupe $this->mergeRolePerms($perms, "@$groupname"); } # si un role ou des permissions existent, considérer que l'utilisateur # existe, même s'il n'avait pas été trouvé au départ if (!$founduser && !$role && !$perms) return null; # permissions par défaut A::merge($perms, $defaultPerms); # rôle par défaut if ($role === null) { $role = $this->getDefaultRole(); $this->mergeRolePerms($perms, $role); } $user["role"] = $role; $user["perms"] = array_keys($perms); $user["groups"] = $groupnames; return new SimpleUser($user); } }