diff --git a/phpgwapi/inc/class.acl2.inc.php b/phpgwapi/inc/class.acl2.inc.php new file mode 100644 index 0000000000..302ce94191 --- /dev/null +++ b/phpgwapi/inc/class.acl2.inc.php @@ -0,0 +1,363 @@ +1); //group 0 is for all users + var $memberships_sql = '0'; //group 0 is for all users + var $rights_cache = Array(); + var $masks_cache = Array(); + var $previous_location; // used for inheritance + var $db; + + /*************************************************************************\ + * These lines load up the templates class and set some default values * + \*************************************************************************/ + function acl2() + { + $expected_args[0] = Array('name'=>'account_id','default'=>$GLOBALS['phpgw_info']['user']['userid'], 'type'=>'number'); + $expected_args[1] = Array('name'=>'host_id','default'=>0, 'type'=>'number'); + $expected_args[2] = Array('name'=>'app_id','default'=>$GLOBALS['phpgw']->applications->data[$GLOBALS['phpgw_info']['flags']['currentapp']]['id'], 'type'=>'number'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $this->db = $GLOBALS['phpgw']->db; + $this->account_id = $args['account_id']; + $this->host_id = $args['host_id']; + $this->app_id = $args['app_id']; + } + + function get_memberships () + { + $expected_args[0] = Array('name'=>'account_id','default'=>$this->account_id, 'type'=>'number'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $sql = "SELECT acl_location,acl_rights FROM phpgw_acl2 + WHERE ( acl_host='".$this->host_id."' and acl_appid = 0 and acl_account = ".$args['account_id'].")"; + $this->db->query($sql,__LINE__,__FILE__); + + while ($this->db->next_record()) + { + if(!isset($this->memberships[$this->db->f('acl_location')])) + { + $this->memberships[$this->db->f('acl_location')] = $this->db->f('acl_rights'); + $this->memberships_sql .= ','.$this->db->f('acl_location'); + $this->get_memberships(Array('account_id'=>$this->db->f('acl_location'))); + } + } + } + + function cache_rights() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + if(isset($this->rights_cache[$args['app_id']][$args['location']])) + { + return; + } + + $sql = "SELECT acl_rights,acl_type,acl_data,acl_location FROM phpgw_acl2 WHERE (acl_appid = '".$args['app_id']."' "; + $sql .= " and (acl_account in (".$this->account_id.",".$this->memberships_sql.'))'; + $sql .= " and (".$this->get_location_list($args['location'],$args['app_id']).")"; + $sql .= ') ORDER BY acl_location, acl_type DESC'; + + $this->db->query($sql,__LINE__,__FILE__); + while ($this->db->next_record()) + { + if($this->rights_cache[$args['app_id']][$args['location']] == 0) + { + if ($this->previous_location != '') + { + $this->rights_cache[$args['app_id']][$this->db->f('acl_location')] = $this->bit_mask($this->rights_cache[$args['app_id']][$this->previous_location], $this->masks_cache[$args['app_id']][$this->previous_location]); + } + else + { + $this->masks_cache[$args['app_id']][$this->db->f('acl_location')] = 0; + $this->rights_cache[$args['app_id']][$this->db->f('acl_location')] = 0; + } + } + + if((int)$this->db->f('acl_type') == 0) + { + $this->rights_cache[$args['app_id']][$this->db->f('acl_location')] = $this->bit_set($this->rights_cache[$args['app_id']][$this->db->f('acl_location')],(int)$this->db->f('acl_rights')); + } + else + { + $this->masks_cache[$args['app_id']][$this->db->f('acl_location')] = $this->bit_set($this->rights_cache[$args['app_id']][$this->db->f('acl_location')],(int)$this->db->f('acl_rights')); + } + $this->previous_location = $this->db->f('acl_location'); + } + $this->previous_location = ''; + } + + function get_location_list() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $expected_args[2] = Array('name'=>'return','default'=>'sql', 'type'=>'alpha'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + if(!strstr($args['location'], '.')) + { + $location_list = Array('.','.'.$args['location'],$args['location']); + $sql = "acl_location in ('.', '.'.".$args['location'].",".$args['location'].")"; + return $sql; + } + $location_list = explode('.',$args['location']); + $num = count($location_list); + for ($i=0; $i < $num; $i++) + { + if(isset($location_list[$i-1])) + { + if($location_list[$i-1] != '.') + { + $location_list[$i] = $location_list[$i-1].'.'.$location_list[$i]; + } + else + { + $location_list[$i] = $location_list[$i-1].$location_list[$i]; + } + } + else + { + $location_list[$i] = '.'; + } + + if(!isset($sql)) + { + $sql = "acl_location in ('".$location_list[$i]."'"; + } + else + { + $sql .= ",'".$location_list[$i]."'"; + } + + if($args['return'] != 'array' && !isset($this->rights_cache[$args['app_id']][$args['location']])) + { + $this->rights_cache[$args['app_id']][$location_list[$i]] = 0; + $this->masks_cache[$args['app_id']][$location_list[$i]] = 0; + } + } + $sql .= ')'; + if ($args['return'] == 'array') + { + return $location_list; + } + return $sql; + } + + function check() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'required','default'=>1, 'type'=>'number'); + $expected_args[2] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $this->cache_rights($args['location'],$args['app_id']); + return $this->bit_check($this->rights_cache[$args['app_id']][$args['location']],$args['required']); + } + + /*! + @function add + @abstract Adds ACL record to $acl->data + @discussion Adds ACL record to $acl->data.
+ Syntax: array add()
+ Example1: acl->add(); + @param $appname default False derives value from $phpgw_info['flags']['currentapp'] + @param $location location + @param $rights rights + */ + function add() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'rights','default'=>1, 'type'=>'number'); + $expected_args[2] = Array('name'=>'type','default'=>0, 'type'=>'number'); + $expected_args[3] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $expected_args[4] = Array('name'=>'data','default'=>NULL, 'type'=>'any'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $sql = "SELECT acl_rights FROM phpgw_acl2 WHERE (acl_appid = '".$args['app_id']."' "; + $sql .= " and acl_account = ".$this->account_id; + $sql .= " and acl_location = '".$args['location']."' and acl_type=".$args['type'].")"; + $this->db->query($sql,__LINE__,__FILE__); + if($this->db->num_rows() != 0) + { + $this->db->next_record(); + $newrights = $this->bit_set($args['rights'], (int)$this->db->f('acl_rights')); + $sql = "UPDATE phpgw_acl2 SET acl_rights =".$newrights; + $sql .= " WHERE acl_host=".$this->host_id." AND acl_appid=".$args['app_id']." AND acl_account=".$this->account_id." AND acl_location='".$args['location']."' AND acl_type=".$args['type']; + } + else + { + $sql = "INSERT INTO phpgw_acl2 (acl_host,acl_appid,acl_account,acl_location,acl_rights,acl_type,acl_data) VALUES (".$this->host_id.",".$args['app_id'].",".$this->account_id.",'".$args['location']."',".$args['rights'].",".$args['type'].",'".$args['data']."')"; + } + $this->db->query($sql,__LINE__,__FILE__); + $this->rights_cache = Array(); + $this->masks_cache = Array(); + } + + function set() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'rights','default'=>1, 'type'=>'number'); + $expected_args[2] = Array('name'=>'type','default'=>0, 'type'=>'number'); + $expected_args[3] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $expected_args[4] = Array('name'=>'data','default'=>NULL, 'type'=>'any'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $sql = "SELECT acl_rights FROM phpgw_acl2 WHERE (acl_appid = '".$args['app_id']."' "; + $sql .= " and acl_account = ".$this->account_id; + $sql .= " and acl_location = '".$args['location']."' and acl_type=".$args['type'].")"; + $this->db->query($sql,__LINE__,__FILE__); + if($this->db->num_rows() != 0) + { + if((int)$args['rights'] == 0) + { + $sql = "DELETE FROM phpgw_acl2"; + } + else + { + $sql = "UPDATE phpgw_acl2 SET acl_rights =".$args['rights']; + } + $sql .= " WHERE acl_host=".$this->host_id." AND acl_appid=".$args['app_id']." AND acl_account=".$this->account_id." AND acl_location='".$args['location']."' AND acl_type=".$args['type']; + $this->db->query($sql,__LINE__,__FILE__); + } + else + { + if($args['rights'] != 0) + { + $sql = "INSERT INTO phpgw_acl2 (acl_host,acl_appid,acl_account,acl_location,acl_rights,acl_type,acl_data) VALUES (".$this->host_id.",".$args['app_id'].",".$this->account_id.",'".$args['location']."',".$args['rights'].",".$args['type'].",'".$args['data']."')"; + $this->db->query($sql,__LINE__,__FILE__); + } + } + $this->rights_cache = Array(); + $this->masks_cache = Array(); + } + + function remove() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'rights','default'=>1, 'type'=>'number'); + $expected_args[2] = Array('name'=>'type','default'=>0, 'type'=>'number'); + $expected_args[3] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $expected_args[4] = Array('name'=>'data','default'=>NULL, 'type'=>'any'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $sql = "SELECT acl_rights FROM phpgw_acl2 WHERE (acl_appid = '".$args['app_id']."' "; + $sql .= " and acl_account = ".$this->account_id; + $sql .= " and acl_location = '".$args['location']."' and acl_type=".$args['type'].")"; + $this->db->query($sql,__LINE__,__FILE__); + if($this->db->num_rows() != 0) + { + $this->db->next_record(); +//echo '$args[rights] = '.$args['rights'].'
'; +//echo '$this->db->f(acl_rights) = '.$this->db->f('acl_rights').'
'; + $newrights = $this->bit_mask((int)$this->db->f('acl_rights'),$args['rights']); +//echo 'newrights = '.$newrights.'
'; + if ($newrights != 0) + { + $sql = "UPDATE phpgw_acl2 SET acl_rights =".$newrights; + } + else + { + $sql = "DELETE FROM phpgw_acl2"; + } + $sql .= " WHERE acl_host=".$this->host_id." AND acl_appid=".$args['app_id']." AND acl_account=".$this->account_id." AND acl_location='".$args['location']."' AND acl_type=".$args['type']; + $this->db->query($sql,__LINE__,__FILE__); + $this->rights_cache = Array(); + $this->masks_cache = Array(); + } + } + + /*************************************************************************\ + * Non-standard functions. Should only be used for ACL management needs * + \*************************************************************************/ + function check_specific() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'required','default'=>1, 'type'=>'number'); + $expected_args[2] = Array('name'=>'account_id','default'=>$this->account_id, 'type'=>'number'); + $expected_args[3] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $sql = "SELECT acl_rights,acl_type,acl_data FROM phpgw_acl2 WHERE (acl_appid = '".$args['app_id']."' "; + $sql .= " and acl_account = ".$args['account_id']; + $sql .= " and acl_location = '".$args['location']."' and acl_type=0)"; + $this->db->query($sql,__LINE__,__FILE__); + $rights = 0; + while ($this->db->next_record()) + { + $rights = $this->bit_set($rights,(int)$this->db->f('acl_rights')); + } + return $this->bit_check($rights,$args['required']); + } + + /* I dont feel this function will be needed, and plan to remove it when certain. + function check_location() + { + $expected_args[0] = Array('name'=>'location','default'=>'##REQUIRED##', 'type'=>'alphanumeric'); + $expected_args[1] = Array('name'=>'required','default'=>1, 'type'=>'number'); + $expected_args[2] = Array('name'=>'app_id','default'=>$this->app_id, 'type'=>'number'); + $recieved_args = func_get_args(); + $args = safe_args($expected_args, $recieved_args,__LINE__,__FILE__); + + $sql = "SELECT acl_rights,acl_type,acl_data FROM phpgw_acl2 WHERE (acl_appid = '".$args['app_id']."' "; + $sql .= " and (acl_account in (".$this->account_id.",".$this->memberships_sql.'))'; + $sql .= " and acl_location = '".$args['location']."' and acl_type=0)"; + $this->db->query($sql,__LINE__,__FILE__); + $rights = 0; + while ($this->db->next_record()) + { + $rights = $this->bit_set($rights,(int)$this->db->f('acl_rights')); + } + return $this->bit_check($rights,$args['required']); + } + */ + + + /*************************************************************************\ + * Support functions * + \*************************************************************************/ + /*! + @function bit_set + @abstract add/turn_on new bit to current value + */ + function bit_set($rights, $new) + { + return $rights |= $new; + } + + /*! + @function bit_mask + @abstract mask/turn_off new bit from current value + */ + function bit_mask($rights, $mask) + { + return $rights &= ~$mask; + } + + /*! + @function bit_check + @abstract check if required bit is set/turned_on in the rights + */ + function bit_check($rights, $required) + { + return ($rights & $required); + } + } +?> diff --git a/phpgwapi/inc/class.acl2.sql b/phpgwapi/inc/class.acl2.sql new file mode 100644 index 0000000000..2f9d9ed6db --- /dev/null +++ b/phpgwapi/inc/class.acl2.sql @@ -0,0 +1,25 @@ +# +# Table structure for table 'phpgw_acl2' +# + +CREATE TABLE `phpgw_acl2` ( + `acl_host` int(11) NOT NULL default '0', + `acl_appid` int(11) NOT NULL default '0', + `acl_account` int(11) NOT NULL default '0', + `acl_location` varchar(255) NOT NULL default '', + `acl_rights` int(11) default NULL, + `acl_type` tinyint(4) NOT NULL default '0', + `acl_data` text +); + +# +# Sample data for table 'phpgw_acl2' +# + +INSERT INTO `phpgw_acl2` VALUES("0", "0", "1", "5", "1", "0", NULL); +INSERT INTO `phpgw_acl2` VALUES("0", "0", "5", "6", "1", "0", NULL); +INSERT INTO `phpgw_acl2` VALUES("0", "1", "1", ".run", "1", "0", NULL); +INSERT INTO `phpgw_acl2` VALUES("0", "1", "1", ".one.three.four", "1", "0", NULL); +INSERT INTO `phpgw_acl2` VALUES("0", "1", "6", ".one.two", "3", "0", NULL); +INSERT INTO `phpgw_acl2` VALUES("0", "1", "1", ".one.two.three", "2", "0", ""); +INSERT INTO `phpgw_acl2` VALUES("0", "1", "1", ".one.two", "3", "1", "");