PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/s3db3.5.10/s3dbcore/s3list.php

https://code.google.com/p/s3db/
PHP | 379 lines | 235 code | 111 blank | 33 comment | 32 complexity | c22779c61c9dd88864ca94f210022d4a MD5 | raw file
  1. <?php
  2. #function s3list lists all the resources in the element following "uid" in the s3core structure. For example, if element == rules, then s3list will list all the rules on a given project_id, provided project_id is specified. If element is statements, then s3list wil be expecting rule_id and resource_id or just one of them
  3. #s3list checks permissions directly
  4. function s3list($s3ql)
  5. {$regexp = $GLOBALS['regexp'];
  6. $dbstruct = $GLOBALS['dbstruct'];
  7. extract($s3ql);
  8. if (is_array($where)) {
  9. extract($where);
  10. }
  11. if(!$user_id)
  12. {return ('User authentication is required');
  13. exit;
  14. }
  15. if ($order_by) {
  16. $order_by = ' order by '.$order_by;
  17. }
  18. if (!$select) {
  19. $select = '*';
  20. }
  21. if (!$from) {
  22. $from = 'projects';
  23. }
  24. $equality = '='; #by default, equality on query end be this, unless specified that equality should be a regular expression
  25. $cols = $dbstruct[$from];
  26. #Error messages
  27. $syntax_message = "Please provide all the necessary fields. For syntax instructions refer to <a href='http://www.s3db.org/documentation.html'>S3DB Documentation</a>";
  28. $success = '<error>0</error><message>'.$from.' '.$action.'ed '.$element_id.'</message>';
  29. $not_a_query = '<error>1</error><message>'.$from.' is not a valid S3element. Valid elements: groups, users, keys, projects, rules, statements, classes, instances, rulelog";</message>';
  30. $something_went_wrong = '<error>2</error><message>Failed to '.$action.' '.$from.'</message>';
  31. $something_missing = '<error>3</error><message>'.$syntax_message.'</message>';
  32. $repeating_action = '<error>4</error>';
  33. $no_permission_message = '<error>5</error>';
  34. $something_does_not_exist = '<error>5</error>';
  35. $wrong_query_for_purpose = '<error>6</error>';
  36. $wrong_input = '<error>7</error>';
  37. $no_output = '<error>8</error>';
  38. #alternative IDs that can be used for the query
  39. $alt = array('keys'=>array('key_id'),
  40. 'rulelog'=>array('rule_id'),
  41. 'users'=>array('group_id', 'project_id'),
  42. 'groups'=>array('user_id'),
  43. 'projects'=>array('user_id'),
  44. 'classes'=>array('project_id', 'rule_id'),
  45. 'rules'=>array('project_id', 'class_id'),
  46. 'instances'=>array('class_id', 'project_id'),
  47. 'statements'=>array('rule_id', 'instance_id', 'project_id'),
  48. 'files'=>array('statement_id', 'rule_id', 'instance_id', 'project_id'));
  49. #if from is not one of these elements, sent the user back, query is invalid!
  50. if (!in_array($from, array_keys($alt))) {
  51. #check if user is inputing a sigular of one of the alt plurals
  52. $plurals = array_keys($alt);
  53. $singulars = array('key', 'rulelog', 'user', 'group','project', 'class', 'rule', 'instance', 'statement', 'file');
  54. $from = str_replace($singulars, $plurals, $from);
  55. #if still not in array, definitelly exit;
  56. if (!in_array($from, array_keys($alt))) {
  57. return ($not_a_query);
  58. }
  59. }
  60. #now replace on "where" the correct s3db names
  61. $s3map = array('users'=>array('user_id'=>'account_id',
  62. 'login'=>'account_lid',
  63. 'password'=>'account_pwd',
  64. 'username'=>'account_uname',
  65. 'email'=>'account_email',
  66. 'phone'=>'account_phone',
  67. 'address'=>'addr1',
  68. 'address2'=>'addr2',
  69. 'city'=>'city',
  70. 'state'=>'state',
  71. 'postal_code'=>'postal_code',
  72. 'country'=>'country'),
  73. 'groups'=>array('group_id'=>'account_id',
  74. 'groupname'=>'account_lid'),
  75. 'keys'=>array(),
  76. 'accesslog'=>array('account_lid'=>'login_id', 'time'=>'login_timestamp',),
  77. 'projects'=>array(),
  78. 'project'=>array(),
  79. 'instances'=>array('class_id'=>'resource_class_id',
  80. 'instance_id'=>'resource_id'),
  81. 'instance'=>array('class_id'=>'resource_class_id',
  82. 'instance_id'=>'resource_id'),
  83. 'classes'=>array('class_id'=>'resource_id'),
  84. 'class'=>array('class_id'=>'resource_id'),
  85. 'rules'=>array(),
  86. 'rule'=>array(),
  87. 'statements'=>array('instance_id'=>'resource_id'),
  88. 'statement'=>array('instance_id'=>'resource_id'),
  89. 'files'=>array());
  90. foreach ($alt[$from] as $s3id) {
  91. $s3dbId = $s3map[$from][$s3id];
  92. if ($s3dbId=='') {
  93. $s3dbId = $s3id;
  94. }
  95. if ($where[$s3id]!='') {
  96. #does it exist? What sort of resource is this? Type of id should be identified in the first letter (Class_id is C, rule_id is R...)
  97. $CRISP = strtoupper(substr($s3id, 0, 1));
  98. $id = $CRISP.$where[$s3id];
  99. $info[$where[$s3id]] = s3info(str_replace('_id', '', $s3id), $where[$s3id], $db);
  100. if (!is_array($info)) {
  101. return ($something_does_not_exist.'<message>'.$s3id.' '.$where[$s3id].' does not exist</message>');
  102. }
  103. if (!permissionOnResource(compact('user_id', 'db', 'id'))) {
  104. return ($no_permission_message.'<message>user does not have permission on '.$id.'</message>');
  105. }
  106. #does user have permission on this/these resources?
  107. $query_end .= " and ".$s3dbId." ".$equality." '".$where[$s3id]."'";
  108. }
  109. }
  110. $toreplace = array_keys($s3map[$from]);
  111. $replacements = array_values($s3map[$from]);
  112. $s3ql['select'] = str_replace($toreplace, $replacements, $query_end);
  113. #restrict the query to the rules where user is allowed
  114. $user_projects = findUserProjects($user_id, $db); #alternative to re-using s3list to query projects - still not sure which is faster...
  115. $s3ql=compact('user_id','db');
  116. $s3ql['select']='project_id';
  117. $s3ql['from']='projects';
  118. #$user_projects = s3list($s3ql);
  119. if (is_array($user_projects)) {
  120. $user_permission_list = create_permission_list($user_projects);
  121. $user_project_list = create_project_id_list($user_projects);
  122. }
  123. if (!is_array($user_projects)) {
  124. return ($no_output.'<message>User does not have permission in any project</message>');
  125. }
  126. if ($user_id!='1' && ereg('(projects|classes|rules|instances|statements|rulelog)', $from) && $where['project_id']=='') {
  127. #If query end is empty, it means no id was supplied. So list all 'resources' where user is allowed, which implies making a query in project.
  128. $query_end .= " and project_id ".$regexp." '".$user_project_list."'";
  129. }
  130. #When rule_id (or class_id) is supplied check if user has permission on a project that has permission on that rule (or class). If rule_id is not supplied
  131. #When instance_id is supplied, check if user has permission on the rule (or class) of that instance
  132. #array_keys contains the things to replace and array_values the replacements
  133. switch ($from) {
  134. case 'keys':{
  135. $table = 'access_keys';
  136. $required = "expires > '".date('Y-m-d')."'";
  137. if ($user_id!='1') {
  138. $required .= " and (account_id = '".$user_id."')";
  139. }
  140. break;
  141. }
  142. case 'rulelog':{
  143. $table = 'rule_change_log';
  144. $required = "rule_id !=''";
  145. break;
  146. }
  147. case 'users':{#expecting group_id or project_id
  148. #remove password from query fields
  149. $table = 'account';
  150. $required = "account_type = 'u' and account_status = 'A'";
  151. break;
  152. }
  153. case 'groups':{
  154. $table = 'account';
  155. $required = "account_type = 'g' and account_status = 'A'";
  156. break;
  157. }
  158. case 'projects':{
  159. $table = 'project';
  160. $required = "project_status = 'A'";
  161. #if user is not admin, retrict this query to the projects user can view by extending queryend
  162. if ($user_id!='1') {
  163. $required .= " and (project_owner = '".$user_id."' or project_id in (select acl_project_id from s3db_project_acl where acl_account = '".$user_id."' and acl_rights!='0'))";
  164. }
  165. break;
  166. }
  167. case 'classes':{
  168. #$table = 'resource';
  169. $table = 'resource, s3db_rule';
  170. $required = "iid = '0'";
  171. $select = str_replace('project_id', 's3db_rule.project_id', $select);
  172. $select = str_replace('notes', 's3db_resource.notes', $select);
  173. if ($where['project_id']!='') {
  174. $query_end = str_replace("and project_id = '".$project_id."'", "and (entity = subject and verb = 'has UID' and object = 'UID' and s3db_resource.project_id = s3db_rule.project_id and (s3db_rule.project_id = '".$project_id."' or s3db_rule.permission ".$regexp." '(_|^)".$project_id."_'))", $query_end);
  175. }
  176. #restrict the query to the rules where user is allowed
  177. $query_end = str_replace("and project_id ".$regexp." '".$user_project_list."'", "and subject = entity and object = 'UID' and s3db_rule.project_id = s3db_resource.project_id and (s3db_rule.project_id ".$regexp." '".$user_project_list."' or s3db_rule.permission ".$regexp." '".$user_permission_list."')", $query_end);
  178. break;
  179. }
  180. case 'instances':{
  181. $table = 'resource';
  182. $required = "iid = '1'";
  183. #to avoid having to call s3list again, created this function that simulates finding user classes
  184. $classes = findUserClasses($user_id, $db);
  185. if (!is_array($classes)) {
  186. return ($no_output.'<message>User does not have permission in any classes</message>');
  187. }
  188. $classes_list = create_class_id_list($classes);
  189. $query_end = str_replace("and project_id ".$regexp." '".$user_project_list."'", "and resource_class_id ".$regexp." '".$classes_list."'", $query_end);
  190. break;
  191. }
  192. case 'rules':{
  193. $table = 'rule';
  194. $required = "rule_id !='0'";
  195. if ($where['project_id']!='') {
  196. $query_end = str_replace("and project_id = '".$project_id."'", "and (project_id ".$regexp." '^".$project_id."$' or permission ".$regexp." '(_|^)".$project_id."_')", $query_end);
  197. if ($where['class_id']!='') {
  198. $class_info = s3info('class', $where['class_id'], $db);
  199. $query_end = str_replace("and class_id = '".$where['class_id']."'", "and subject = '".$class_info['entity']."'", $query_end);
  200. }
  201. }
  202. elseif ($where['class_id']!='') { #no project_id but w/ class_id. If no project_id is indicated, it will have to find the correct subjects (which can be repeated if queried on several projects)
  203. $class_info = s3info('class', $where['class_id'], $db);
  204. $query_end = str_replace("and class_id = '".$where['class_id']."'", "and (subject_id = '".$where['class_id']."' or (subject = '".$class_info['entity']."' and project_id = '".$class_info['project_id']."'))",$query_end); #all that don't belong to this project will have to be queried by class_id.
  205. }
  206. else {
  207. $query_end = str_replace("and project_id ".$regexp." '".$user_project_list."'", " and (project_id ".$regexp." '".$user_project_list."' or permission ".$regexp." '".$user_permission_list."')", $query_end);
  208. }
  209. break;
  210. }
  211. case 'statements':{
  212. $table = 'statement';
  213. $required = "status ='A'";
  214. #user only has permission to a number of statement, those where he has permission on rule. Permission on rule propagates to permission on statement
  215. #alternative to calling s3list again:
  216. $rules = findUserRules($user_id, $db);
  217. #echo '<pre>';print_r($rules);
  218. #exit;
  219. if (!is_array($rules)) {
  220. return ($no_output.'<message>User does not have permission in any rules</message>');
  221. }
  222. else {
  223. $user_rule_list = create_rule_id_list($rules);
  224. $query_end = str_replace("and project_id ".$regexp." '".$user_project_list."'", "and rule_id ".$regexp." '".$user_rule_list."'", $query_end);
  225. }
  226. break;
  227. }
  228. }
  229. #POSSIBLY MOVE THIS PART TO A SEPARATE FUNCTION!!
  230. $sql = "select ".$select." from s3db_".$table." where ".$required." ".$query_end.$order_by;
  231. #echo $sql.'<br>';
  232. #exit;
  233. $db->query($sql, __LINE__, __FILE__);
  234. while($db->next_record())
  235. {
  236. $resultStr .= "\$data[] = Array(";
  237. if ($extracol!='')
  238. $resultStr .= "'".$extracol."'=>'".$db->f($SQLfun)."',";
  239. foreach ($cols as $col)
  240. {
  241. #if($db->f($col)!='')
  242. {
  243. $resultStr .= "'".$col."'=>'".addslashes($db->f($col))."'";
  244. if($col != end($cols))
  245. $resultStr .= ",";
  246. }
  247. }
  248. $resultStr .= ");";
  249. }
  250. #evaluate the long string
  251. eval($resultStr);
  252. #echo '<pre>';print_r($data);
  253. if (is_array($data)) {
  254. if (!$nomap) {#include stuff relevant for each element
  255. foreach ($data as $element_info) {
  256. #$element_info['dataAcl'] = instanceAcl(array('instance_info'=>$element_info, 'user_id'=>$user_id, 'db'=>$db));
  257. $data1[] = include_all(array('elements'=>$from, 'element_info'=>$element_info, 'user_id'=>$user_id, 'db'=>$db));
  258. }
  259. $data = $data1;
  260. }
  261. }
  262. else {
  263. $data = $no_output.'<message>Your query returned no results</message>';
  264. }
  265. #echo '<pre>';print_r($data);
  266. return ($data);
  267. }
  268. ?>