summaryrefslogtreecommitdiff
path: root/modules/gallery/helpers/access.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gallery/helpers/access.php')
-rw-r--r--modules/gallery/helpers/access.php108
1 files changed, 71 insertions, 37 deletions
diff --git a/modules/gallery/helpers/access.php b/modules/gallery/helpers/access.php
index c48f0b79..949aea84 100644
--- a/modules/gallery/helpers/access.php
+++ b/modules/gallery/helpers/access.php
@@ -66,9 +66,10 @@
* the Access_Intent_Model
*/
class access_Core {
- const DENY = 0;
- const ALLOW = 1;
- const UNKNOWN = 2;
+ const DENY = false;
+ const ALLOW = true;
+ const INHERIT = null; // access_intent
+ const UNKNOWN = null; // cache (access_cache, items)
/**
* Does the active user have this permission on this item?
@@ -78,18 +79,30 @@ class access_Core {
* @return boolean
*/
static function can($perm_name, $item) {
+ return self::user_can(user::active(), $perm_name, $item);
+ }
+
+ /**
+ * Does the user have this permission on this item?
+ *
+ * @param User_Model $user
+ * @param string $perm_name
+ * @param Item_Model $item
+ * @return boolean
+ */
+ static function user_can($user, $perm_name, $item) {
if (!$item->loaded) {
return false;
}
- if (user::active()->admin) {
+ if ($user->admin) {
return true;
}
$resource = $perm_name == "view" ?
$item : model_cache::get("access_cache", $item->id, "item_id");
- foreach (user::group_ids() as $id) {
- if ($resource->__get("{$perm_name}_$id") === self::ALLOW) {
+ foreach ($user->groups as $group) {
+ if ($resource->__get("{$perm_name}_{$group->id}") === self::ALLOW) {
return true;
}
}
@@ -129,7 +142,7 @@ class access_Core {
* @param Group_Model $group
* @param string $perm_name
* @param Item_Model $item
- * @return integer access::ALLOW, access::DENY or null for no intent
+ * @return boolean access::ALLOW, access::DENY or access::INHERIT (null) for no intent
*/
static function group_intent($group, $perm_name, $item) {
$intent = model_cache::get("access_intent", $item->id, "item_id");
@@ -153,11 +166,11 @@ class access_Core {
// For view permissions, if any parent is self::DENY, then those parents lock this one.
// Return
$lock = ORM::factory("item")
- ->where("`left` <= $item->left")
- ->where("`right` >= $item->right")
+ ->where("`left_ptr` <= $item->left_ptr")
+ ->where("`right_ptr` >= $item->right_ptr")
->where("items.id <> $item->id")
->join("access_intents", "items.id", "access_intents.item_id")
- ->where("access_intents.view_$group->id", 0)
+ ->where("access_intents.view_$group->id", self::DENY)
->orderby("level", "DESC")
->limit(1)
->find();
@@ -205,6 +218,7 @@ class access_Core {
}
self::_update_htaccess_files($album, $group, $perm_name, $value);
+ model_cache::clear();
}
/**
@@ -240,7 +254,23 @@ class access_Core {
if ($item->id == 1) {
throw new Exception("@todo CANT_RESET_ROOT_PERMISSION");
}
- self::_set($group, $perm_name, $item, null);
+ self::_set($group, $perm_name, $item, self::INHERIT);
+ }
+
+ /**
+ * Recalculate the permissions for a given item and its hierarchy. $item must be an album.
+ */
+ static function recalculate_permissions($item) {
+ foreach (self::_get_all_groups() as $group) {
+ foreach (ORM::factory("permission")->find_all() as $perm) {
+ if ($perm->name == "view") {
+ self::_update_access_view_cache($group, $item);
+ } else {
+ self::_update_access_non_view_cache($group, $perm->name, $item);
+ }
+ }
+ }
+ model_cache::clear();
}
/**
@@ -411,6 +441,7 @@ class access_Core {
$cache_table = $perm_name == "view" ? "items" : "access_caches";
$db->query("ALTER TABLE {{$cache_table}} DROP `$field`");
$db->query("ALTER TABLE {access_intents} DROP `$field`");
+ model_cache::clear();
ORM::factory("access_intent")->clear_cache();
}
@@ -425,9 +456,11 @@ class access_Core {
$db = Database::instance();
$field = "{$perm_name}_{$group->id}";
$cache_table = $perm_name == "view" ? "items" : "access_caches";
- $db->query("ALTER TABLE {{$cache_table}} ADD `$field` SMALLINT NOT NULL DEFAULT 0");
- $db->query("ALTER TABLE {access_intents} ADD `$field` BOOLEAN DEFAULT NULL");
- $db->update("access_intents", array($field => 0), array("item_id" => 1));
+ $not_null = $cache_table == "items" ? "" : "NOT NULL";
+ $db->query("ALTER TABLE {{$cache_table}} ADD `$field` BINARY $not_null DEFAULT FALSE");
+ $db->query("ALTER TABLE {access_intents} ADD `$field` BINARY DEFAULT NULL");
+ $db->update("access_intents", array($field => self::DENY), array("item_id" => 1));
+ model_cache::clear();
ORM::factory("access_intent")->clear_cache();
}
@@ -457,11 +490,11 @@ class access_Core {
// item, then its safe to propagate from here.
if ($access->$field !== self::DENY) {
$tmp_item = ORM::factory("item")
- ->where("left <", $item->left)
- ->where("right >", $item->right)
+ ->where("left_ptr <", $item->left_ptr)
+ ->where("right_ptr >", $item->right_ptr)
->join("access_intents", "access_intents.item_id", "items.id")
->where("access_intents.$field", self::DENY)
- ->orderby("left", "DESC")
+ ->orderby("left_ptr", "DESC")
->limit(1)
->find();
if ($tmp_item->loaded) {
@@ -474,26 +507,26 @@ class access_Core {
// them according the rule above. So mark every permission below this level as UNKNOWN so
// that we can tell which permissions have been changed, and which ones need to be updated.
$db->update("items", array($field => self::UNKNOWN),
- array("left >=" => $item->left, "right <=" => $item->right));
+ array("left_ptr >=" => $item->left_ptr, "right_ptr <=" => $item->right_ptr));
$query = ORM::factory("access_intent")
- ->select(array("access_intents.$field", "items.left", "items.right", "items.id"))
+ ->select(array("access_intents.$field", "items.left_ptr", "items.right_ptr", "items.id"))
->join("items", "items.id", "access_intents.item_id")
- ->where("left >=", $item->left)
- ->where("right <=", $item->right)
+ ->where("left_ptr >=", $item->left_ptr)
+ ->where("right_ptr <=", $item->right_ptr)
->where("type", "album")
- ->where("access_intents.$field IS NOT", null)
+ ->where("access_intents.$field IS NOT", self::INHERIT)
->orderby("level", "DESC")
->find_all();
foreach ($query as $row) {
if ($row->$field == self::ALLOW) {
// Propagate ALLOW for any row that is still UNKNOWN.
$db->update("items", array($field => $row->$field),
- array($field => self::UNKNOWN, "left >=" => $row->left, "right <=" => $row->right));
+ array($field => self::UNKNOWN, "left_ptr >=" => $row->left_ptr, "right_ptr <=" => $row->right_ptr));
} else if ($row->$field == self::DENY) {
// DENY overwrites everything below it
$db->update("items", array($field => $row->$field),
- array("left >=" => $row->left, "right <=" => $row->right));
+ array("left_ptr >=" => $row->left_ptr, "right_ptr <=" => $row->right_ptr));
}
}
@@ -501,7 +534,7 @@ class access_Core {
// DENY parent in the hierarchy to propagate from. So we'll still have a UNKNOWN values in
// the hierarchy, and all of those are safe to change to ALLOW.
$db->update("items", array($field => self::ALLOW),
- array($field => self::UNKNOWN, "left >=" => $item->left, "right <=" => $item->right));
+ array($field => self::UNKNOWN, "left_ptr >=" => $item->left_ptr, "right_ptr <=" => $item->right_ptr));
}
/**
@@ -526,13 +559,13 @@ class access_Core {
//
// @todo To optimize this, we wouldn't need to propagate from the parent, we could just
// propagate from here with the parent's intent.
- if ($access->$field === null) {
+ if ($access->$field === self::INHERIT) {
$tmp_item = ORM::factory("item")
->join("access_intents", "items.id", "access_intents.item_id")
- ->where("left <", $item->left)
- ->where("right >", $item->right)
- ->where("$field IS NOT", null)
- ->orderby("left", "DESC")
+ ->where("left_ptr <", $item->left_ptr)
+ ->where("right_ptr >", $item->right_ptr)
+ ->where("$field IS NOT", self::UNKNOWN)
+ ->orderby("left_ptr", "DESC")
->limit(1)
->find();
if ($tmp_item->loaded) {
@@ -543,20 +576,21 @@ class access_Core {
// With non-view permissions, each level can override any permissions that came above it
// so start at the top and work downwards, overlaying permissions as we go.
$query = ORM::factory("access_intent")
- ->select(array("access_intents.$field", "items.left", "items.right"))
+ ->select(array("access_intents.$field", "items.left_ptr", "items.right_ptr"))
->join("items", "items.id", "access_intents.item_id")
- ->where("left >=", $item->left)
- ->where("right <=", $item->right)
- ->where("$field IS NOT", null)
+ ->where("left_ptr >=", $item->left_ptr)
+ ->where("right_ptr <=", $item->right_ptr)
+ ->where("$field IS NOT", self::INHERIT)
->orderby("level", "ASC")
->find_all();
foreach ($query as $row) {
+ $value = ($row->$field === self::ALLOW) ? "TRUE" : "FALSE";
$db->query(
- "UPDATE {access_caches} SET `$field` = {$row->$field} " .
+ "UPDATE {access_caches} SET `$field` = $value " .
"WHERE `item_id` IN " .
" (SELECT `id` FROM {items} " .
- " WHERE `left` >= $row->left " .
- " AND `right` <= $row->right)");
+ " WHERE `left_ptr` >= $row->left_ptr " .
+ " AND `right_ptr` <= $row->right_ptr)");
}
}