Check (expected) folder type and disable access to folder contents or cache if invalid (#4378)

This commit is contained in:
Thomas Bruederli 2015-01-29 16:48:42 +01:00
parent 44216168f1
commit 038e269d51
3 changed files with 80 additions and 27 deletions

View file

@ -154,7 +154,7 @@ class kolab_storage
if (self::setup()) {
foreach ((array)self::list_folders('', '*', $type, $subscribed, $folderdata) as $foldername) {
$folders[$foldername] = new kolab_storage_folder($foldername, $folderdata[$foldername]);
$folders[$foldername] = new kolab_storage_folder($foldername, $type, $folderdata[$foldername]);
}
}
@ -171,7 +171,7 @@ class kolab_storage
{
if (self::setup()) {
foreach ((array)self::list_folders('', '*', $type . '.default', false, $folderdata) as $foldername) {
return new kolab_storage_folder($foldername, $folderdata[$foldername]);
return new kolab_storage_folder($foldername, $type, $folderdata[$foldername]);
}
}
@ -203,11 +203,11 @@ class kolab_storage
{
self::setup();
$folder = null;
foreach ((array)self::list_folders('', '*', $type) as $foldername) {
foreach ((array)self::list_folders('', '*', $type, null, $folderdata) as $foldername) {
if (!$folder)
$folder = new kolab_storage_folder($foldername);
$folder = new kolab_storage_folder($foldername, $type, $folderdata[$foldername]);
else
$folder->set_folder($foldername);
$folder->set_folder($foldername, $type, $folderdata[$foldername]);
if ($object = $folder->get_object($uid, '*'))
return $object;
@ -230,11 +230,11 @@ class kolab_storage
$folder = null;
$result = array();
foreach ((array)self::list_folders('', '*', $type) as $foldername) {
foreach ((array)self::list_folders('', '*', $type, null, $folderdata) as $foldername) {
if (!$folder)
$folder = new kolab_storage_folder($foldername);
$folder = new kolab_storage_folder($foldername, $type, $folderdata[$foldername]);
else
$folder->set_folder($foldername);
$folder->set_folder($foldername, $type, $folderdata[$foldername]);
foreach ($folder->select($query, '*') as $object) {
$result[] = $object;
@ -901,7 +901,7 @@ class kolab_storage
!self::folder_is_subscribed($foldername, true) &&
!in_array(self::$imap->folder_namespace($foldername), (array)$exclude_ns)
) {
$folders[] = new kolab_storage_folder($foldername, $folderdata[$foldername]);
$folders[] = new kolab_storage_folder($foldername, $type, $folderdata[$foldername]);
}
}
@ -974,7 +974,7 @@ class kolab_storage
$parent_parent = join($delim, $path);
if (!$refs[$parent]) {
if ($folder->type && self::folder_type($parent) == $folder->type) {
$refs[$parent] = new kolab_storage_folder($parent, $folder->type);
$refs[$parent] = new kolab_storage_folder($parent, $folder->type, $folder->type);
$refs[$parent]->parent = $parent_parent;
}
else if ($parent_parent == $other_ns) {
@ -1542,7 +1542,7 @@ class kolab_storage
foreach ($folders as $userfolder) {
foreach ((array)self::list_folders($userfolder->name . $delimiter, '*', $type, false, $folderdata) as $foldername) {
if (!$folders[$foldername]) {
$folders[$foldername] = new kolab_storage_folder($foldername, $folderdata[$foldername]);
$folders[$foldername] = new kolab_storage_folder($foldername, $type, $folderdata[$foldername]);
$userfolder->children[] = $folders[$foldername];
}
}

View file

@ -80,6 +80,7 @@ class kolab_storage_cache
$this->db = $rcmail->get_dbh();
$this->imap = $rcmail->get_storage();
$this->enabled = $rcmail->config->get('kolab_cache', false);
$this->folders_table = $this->db->table_name('kolab_folders');
if ($this->enabled) {
// always read folder cache and lock state from DB master
@ -98,8 +99,7 @@ class kolab_storage_cache
*/
public function select_by_id($folder_id)
{
$folders_table = $this->db->table_name('kolab_folders', true);
$sql_arr = $this->db->fetch_assoc($this->db->query("SELECT * FROM $folders_table WHERE `folder_id` = ?", $folder_id));
$sql_arr = $this->db->fetch_assoc($this->db->query("SELECT * FROM `{$this->cache_table}` WHERE `folder_id` = ?", $folder_id));
if ($sql_arr) {
$this->metadata = $sql_arr;
$this->folder_id = $sql_arr['folder_id'];
@ -120,14 +120,13 @@ class kolab_storage_cache
{
$this->folder = $storage_folder;
if (empty($this->folder->name)) {
if (empty($this->folder->name) || !$this->folder->valid) {
$this->ready = false;
return;
}
// compose fully qualified ressource uri for this instance
$this->resource_uri = $this->folder->get_resource_uri();
$this->folders_table = $this->db->table_name('kolab_folders');
$this->cache_table = $this->db->table_name('kolab_cache_' . $this->folder->type);
$this->ready = $this->enabled && !empty($this->folder->type);
$this->folder_id = null;

View file

@ -30,14 +30,22 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public $cache;
private $type_annotation;
/**
* Indicate validity status
* @var boolean
*/
public $valid = false;
private $resource_uri;
/**
* Default constructor
*
* @param string The folder name/path
* @param string Expected folder type
*/
function __construct($name, $type = null)
function __construct($name, $type = null, $type_annotation = null)
{
parent::__construct($name);
$this->imap->set_options(array('skip_deleted' => true));
@ -49,28 +57,31 @@ class kolab_storage_folder extends kolab_storage_folder_api
* Set the IMAP folder this instance connects to
*
* @param string The folder name/path
* @param string Expected folder type
* @param string Optional folder type if known
*/
public function set_folder($name, $type = null)
public function set_folder($name, $type = null, $type_annotation = null)
{
$this->type_annotation = $type ? $type : kolab_storage::folder_type($name);
if (empty($type_annotation)) {
$type_annotation = kolab_storage::folder_type($name);
}
$oldtype = $this->type;
list($this->type, $suffix) = explode('.', $this->type_annotation);
list($this->type, $suffix) = explode('.', $type_annotation);
$this->default = $suffix == 'default';
$this->subtype = $this->default ? '' : $suffix;
$this->name = $name;
$this->id = kolab_storage::folder_id($name);
$this->valid = !empty($this->type) && $this->type != 'mail' && (!$type || $this->type == $type);
// reset cached object properties
$this->owner = $this->namespace = $this->resource_uri = $this->info = $this->idata = null;
// get a new cache instance of folder type changed
if (!$this->cache || $type != $oldtype)
// get a new cache instance if folder type changed
if (!$this->cache || $this->type != $oldtype)
$this->cache = kolab_storage_cache::factory($this);
$this->imap->set_folder($this->name);
$this->cache->set_folder($this);
}
@ -204,6 +215,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function count($query = null)
{
if (!$this->valid) {
return 0;
}
// synchronize cache first
$this->cache->synchronize();
@ -221,6 +236,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
{
if (!$type) $type = $this->type;
if (!$this->valid) {
return array();
}
// synchronize caches
$this->cache->synchronize();
@ -238,9 +257,14 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function select($query = array())
{
if (!$this->valid) {
return array();
}
// check query argument
if (empty($query))
if (empty($query)) {
return $this->get_objects();
}
// synchronize caches
$this->cache->synchronize();
@ -258,6 +282,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function get_uids($query = array())
{
if (!$this->valid) {
return array();
}
// synchronize caches
$this->cache->synchronize();
@ -319,6 +347,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function get_object($uid, $type = null)
{
if (!$this->valid) {
return false;
}
// synchronize caches
$this->cache->synchronize();
@ -348,7 +380,7 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function get_attachment($uid, $part, $mailbox = null, $print = false, $fp = null, $skip_charset_conv = false)
{
if ($msguid = ($mailbox ? $uid : $this->cache->uid2msguid($uid))) {
if ($this->valid && ($msguid = ($mailbox ? $uid : $this->cache->uid2msguid($uid)))) {
$this->imap->set_folder($mailbox ? $mailbox : $this->name);
if (substr($part, 0, 2) == 'i:') {
@ -392,6 +424,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function read_object($msguid, $type = null, $folder = null)
{
if (!$this->valid) {
return false;
}
if (!$type) $type = $this->type;
if (!$folder) $folder = $this->name;
@ -537,6 +573,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function save(&$object, $type = null, $uid = null)
{
if (!$this->valid) {
return false;
}
if (!$type)
$type = $this->type;
@ -732,6 +772,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function delete($object, $expunge = true)
{
if (!$this->valid) {
return false;
}
$msguid = is_array($object) ? $object['_msguid'] : $this->cache->uid2msguid($object);
$success = false;
@ -759,6 +803,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function delete_all()
{
if (!$this->valid) {
return false;
}
$this->cache->purge();
$this->cache->bypass(true);
$result = $this->imap->clear_folder($this->name);
@ -776,6 +824,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function undelete($uid)
{
if (!$this->valid) {
return false;
}
if ($msguid = $this->cache->uid2msguid($uid, true)) {
$this->cache->bypass(true);
$result = $this->imap->set_flag($msguid, 'UNDELETED', $this->name);
@ -799,6 +851,10 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
public function move($uid, $target_folder)
{
if (!$this->valid) {
return false;
}
if (is_string($target_folder))
$target_folder = kolab_storage::get_folder($target_folder);
@ -1054,8 +1110,6 @@ class kolab_storage_folder extends kolab_storage_folder_api
*/
private function trigger_url($url, $auth_user = null, $auth_passwd = null)
{
require_once('HTTP/Request2.php');
try {
$request = libkolab::http_request($url);