diff --git a/core/src/core/classes/class.AJXP_Role.php b/core/src/core/classes/class.AJXP_Role.php index 8e32942bd1..ef1b97b1ef 100644 --- a/core/src/core/classes/class.AJXP_Role.php +++ b/core/src/core/classes/class.AJXP_Role.php @@ -63,6 +63,11 @@ class AJXP_Role implements AjxpGroupPathProvider */ protected $masks = array(); + /** + * @var integer + */ + protected $lastUpdated = 0; + static $cypheredPassPrefix = '$pydio_password$'; public function __construct($id) @@ -270,13 +275,13 @@ public function setParameterValue($pluginId, $parameterName, $parameterValue, $r */ public function filterParameterValue($pluginId, $parameterName, $repositoryId, $parameterValue) { - if (isSet($this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName])) { - $v = $this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName]; + if (isSet($this->parameters[$repositoryId][$pluginId][$parameterName])) { + $v = $this->parameters[$repositoryId][$pluginId][$parameterName]; if($v === AJXP_VALUE_CLEAR) return ""; else return $this->filterCypheredPasswordValue($v); } - if (isSet($this->parameters[$repositoryId][$pluginId][$parameterName])) { - $v = $this->parameters[$repositoryId][$pluginId][$parameterName]; + if (isSet($this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName])) { + $v = $this->parameters[AJXP_REPO_SCOPE_ALL][$pluginId][$parameterName]; if($v === AJXP_VALUE_CLEAR) return ""; else return $this->filterCypheredPasswordValue($v); } @@ -391,13 +396,18 @@ public function override(AJXP_Role $role) { $newRole = new AJXP_Role($role->getId()); - $newAcls = $this->array_merge_recursive2($role->listAcls(), $this->listAcls()); + $roleAcl = $role->listAcls(); + $newAcls = $this->array_merge_recursive2($roleAcl, $this->listAcls()); foreach ($newAcls as $repoId => $rightString) { if($rightString == AJXP_VALUE_CLEAR) continue; + if(empty($rightString) && !empty($roleAcl[$repoId])){ + $rightString = $roleAcl[$repoId]; + } $newRole->setAcl($repoId, $rightString); } - $newParams = $this->array_merge_recursive2($role->listParameters(true), $this->listParameters(true)); + $roleParameters = $role->listParameters(true); + $newParams = $this->array_merge_recursive2($roleParameters, $this->listParameters(true)); foreach ($newParams as $repoId => $data) { foreach ($data as $pluginId => $param) { foreach ($param as $parameterName => $parameterValue) { @@ -406,6 +416,9 @@ public function override(AJXP_Role $role) continue; } if($parameterValue == AJXP_VALUE_CLEAR) continue; + if($parameterValue === "" && !empty($roleParameters[$repoId][$pluginId][$parameterName])){ + $parameterValue = $newParams[$repoId][$pluginId][$parameterName]; + } $newRole->setParameterValue($pluginId, $parameterName, $parameterValue, $repoId); } } @@ -424,7 +437,6 @@ public function override(AJXP_Role $role) $allKeys = array_merge(array_keys($this->masks), array_keys($roleMasks)); foreach($allKeys as $repoId){ if(isSet($roleMasks[$repoId]) && isSet($this->masks[$repoId])){ - //$newRole->setMask($repoId, $this->masks[$repoId]->override($roleMasks[$repoId])); $newRole->setMask($repoId, $roleMasks[$repoId]->override($this->masks[$repoId])); }else if(isSet($roleMasks[$repoId])){ $newRole->setMask($repoId, $roleMasks[$repoId]); @@ -556,4 +568,12 @@ public function autoAppliesTo($specificRight) return in_array($specificRight, $this->autoApplies); } + public function getLastUpdated(){ + return $this->lastUpdated; + } + + public function setLastUpdated($time){ + $this->lastUpdated = $time; + } + } diff --git a/core/src/core/classes/class.AuthService.php b/core/src/core/classes/class.AuthService.php index 3a89fb46a3..6cbf2e8828 100644 --- a/core/src/core/classes/class.AuthService.php +++ b/core/src/core/classes/class.AuthService.php @@ -31,6 +31,7 @@ class AuthService public static $roles; public static $useSession = true; private static $currentUser; + public static $bufferedMessage = null; /** * Whether the whole users management system is enabled or not. * @static @@ -320,7 +321,18 @@ public static function logUser($user_id, $pwd, $bypass_pwd = false, $cookieLogin $confDriver = ConfService::getConfStorageImpl(); if ($user_id == null) { if (self::$useSession) { - if(isSet($_SESSION["AJXP_USER"]) && is_object($_SESSION["AJXP_USER"])) return 1; + if(isSet($_SESSION["AJXP_USER"]) && is_object($_SESSION["AJXP_USER"])) { + /** + * @var AbstractAjxpUser $u + */ + $u = $_SESSION["AJXP_USER"]; + if($u->reloadRolesIfRequired()){ + ConfService::getInstance()->invalidateLoadedRepositories(); + self::$bufferedMessage = AJXP_XMLWriter::reloadRepositoryList(false); + $_SESSION["AJXP_USER"] = $u; + } + return 1; + } } else { if(isSet(self::$currentUser) && is_object(self::$currentUser)) return 1; } diff --git a/core/src/core/classes/class.ConfService.php b/core/src/core/classes/class.ConfService.php index cafe5eafd1..ca7623f209 100644 --- a/core/src/core/classes/class.ConfService.php +++ b/core/src/core/classes/class.ConfService.php @@ -536,7 +536,7 @@ private function getLoadedRepositories() return $this->configs["REPOSITORIES"]; } - private function invalidateLoadedRepositories() + public function invalidateLoadedRepositories() { if(isSet($_SESSION["REPOSITORIES"])) unset($_SESSION["REPOSITORIES"]); $this->configs["REPOSITORIES"] = null; diff --git a/core/src/plugins/conf.sql/class.sqlConfDriver.php b/core/src/plugins/conf.sql/class.sqlConfDriver.php index fb58b2262d..dc51f70214 100644 --- a/core/src/plugins/conf.sql/class.sqlConfDriver.php +++ b/core/src/plugins/conf.sql/class.sqlConfDriver.php @@ -683,6 +683,9 @@ public function listRoles($roleIds = array(), $excludeReserved = false) $object = unserialize($serialized); if (is_a($object, "AjxpRole") || is_a($object, "AJXP_Role")) { $roles[$id] = $object; + if(is_a($object, "AJXP_Role")){ + $object->setLastUpdated($role_row["last_updated"]); + } } } @@ -704,7 +707,7 @@ public function saveRoles($roles) dibi::query("INSERT INTO [ajxp_roles] ([role_id],[serial_role],[searchable_repositories]) VALUES (%s, %bin, %s)", $roleId, serialize($roleObject), serialize($roleObject->listAcls())); break; case "mysql": - dibi::query("INSERT INTO [ajxp_roles] ([role_id],[serial_role]) VALUES (%s, %s)", $roleId, serialize($roleObject)); + dibi::query("INSERT INTO [ajxp_roles] ([role_id],[serial_role],[last_updated]) VALUES (%s, %s, %i)", $roleId, serialize($roleObject),time()); break; default: return "ERROR!, DB driver " . $this->sqlDriver["driver"] . " not supported yet in __FUNCTION__"; @@ -714,6 +717,7 @@ public function saveRoles($roles) /** * @param AJXP_Role $role + * @return string|void */ public function updateRole($role, $userObject = null) { @@ -732,7 +736,7 @@ public function updateRole($role, $userObject = null) } break; case "mysql": - dibi::query("INSERT INTO [ajxp_roles] ([role_id],[serial_role]) VALUES (%s, %s) ON DUPLICATE KEY UPDATE [serial_role]=VALUES([serial_role])", $role->getId(), serialize($role)); + dibi::query("INSERT INTO [ajxp_roles] ([role_id],[serial_role],[last_updated]) VALUES (%s, %s, %i) ON DUPLICATE KEY UPDATE [serial_role]=VALUES([serial_role]), [last_updated]=VALUES([last_updated])", $role->getId(), serialize($role), time()); break; default: return "ERROR!, DB driver ". $this->sqlDriver["driver"] ." not supported yet in __FUNCTION__"; @@ -751,9 +755,20 @@ public function deleteRole($role) dibi::query("DELETE FROM [ajxp_roles] WHERE [role_id]=%s", $roleId); } + /** + * Compute the most recent date where one of these roles where updated. + * + * @param $rolesIdsList + * @return int + */ + public function rolesLastUpdated($rolesIdsList){ + $res = dibi::query("SELECT MAX([last_updated]) FROM [ajxp_roles] WHERE [role_id] IN (%s)", $rolesIdsList); + return $res->fetchSingle(); + } + public function countAdminUsers() { - $rows = dibi::query("SELECT COUNT(*) FROM ajxp_user_rights WHERE [repo_uuid] = %s AND [rights] = %s", "ajxp.admin", "1"); + $rows = dibi::query("SELECT COUNT(*) FROM [ajxp_user_rights] WHERE [repo_uuid] = %s AND [rights] = %s", "ajxp.admin", "1"); return $rows->fetchSingle(); } diff --git a/core/src/plugins/conf.sql/create.mysql b/core/src/plugins/conf.sql/create.mysql index b03a09a316..38633cd8e7 100644 --- a/core/src/plugins/conf.sql/create.mysql +++ b/core/src/plugins/conf.sql/create.mysql @@ -57,7 +57,9 @@ CREATE TABLE IF NOT EXISTS ajxp_repo_options ( CREATE TABLE IF NOT EXISTS ajxp_roles ( role_id VARCHAR(255) PRIMARY KEY, - serial_role TEXT(500) NOT NULL + serial_role TEXT(500) NOT NULL, + last_updated INT(11) NOT NULL DEFAULT 0, + INDEX `last_updated` (`last_updated`) ) CHARACTER SET utf8 COLLATE utf8_unicode_ci; CREATE TABLE IF NOT EXISTS ajxp_groups ( diff --git a/core/src/plugins/core.conf/class.AbstractAjxpUser.php b/core/src/plugins/core.conf/class.AbstractAjxpUser.php index 1ef4b2c911..87372365fb 100644 --- a/core/src/plugins/core.conf/class.AbstractAjxpUser.php +++ b/core/src/plugins/core.conf/class.AbstractAjxpUser.php @@ -582,4 +582,31 @@ protected function filterRolesForSaving($roles, $checkBoolean) return $res; } + protected $lastSessionSerialization = 0; + + public function __sleep(){ + $this->lastSessionSerialization = time(); + return array("id", "hasAdmin", "rights", "prefs", "bookmarks", "version", "roles", "parentUser", "resolveAsParent", "hidden", "groupPath", "personalRole", "lastSessionSerialization"); + } + + public function __wakeup(){ + $this->storage = ConfService::getConfStorageImpl(); + $this->recomputeMergedRole(); + } + + public function reloadRolesIfRequired(){ + if($this->lastSessionSerialization && count($this->roles) + && $this->storage->rolesLastUpdated(array_keys($this->roles)) > $this->lastSessionSerialization){ + + $newRoles = AuthService::getRolesList(array_keys($this->roles)); + foreach($newRoles as $rId => $newRole){ + $this->roles[$rId] = $newRoles[$rId]; + } + $this->recomputeMergedRole(); + return true; + + } + return false; + } + }