function manager()
 {
     if (!$this->manager instanceof SharingTables) {
         $this->manager = SharingTables::instance();
     }
     return $this->manager;
 }
	function after_permission_changed($group = null, $permissions = null) {
		@set_time_limit(0);
		$die = false;
		if ($group == null || $permissions == null) {
			$die = true;
			if ($group == null) {
				$group = array_var($_REQUEST, 'group');
			}
			if ($permissions == null) {
				$permissions = json_decode(array_var($_REQUEST, 'permissions'));
			}
		}
		
		// CHECK PARAMETERS
		if(!count($permissions)){
			return false;
		}
		if (!is_numeric($group) || !$group) {
			throw new Error("Error filling sharing table. Invalid Paramenters for afterPermissionChanged method");
		}

		// INIT LOCAL VARS
		$stManager = SharingTables::instance();
		$affectedObjects = array();
		$members = array();
		$general_condition = '';
		$read_condition = '';
		$delete_condition = '';
		$delete_conditions = array();

		// BUILD OBJECT_IDs SUB-QUERIES
		$from = "FROM ".TABLE_PREFIX."object_members om INNER JOIN ".TABLE_PREFIX."objects o ON o.id = om.object_id";
		foreach ($permissions as $permission) {
			$memberId = $permission->m;
			$objectTypeId = $permission->o;
			if (!$memberId || !$objectTypeId) continue;
			$delete_conditions[] = " ( object_type_id = '$objectTypeId' AND om.member_id = '$memberId' ) ";
			if ($permission->r) {
				$read_conditions[] = " ( object_type_id = '$objectTypeId' AND om.member_id = '$memberId' ) "; 
			}
		}
		
		// DELETE THE AFFECTED OBJECTS FROM SHARING TABLE
		$stManager->delete("object_id IN (SELECT object_id $from WHERE ".implode(' OR ' , $delete_conditions ).") AND group_id = '$group'");
		
		// 2. POPULATE THE SHARING TABLE AGAIN WITH THE READ-PERMISSIONS (If there are)
		if (isset($read_conditions) && count($read_conditions)) {
			$st_new_rows = "
				SELECT $group AS group_id, object_id $from
				WHERE om.is_optimization=0 AND (". implode(' OR ', $read_conditions) . ")";

			$st_insert_sql =  "INSERT INTO ".TABLE_PREFIX."sharing_table(group_id, object_id) $st_new_rows ";
			DB::execute($st_insert_sql);
		}
		
		if ($die) die();
	}
 /**
  * 
  * @param array $objectIds
  * @param int $groupId
  */
 public function populateObjects($objectIds, $groupId)
 {
     if (!is_array($objectIds)) {
         throw new Error(lang("empty group array"), null, null);
     }
     // Insert new rows
     $table = SharingTables::getTableName();
     $cols = array("group_id", "object_id");
     $rows = array();
     foreach ($objectIds as $oid) {
         $rows[] = array($groupId, $oid);
     }
     massiveInsert($table, $cols, $rows, 10000, " ON DUPLICATE KEY UPDATE " . $table . ".group_id=" . $table . ".group_id;");
     $rows = null;
 }
 function delete()
 {
     if (!can_manage_dimension_members(logged_user())) {
         flash_error(lang('no access permissions'));
         ajx_current("empty");
         return;
     }
     $member = Members::findById(get_id());
     try {
         DB::beginWork();
         if (!$member->canBeDeleted($error_message)) {
             throw new Exception($error_message);
         }
         $dim_id = $member->getDimensionId();
         // Remove from shring table
         SharingTables::instance()->delete(" \n\t\t\t\tobject_id IN (\n \t\t\t\t SELECT distinct(object_id) FROM " . TABLE_PREFIX . "object_members WHERE member_id = " . get_id() . " AND is_optimization = 0\n\t\t\t\t)\n\t\t\t");
         $affectedObjectsRows = DB::executeAll("SELECT distinct(object_id) AS object_id FROM " . TABLE_PREFIX . "object_members where member_id = " . get_id() . " AND is_optimization = 0");
         if (is_array($affectedObjectsRows) && count($affectedObjectsRows) > 0) {
             foreach ($affectedObjectsRows as $row) {
                 $oid = $row['object_id'];
                 $object = Objects::findObject($row['object_id']);
                 // return an instance of Message, contact, etc.
                 /* @var $object ContentDataObject */
                 if ($object) {
                     if ($object instanceof ContentDataObject) {
                         $object->addToSharingTable();
                     }
                 }
             }
         }
         $args = $member;
         Hook::fire('delete_member', $args, $ret);
         //			ApplicationLogs::createLog($member, ApplicationLogs::ACTION_DELETE, false, true);
         $ok = $member->delete();
         if ($ok) {
             evt_add("reload dimension tree", $dim_id);
         }
         DB::commit();
         flash_success(lang('success delete member', $member->getName()));
         if (get_id('start')) {
             ajx_current("start");
         } else {
             if (get_id('dont_reload')) {
                 ajx_current("empty");
             } else {
                 ajx_current("reload");
             }
         }
     } catch (Exception $e) {
         DB::rollback();
         flash_error($e->getMessage());
         ajx_current("empty");
     }
 }
 static function addObjToSharingTable($oid, $tid, $obj_mem_ids)
 {
     $gids = array();
     $table_prefix = defined('FORCED_TABLE_PREFIX') && FORCED_TABLE_PREFIX ? FORCED_TABLE_PREFIX : TABLE_PREFIX;
     //1. clear sharing table for this object
     SharingTables::delete("object_id={$oid}");
     //2. get dimensions of this object's members that defines permissions
     $res = DB::execute("SELECT d.id as did FROM " . $table_prefix . "dimensions d INNER JOIN " . $table_prefix . "members m on m.dimension_id=d.id\r\n\t\t\t\tWHERE m.id IN ( SELECT member_id FROM " . $table_prefix . "object_members WHERE object_id = {$oid} AND is_optimization = 0 ) AND d.defines_permissions = 1");
     $dids_tmp = array();
     while ($row = $res->fetchRow()) {
         $dids_tmp[$row['did']] = $row['did'];
     }
     $res->free();
     $dids = array_values($dids_tmp);
     $dids_tmp = null;
     $sql_from = "" . $table_prefix . "contact_member_permissions cmp\r\n\t\tLEFT JOIN " . $table_prefix . "members m ON m.id = cmp.member_id\r\n\t\tLEFT JOIN " . $table_prefix . "dimensions d ON d.id = m.dimension_id";
     $member_where_conditions = "";
     $dim_where_conditions = "";
     // if users can add objects without classifying then check for permissions with member_id=0
     if (config_option('let_users_create_objects_in_root')) {
         $member_where_conditions = "member_id=0 OR ";
         $dim_where_conditions = " OR d.id IS NULL";
     }
     $sql_where = "({$member_where_conditions} member_id IN ( SELECT member_id FROM " . $table_prefix . "object_members WHERE object_id = {$oid} AND is_optimization = 0)) AND cmp.object_type_id = {$tid}";
     //3. If there are dimensions that defines permissions containing any of the object members
     if (count($dids)) {
         // 3.1 get permission groups with permissions over the object.
         $sql_fields = "permission_group_id  AS group_id";
         $sql = "\r\n\t\t\t\tSELECT\r\n\t\t\t\t{$sql_fields}\r\n\t\t\t\tFROM\r\n\t\t\t\t{$sql_from}\r\n\t\t\t\tWHERE\r\n\t\t\t\t{$sql_where} AND (d.id IN (" . implode(',', $dids) . ") {$dim_where_conditions})\r\n\t\t\t";
         $res = DB::execute($sql);
         $gids_tmp = array();
         while ($row = $res->fetchRow()) {
             $gids_tmp[$row['group_id']] = $row['group_id'];
         }
         $res->free();
         // allow all permission groups
         $allow_all_rows = DB::executeAll("SELECT DISTINCT permission_group_id FROM " . $table_prefix . "contact_dimension_permissions cdp\r\n\t\t\t\t\tINNER JOIN " . $table_prefix . "members m on m.dimension_id=cdp.dimension_id\r\n\t\t\t\t\tWHERE cdp.permission_type='allow all' AND cdp.dimension_id IN (" . implode(',', $dids) . ");");
         if (is_array($allow_all_rows)) {
             foreach ($allow_all_rows as $row) {
                 $gids_tmp[$row['permission_group_id']] = $row['permission_group_id'];
             }
         }
         $gids = array_values($gids_tmp);
         $gids_tmp = null;
         // check for mandatory dimensions
         $enabled_dimensions_sql = "";
         $enabled_dimensions_ids = implode(',', config_option('enabled_dimensions'));
         if ($enabled_dimensions_ids != "") {
             $enabled_dimensions_sql = "AND id IN ({$enabled_dimensions_ids})";
         }
         $mandatory_dim_ids = Dimensions::findAll(array('id' => true, 'conditions' => "`defines_permissions`=1 {$enabled_dimensions_sql} AND `permission_query_method`='" . DIMENSION_PERMISSION_QUERY_METHOD_MANDATORY . "'"));
         if (count($gids) > 0 && count($mandatory_dim_ids) > 0) {
             $sql = "SELECT om.member_id, m.dimension_id FROM " . $table_prefix . "object_members om\r\n\t\t\t\t\tINNER JOIN " . $table_prefix . "members m ON m.id=om.member_id INNER JOIN " . $table_prefix . "dimensions d ON d.id=m.dimension_id\r\n\t\t\t\t\tWHERE om.object_id = {$oid} AND om.is_optimization = 0 AND d.id IN (" . implode(",", $mandatory_dim_ids) . ")";
             // Object members in mandatory dimensions
             $object_member_ids_res = DB::executeAll($sql);
             $mandatory_dim_members = array();
             if (!is_null($object_member_ids_res)) {
                 foreach ($object_member_ids_res as $row) {
                     if (!isset($mandatory_dim_members[$row['dimension_id']])) {
                         $mandatory_dim_members[$row['dimension_id']] = array();
                     }
                     $mandatory_dim_members[$row['dimension_id']][] = $row['member_id'];
                 }
                 $mandatory_dim_allowed_pgs = array();
                 // Check foreach group that it has permissions over at least one member of each mandatory dimension
                 foreach ($mandatory_dim_members as $mdim_id => $mmember_ids) {
                     $sql = "SELECT pg.id FROM " . $table_prefix . "permission_groups pg\r\n\t\t\t\t\t\t\tINNER JOIN " . $table_prefix . "contact_dimension_permissions cdp ON cdp.permission_group_id=pg.id\r\n\t\t\t\t\t\t\tINNER JOIN " . $table_prefix . "contact_member_permissions cmp ON cmp.permission_group_id=pg.id\r\n\t\t\t\t\t\t\tWHERE cdp.dimension_id = '{$mdim_id}' AND (\r\n\t\t\t\t\t\t\tcdp.permission_type='allow all' OR cdp.permission_type='check' AND cmp.permission_group_id IN (" . implode(',', $gids) . ")\r\n\t\t\t\t\t\t\tAND cmp.member_id IN (" . implode(',', $mmember_ids) . ")\r\n\t\t\t\t\t\t)";
                     $permission_groups_res = DB::executeAll($sql);
                     $mandatory_dim_allowed_pgs[$mdim_id] = array();
                     if (!is_null($permission_groups_res)) {
                         foreach ($permission_groups_res as $row) {
                             if (!in_array($row['id'], $mandatory_dim_allowed_pgs[$mdim_id])) {
                                 $mandatory_dim_allowed_pgs[$mdim_id][] = $row['id'];
                             }
                         }
                     }
                 }
                 if (isset($mandatory_dim_allowed_pgs) && count($mandatory_dim_allowed_pgs) > 0) {
                     $original_mandatory_dim_allowed_pgs = $mandatory_dim_allowed_pgs;
                     $allowed_gids = array_pop($mandatory_dim_allowed_pgs);
                     foreach ($mandatory_dim_allowed_pgs as $pg_array) {
                         $allowed_gids = array_intersect($allowed_gids, $pg_array);
                     }
                     // If an user has permissions in one dim using a group and in other dim using his personal permissions then add to sharing table its personal permission group
                     $pg_ids = array_unique(array_flat($original_mandatory_dim_allowed_pgs));
                     if (count($pg_ids) == 0) {
                         $pg_ids[0] = 0;
                     }
                     $contact_pgs = array();
                     $contact_pg_rows = DB::executeAll("SELECT * FROM " . TABLE_PREFIX . "contact_permission_groups WHERE permission_group_id IN (" . implode(',', $pg_ids) . ") ORDER BY permission_group_id");
                     if (is_array($contact_pg_rows)) {
                         foreach ($contact_pg_rows as $cpgr) {
                             if (!isset($contact_pgs[$cpgr['contact_id']])) {
                                 $contact_pgs[$cpgr['contact_id']] = array();
                             }
                             $contact_pgs[$cpgr['contact_id']][] = $cpgr['permission_group_id'];
                         }
                     }
                     // each user must have at least one pg for every dimension
                     foreach ($contact_pgs as $contact_id => $permission_groups) {
                         $has_one = array_flip(array_keys($original_mandatory_dim_allowed_pgs));
                         foreach ($has_one as $k => &$v) {
                             $v = false;
                         }
                         foreach ($permission_groups as $pg_id) {
                             foreach ($original_mandatory_dim_allowed_pgs as $dim_id => $allowedpgs) {
                                 if (in_array($pg_id, $allowedpgs)) {
                                     $has_one[$dim_id] = true;
                                     break;
                                 }
                             }
                         }
                         // all dims must be true in this array to allow permissions
                         $has_permission = !in_array(false, $has_one);
                         if ($has_permission) {
                             $contact_row = DB::executeOne("SELECT permission_group_id FROM " . TABLE_PREFIX . "contacts where object_id = {$contact_id}");
                             if (is_array($contact_row) && $contact_row['permission_group_id'] > 0) {
                                 $allowed_gids[] = $contact_row['permission_group_id'];
                             }
                         }
                     }
                     $gids = array_unique($allowed_gids, SORT_NUMERIC);
                 } else {
                     $gids = array();
                 }
             }
         }
     } else {
         if ($obj_mem_ids) {
             // 3.2 No memeber dimensions defines permissions.
             // No esta en ninguna dimension que defina permisos, El objecto esta en algun lado
             // => En todas las dimensiones en la que está no definen permisos => Busco todos los grupos
             $gids = PermissionGroups::instance()->findAll(array('id' => true, 'conditions' => "type != 'roles'"));
         } else {
             // if this object is an email and it is unclassified => add to sharing table the permission groups of the users that have permissions in the email's account
             if (Plugins::instance()->isActivePlugin('mail')) {
                 $mail_ot = ObjectTypes::instance()->findByName('mail');
                 if ($mail_ot instanceof ObjectType && $tid == $mail_ot->getId()) {
                     $gids = array_flat(DB::executeAll("\r\n\t\t\t\t\t\t\tSELECT cpg.permission_group_id\r\n\t\t\t\t\t\t\tFROM " . TABLE_PREFIX . "contact_permission_groups cpg\r\n\t\t\t\t\t\t\tINNER JOIN " . TABLE_PREFIX . "contacts c ON c.permission_group_id=cpg.permission_group_id\r\n\t\t\t\t\t\t\tWHERE cpg.contact_id IN (\r\n\t\t\t\t\t\t\t  SELECT mac.contact_id FROM " . TABLE_PREFIX . "mail_account_contacts mac WHERE mac.account_id = (SELECT mc.account_id FROM " . TABLE_PREFIX . "mail_contents mc WHERE mc.object_id={$oid})\r\n\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t"));
                 }
             }
         }
     }
     if (count($gids)) {
         $stManager = SharingTables::instance();
         $stManager->populateGroups($gids, $oid);
         $gids = null;
     }
 }
 /**
  * This function will return paginated result. Result is an array where first element is 
  * array of returned object and second populated pagination object that can be used for 
  * obtaining and rendering pagination data using various helpers.
  * 
  * Items and pagination array vars are indexed with 0 for items and 1 for pagination
  * because you can't use associative indexing with list() construct
  *
  * @access public
  * @param array $arguments Query argumens (@see find()) Limit and offset are ignored!
  * @param integer $items_per_page Number of items per page
  * @param integer $current_page Current page number
  * @return array
  */
 function paginate($arguments = null, $items_per_page = 10, $current_page = 1)
 {
     if (isset($this) && instance_of($this, 'SharingTables')) {
         return parent::paginate($arguments, $items_per_page, $current_page);
     } else {
         return SharingTables::instance()->paginate($arguments, $items_per_page, $current_page);
     }
     // if
 }
	function delete() {
		if(!can_manage_dimension_members(logged_user())) {
			flash_error(lang('no access permissions'));
			ajx_current("empty");
			return;
		}
		$member = Members::findById(get_id());
		try {
			
			DB::beginWork();
			
			if (!$member->canBeDeleted($error_message)) {
				throw new Exception($error_message);
			}
			$dim_id = $member->getDimensionId();
			
			// Remove from shring table
			SharingTables::instance()->delete(" 
				object_id IN (
 				 SELECT distinct(object_id) FROM ".TABLE_PREFIX."object_members WHERE member_id = ".$member->getId()." AND is_optimization = 0
				)
			");
			$affectedObjectsRows = DB::executeAll("SELECT distinct(object_id) AS object_id FROM ".TABLE_PREFIX."object_members where member_id = ".$member->getId()." AND is_optimization = 0") ;
			if (is_array($affectedObjectsRows) && count($affectedObjectsRows) > 0) {
				foreach ( $affectedObjectsRows as $row ) {
					$oid = $row['object_id'];
					$object = Objects::findObject($row['object_id']); // return an instance of Message, contact, etc.
					/* @var $object ContentDataObject */
					if ($object instanceof ContentDataObject) {
						$object->addToSharingTable();
					}
				}
			}
			
			// remove member associations
			MemberPropertyMembers::delete('member_id = '.$member->getId().' OR property_member_id = '.$member->getId());
			MemberRestrictions::delete('member_id = '.$member->getId().' OR restricted_member_id = '.$member->getId());
			
			// remove from permissions tables
			ContactMemberPermissions::delete('member_id = '.$member->getId());
			PermissionContexts::delete('member_id = '.$member->getId());
			
			// remove associated content object
			if ($member->getObjectId() > 0) {
				$mobj = Objects::findObject($member->getObjectId());
				if ($mobj instanceof ContentDataObject) $mobj->delete();
			}
			
			// delete from object_members
			ObjectMembers::delete('member_id = '.$member->getId());
			
			Hook::fire('delete_member', $member, $ret);

//			ApplicationLogs::createLog($member, ApplicationLogs::ACTION_DELETE, false, true);
			$ok = $member->delete(false);
			if ($ok) {
				evt_add("reload dimension tree", array('dim_id' => $dim_id, 'node' => null));
				evt_add("select dimension member", array('dim_id' => $dim_id, 'node' => 'root'));
			}
			
			DB::commit();
			flash_success(lang('success delete member', $member->getName()));
			if (get_id('start')) {
				ajx_current("start");
			} else {
				if (get_id('dont_reload')) {
					ajx_current("empty");
				} else {
					ajx_current("reload");
				}
			}
		} catch (Exception $e) {
			DB::rollback();
			flash_error($e->getMessage());
			ajx_current("empty");
		}
	}
 /**
  * 
  * @author Ignacio Vazquez - elpepe.uy@gmail.com
  */
 function addToSharingTable()
 {
     $oid = $this->getId();
     $tid = $this->getObjectTypeId();
     $gids = array();
     $table_prefix = defined('FORCED_TABLE_PREFIX') && FORCED_TABLE_PREFIX ? FORCED_TABLE_PREFIX : TABLE_PREFIX;
     //1 clear sharing table for this object
     SharingTables::delete("object_id={$oid}");
     //2 get dimensions of this object's members that defines permissions
     $res = DB::execute("SELECT d.id as did FROM " . $table_prefix . "dimensions d INNER JOIN " . $table_prefix . "members m on m.dimension_id=d.id\n\t\t\tWHERE m.id IN ( SELECT member_id FROM " . $table_prefix . "object_members WHERE object_id = {$oid} AND is_optimization = 0 ) AND d.defines_permissions = 1");
     $dids_tmp = array();
     while ($row = $res->fetchRow()) {
         $dids_tmp[$row['did']] = $row['did'];
     }
     $res->free();
     $dids = array_values($dids_tmp);
     $dids_tmp = null;
     $sql_from = "" . $table_prefix . "contact_member_permissions cmp\n\t\t\tINNER JOIN " . $table_prefix . "members m ON m.id = cmp.member_id\n\t\t\tINNER JOIN " . $table_prefix . "dimensions d ON d.id = m.dimension_id";
     $sql_where = "member_id IN ( SELECT member_id FROM " . $table_prefix . "object_members WHERE object_id = {$oid} AND is_optimization = 0) AND cmp.object_type_id = {$tid}";
     //3 If there are dimensions that defines permissions containing any of the object members
     if (count($dids)) {
         // 3.1 get permission groups with permissions over the object.
         $sql_fields = "permission_group_id  AS group_id";
         $sql = "\n\t\t\t\tSELECT \n\t\t\t\t  {$sql_fields}\t\n\t\t\t\tFROM\n\t\t\t\t  {$sql_from}\n\t\t\t\tWHERE\n\t\t\t\t  {$sql_where} AND d.id IN (" . implode(',', $dids) . ")";
         $res = DB::execute($sql);
         $gids_tmp = array();
         while ($row = $res->fetchRow()) {
             $gids_tmp[$row['group_id']] = $row['group_id'];
         }
         $res->free();
         // allow all permission groups
         $allow_all_rows = DB::executeAll("SELECT DISTINCT permission_group_id FROM " . $table_prefix . "contact_dimension_permissions cdp \n\t\t\t\tINNER JOIN " . $table_prefix . "members m on m.dimension_id=cdp.dimension_id\n\t\t\t\tWHERE cdp.permission_type='allow all' AND cdp.dimension_id IN (" . implode(',', $dids) . ");");
         if (is_array($allow_all_rows)) {
             foreach ($allow_all_rows as $row) {
                 $gids_tmp[$row['permission_group_id']] = $row['permission_group_id'];
             }
         }
         $gids = array_values($gids_tmp);
         $gids_tmp = null;
     } else {
         if (count($this->getMemberIds()) > 0) {
             // 3.2 No memeber dimensions defines permissions.
             // No esta en ninguna dimension que defina permisos, El objecto esta en algun lado
             // => En todas las dimensiones en la que está no definen permisos => Busco todos los grupos
             $gids = PermissionGroups::instance()->findAll(array('id' => true));
         }
     }
     if (count($gids)) {
         $stManager = SharingTables::instance();
         $stManager->populateGroups($gids, $oid);
         $gids = null;
     }
 }
Example #9
0
/**
 * Return true is $user can read the $object. False otherwise.
 * Query executed in sharing table
 *
 * @param Contact $user
 * @param $object_id
 * @return boolean
 */
function can_read_sharing_table(Contact $user, $object_id)
{
    $perm = SharingTables::instance()->findOne(array('conditions' => array("object_id=? AND group_id IN (SELECT permission_group_id FROM " . TABLE_PREFIX . "contact_permission_groups WHERE contact_id = '" . $user->getId() . "')", $object_id)));
    return !is_null($perm);
}
 function adjust_root_permissions($group, $root_perm_info = null)
 {
     // ROOT PERMISSIONS
     if (!is_null($root_perm_info)) {
         // user does not have permissions for object_type_ids
         $root_permissions_sharing_table_delete = array_var($root_perm_info, 'root_permissions_sharing_table_delete');
         if (is_array($root_permissions_sharing_table_delete)) {
             foreach ($root_permissions_sharing_table_delete as $object_type_id) {
                 $cond = "group_id={$group} AND object_id IN (SELECT o.id FROM " . TABLE_PREFIX . "objects o WHERE o.object_type_id = {$object_type_id} AND NOT EXISTS(\r\n\t\t\t\t\t\tSELECT om.object_id FROM " . TABLE_PREFIX . "object_members om WHERE om.object_id=o.id AND om.member_id IN (SELECT m.id FROM " . TABLE_PREFIX . "members m WHERE m.dimension_id IN (\r\n\t\t\t\t\t\t\tSELECT d.id FROM " . TABLE_PREFIX . "dimensions d WHERE d.is_manageable=1\r\n\t\t\t\t\t\t))\r\n\t\t\t\t\t))";
                 SharingTables::instance()->delete($cond);
             }
         }
         // user has permissions for object_type_ids
         $root_permissions_sharing_table_add = array_var($root_perm_info, 'root_permissions_sharing_table_add');
         if (is_array($root_permissions_sharing_table_add)) {
             $file_ot = ObjectTypes::findByName('file');
             foreach ($root_permissions_sharing_table_add as $object_type_id) {
                 $additional_where = "";
                 $additional_join = "";
                 if ($file_ot->getId() == $object_type_id && Plugins::instance()->isActivePlugin('mail')) {
                     $additional_join .= "INNER JOIN " . TABLE_PREFIX . "project_files e ON e.object_id=o.id";
                     $additional_where .= "AND IF(e.mail_id=0, true, EXISTS (SELECT mac.contact_id FROM " . TABLE_PREFIX . "mail_account_contacts mac \r\n\t\t\t\t\t\t\tWHERE mac.contact_id IN (SELECT cpg.contact_id FROM " . TABLE_PREFIX . "contact_permission_groups cpg WHERE permission_group_id={$group}) \r\n\t\t\t\t\t\t\t\tAND mac.account_id=(SELECT mc.account_id FROM " . TABLE_PREFIX . "mail_contents mc WHERE mc.object_id=e.mail_id)))";
                 }
                 $sql = "SELECT o.id FROM " . TABLE_PREFIX . "objects o {$additional_join} WHERE o.object_type_id = {$object_type_id} AND NOT EXISTS(\r\n\t\t\t\t\t\tSELECT om.object_id FROM " . TABLE_PREFIX . "object_members om WHERE om.object_id=o.id AND om.member_id IN (SELECT m.id FROM " . TABLE_PREFIX . "members m WHERE m.dimension_id IN (\r\n\t\t\t\t\t\t\tSELECT d.id FROM " . TABLE_PREFIX . "dimensions d WHERE d.is_manageable=1\r\n\t\t\t\t\t\t))\r\n\t\t\t\t\t) {$additional_where}";
                 $rows = DB::executeAll($sql);
                 $ids = array_flat($rows);
                 $values = "";
                 foreach ($ids as $id) {
                     $values .= ($values == "" ? "" : ",") . "('{$id}','{$group}')";
                 }
                 DB::execute("INSERT INTO " . TABLE_PREFIX . "sharing_table (object_id, group_id) VALUES {$values} ON DUPLICATE KEY UPDATE group_id=group_id;");
             }
         }
     }
 }
Example #11
0
/**
 * Return true is $user can read the $object. False otherwise.
 * Query executed in sharing table
 *
 * @param Contact $user
 * @param $object_id
 * @return boolean
 */
function can_read_sharing_table(Contact $user, $object_id, $allow_super_admin = true)
{
    if ($allow_super_admin && $user->isAdministrator()) {
        return true;
    }
    $perm = SharingTables::instance()->findOne(array('conditions' => array("object_id=? AND group_id IN (SELECT permission_group_id FROM " . TABLE_PREFIX . "contact_permission_groups WHERE contact_id = '" . $user->getId() . "')", $object_id)));
    return !is_null($perm);
}
 function clearSharingTable()
 {
     return SharingTables::delete("`object_id` = " . $this->getId());
 }
	/**
	 * 
	 * 
	 */
	function addToSharingTable() {
		$oid = $this->getId();
		$tid = $this->getObjectTypeId() ;
		$gids = array();
		
		$table_prefix = defined('FORCED_TABLE_PREFIX') && FORCED_TABLE_PREFIX ? FORCED_TABLE_PREFIX : TABLE_PREFIX;
		
		//1. clear sharing table for this object
		SharingTables::delete("object_id=$oid");
		
		//2. get dimensions of this object's members that defines permissions
		$res = DB::execute("SELECT d.id as did FROM ".$table_prefix."dimensions d INNER JOIN ".$table_prefix."members m on m.dimension_id=d.id
			WHERE m.id IN ( SELECT member_id FROM ".$table_prefix."object_members WHERE object_id = $oid AND is_optimization = 0 ) AND d.defines_permissions = 1");
		$dids_tmp = array();
		while ($row = $res->fetchRow() ) {
			$dids_tmp[$row['did']] = $row['did'] ;
		}
		$res->free();
		$dids = array_values($dids_tmp);
		$dids_tmp = null;
		
		$sql_from = "".$table_prefix."contact_member_permissions cmp
			INNER JOIN ".$table_prefix."members m ON m.id = cmp.member_id
			INNER JOIN ".$table_prefix."dimensions d ON d.id = m.dimension_id";
		
		$sql_where = "member_id IN ( SELECT member_id FROM ".$table_prefix."object_members WHERE object_id = $oid AND is_optimization = 0) AND cmp.object_type_id = $tid";

		//3. If there are dimensions that defines permissions containing any of the object members
		if ( count($dids) ){
			// 3.1 get permission groups with permissions over the object.
			$sql_fields = "permission_group_id  AS group_id";
			
			$sql = "
				SELECT 
				  $sql_fields	
				FROM
				  $sql_from
				WHERE
				  $sql_where AND d.id IN (". implode(',',$dids).")";
				 
			$res = DB::execute($sql);
			$gids_tmp = array();
			while ( $row = $res->fetchRow() ) {
				$gids_tmp[$row['group_id']] = $row['group_id'];
			}
			$res->free();
			
			// allow all permission groups
			$allow_all_rows = DB::executeAll("SELECT DISTINCT permission_group_id FROM ".$table_prefix."contact_dimension_permissions cdp 
				INNER JOIN ".$table_prefix."members m on m.dimension_id=cdp.dimension_id
				WHERE cdp.permission_type='allow all' AND cdp.dimension_id IN (". implode(',',$dids).");");
			
			if (is_array($allow_all_rows)) {
				foreach ($allow_all_rows as $row) {
					$gids_tmp[$row['permission_group_id']] = $row['permission_group_id'];
				}
			}
			
			$gids = array_values($gids_tmp);
			$gids_tmp = null;
			
			// check for mandatory dimensions
			$mandatory_dim_ids = Dimensions::findAll(array('id' => true, 'conditions' => "`defines_permissions`=1 AND `permission_query_method`='".DIMENSION_PERMISSION_QUERY_METHOD_MANDATORY."'"));
			if (count($gids) > 0 && count($mandatory_dim_ids) > 0) {
				$sql = "SELECT om.member_id, m.dimension_id FROM ".$table_prefix."object_members om 
				INNER JOIN ".$table_prefix."members m ON m.id=om.member_id INNER JOIN ".$table_prefix."dimensions d ON d.id=m.dimension_id 
				WHERE om.object_id = $oid AND om.is_optimization = 0 AND d.id IN (".implode(",", $mandatory_dim_ids).")";
				
				// Object members in mandatory dimensions
				$object_member_ids_res = DB::executeAll($sql);
				$mandatory_dim_members = array();
				if (!is_null($object_member_ids_res)) {
					foreach ($object_member_ids_res as $row) {
						if (!isset($mandatory_dim_members[$row['dimension_id']])) $mandatory_dim_members[$row['dimension_id']] = array();
						$mandatory_dim_members[$row['dimension_id']][] = $row['member_id'];
					}
					
					$mandatory_dim_allowed_pgs = array();
					// Check foreach group that it has permissions over at least one member of each mandatory dimension
					foreach ($mandatory_dim_members as $mdim_id => $mmember_ids) {
						$sql = "SELECT pg.id FROM ".$table_prefix."permission_groups pg
						INNER JOIN ".$table_prefix."contact_dimension_permissions cdp ON cdp.permission_group_id=pg.id
						INNER JOIN ".$table_prefix."contact_member_permissions cmp ON cmp.permission_group_id=pg.id
						WHERE cdp.dimension_id = '$mdim_id' AND (
							cdp.permission_type='allow all' OR cdp.permission_type='check' AND cmp.permission_group_id IN (".implode(',', $gids).")
							AND cmp.member_id IN (".implode(',', $mmember_ids).")
						)";
						
						$permission_groups_res = DB::executeAll($sql);
						$mandatory_dim_allowed_pgs[$mdim_id] = array();
						if (!is_null($permission_groups_res)) {
							foreach ($permission_groups_res as $row) {
								if (!in_array($row['id'], $mandatory_dim_allowed_pgs[$mdim_id])) $mandatory_dim_allowed_pgs[$mdim_id][] = $row['id'];
							}
						}
					}

					if (isset($mandatory_dim_allowed_pgs) && count($mandatory_dim_allowed_pgs) > 0) {
						$original_mandatory_dim_allowed_pgs = $mandatory_dim_allowed_pgs;
						$allowed_gids = array_pop($mandatory_dim_allowed_pgs);
						foreach ($mandatory_dim_allowed_pgs as $pg_array) {
							$allowed_gids = array_intersect($allowed_gids, $pg_array);
						}
						
						// If an user has permissions in one dim using a group and in other dim using his personal permissions then add to sharing table its personal permission group
						$pg_ids = array_unique(array_flat($original_mandatory_dim_allowed_pgs));
						$pgs_data = DB::executeAll("SELECT * FROM ".TABLE_PREFIX."permission_groups WHERE id IN (".implode(',',$pg_ids).")");
						$contact_pgs = array();
						$contact_pg_rows = DB::executeAll("SELECT * FROM ".TABLE_PREFIX."contact_permission_groups WHERE permission_group_id IN (".implode(',',$pg_ids).") ORDER BY permission_group_id");
						foreach ($contact_pg_rows as $cpgr) {
							if (!isset($contact_pgs[$cpgr['contact_id']])) $contact_pgs[$cpgr['contact_id']] = array();
							$contact_pgs[$cpgr['contact_id']][] = $cpgr['permission_group_id'];
						}
						
						// each user must have at least one pg for every dimension
						foreach ($contact_pgs as $contact_id => $permission_groups) {
							$has_one = array_flip(array_keys($original_mandatory_dim_allowed_pgs));
							foreach ($has_one as $k => &$v) $v = false;
							
							foreach ($permission_groups as $pg_id) {
								foreach ($original_mandatory_dim_allowed_pgs as $dim_id => $allowedpgs) {
									if (in_array($pg_id, $allowedpgs)) {
										$has_one[$dim_id] = true;
										break;
									}
								}
							}
							// all dims must be true in this array to allow permissions
							$has_permission = !in_array(false, $has_one);
							if ($has_permission) {
								$contact_row = DB::executeOne("SELECT permission_group_id FROM ".TABLE_PREFIX."contacts where object_id = $contact_id");
								if (is_array($contact_row) && $contact_row['permission_group_id'] > 0) {
									$allowed_gids[] = $contact_row['permission_group_id'];
								} 
							}
						}
						
						$gids = array_unique($allowed_gids, SORT_NUMERIC);
					} else {
						$gids = array();
					}
				}
			}
			
		}else { 
			if ( count($this->getMemberIds()) > 0 ) {
				// 3.2 No memeber dimensions defines permissions. 
				// No esta en ninguna dimension que defina permisos, El objecto esta en algun lado
				// => En todas las dimensiones en la que está no definen permisos => Busco todos los grupos
				$gids = PermissionGroups::instance()->findAll(array('id' => true));
			}
		}
		
		if(count($gids)) {
			$stManager = SharingTables::instance();
			$stManager->populateGroups($gids, $oid);
			$gids = null;
		} 
		
	}
Example #14
0
function sharing_table_partial_rebuild()
{
    $start_date = config_option('last_sharing_table_rebuild');
    _log("Rebuilding sharing table since {$start_date} ...");
    $obj_count = SharingTables::instance()->rebuild($start_date);
    _log("Finished rebuilding sharing table - {$obj_count} objects.");
}