function s3list($s3ql) { $regexp = $GLOBALS['regexp']; $dbstruct = $GLOBALS['dbstruct']; extract($s3ql); if (is_array($where)) { extract($where); } if (!$user_id) { return 'User authentication is required'; exit; } if ($order_by) { $order_by = ' order by ' . $order_by; } if (!$select) { $select = '*'; } if (!$from) { $from = 'projects'; } $equality = '='; #by default, equality on query end be this, unless specified that equality should be a regular expression $cols = $dbstruct[$from]; #Error messages $syntax_message = "Please provide all the necessary fields. For syntax instructions refer to <a href='http://www.s3db.org/documentation.html'>S3DB Documentation</a>"; $success = '<error>0</error><message>' . $from . ' ' . $action . 'ed ' . $element_id . '</message>'; $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>'; $something_went_wrong = '<error>2</error><message>Failed to ' . $action . ' ' . $from . '</message>'; $something_missing = '<error>3</error><message>' . $syntax_message . '</message>'; $repeating_action = '<error>4</error>'; $no_permission_message = '<error>5</error>'; $something_does_not_exist = '<error>5</error>'; $wrong_query_for_purpose = '<error>6</error>'; $wrong_input = '<error>7</error>'; $no_output = '<error>8</error>'; #alternative IDs that can be used for the query $alt = array('keys' => array('key_id'), 'rulelog' => array('rule_id'), 'users' => array('group_id', 'project_id'), 'groups' => array('user_id'), 'projects' => array('user_id'), 'classes' => array('project_id', 'rule_id'), 'rules' => array('project_id', 'class_id'), 'instances' => array('class_id', 'project_id'), 'statements' => array('rule_id', 'instance_id', 'project_id'), 'files' => array('statement_id', 'rule_id', 'instance_id', 'project_id')); #if from is not one of these elements, sent the user back, query is invalid! if (!in_array($from, array_keys($alt))) { #check if user is inputing a sigular of one of the alt plurals $plurals = array_keys($alt); $singulars = array('key', 'rulelog', 'user', 'group', 'project', 'class', 'rule', 'instance', 'statement', 'file'); $from = str_replace($singulars, $plurals, $from); #if still not in array, definitelly exit; if (!in_array($from, array_keys($alt))) { return $not_a_query; } } #now replace on "where" the correct s3db names $s3map = array('users' => array('user_id' => 'account_id', 'login' => 'account_lid', 'password' => 'account_pwd', 'username' => 'account_uname', 'email' => 'account_email', 'phone' => 'account_phone', 'address' => 'addr1', 'address2' => 'addr2', 'city' => 'city', 'state' => 'state', 'postal_code' => 'postal_code', 'country' => 'country'), 'groups' => array('group_id' => 'account_id', 'groupname' => 'account_lid'), 'keys' => array(), 'accesslog' => array('account_lid' => 'login_id', 'time' => 'login_timestamp'), 'projects' => array(), 'project' => array(), 'instances' => array('class_id' => 'resource_class_id', 'instance_id' => 'resource_id'), 'instance' => array('class_id' => 'resource_class_id', 'instance_id' => 'resource_id'), 'classes' => array('class_id' => 'resource_id'), 'class' => array('class_id' => 'resource_id'), 'rules' => array(), 'rule' => array(), 'statements' => array('instance_id' => 'resource_id'), 'statement' => array('instance_id' => 'resource_id'), 'files' => array()); foreach ($alt[$from] as $s3id) { $s3dbId = $s3map[$from][$s3id]; if ($s3dbId == '') { $s3dbId = $s3id; } if ($where[$s3id] != '') { #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...) $CRISP = strtoupper(substr($s3id, 0, 1)); $id = $CRISP . $where[$s3id]; $info[$where[$s3id]] = s3info(str_replace('_id', '', $s3id), $where[$s3id], $db); if (!is_array($info)) { return $something_does_not_exist . '<message>' . $s3id . ' ' . $where[$s3id] . ' does not exist</message>'; } if (!permissionOnResource(compact('user_id', 'db', 'id'))) { return $no_permission_message . '<message>user does not have permission on ' . $id . '</message>'; } #does user have permission on this/these resources? $query_end .= " and " . $s3dbId . " " . $equality . " '" . $where[$s3id] . "'"; } } $toreplace = array_keys($s3map[$from]); $replacements = array_values($s3map[$from]); $s3ql['select'] = str_replace($toreplace, $replacements, $query_end); #restrict the query to the rules where user is allowed $user_projects = findUserProjects($user_id, $db); #alternative to re-using s3list to query projects - still not sure which is faster... $s3ql = compact('user_id', 'db'); $s3ql['select'] = 'project_id'; $s3ql['from'] = 'projects'; #$user_projects = s3list($s3ql); if (is_array($user_projects)) { $user_permission_list = create_permission_list($user_projects); $user_project_list = create_project_id_list($user_projects); } if (!is_array($user_projects)) { return $no_output . '<message>User does not have permission in any project</message>'; } if ($user_id != '1' && ereg('(projects|classes|rules|instances|statements|rulelog)', $from) && $where['project_id'] == '') { #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. $query_end .= " and project_id " . $regexp . " '" . $user_project_list . "'"; } #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 #When instance_id is supplied, check if user has permission on the rule (or class) of that instance #array_keys contains the things to replace and array_values the replacements switch ($from) { case 'keys': $table = 'access_keys'; $required = "expires > '" . date('Y-m-d') . "'"; if ($user_id != '1') { $required .= " and (account_id = '" . $user_id . "')"; } break; case 'rulelog': $table = 'rule_change_log'; $required = "rule_id !=''"; break; case 'users': #expecting group_id or project_id #remove password from query fields $table = 'account'; $required = "account_type = 'u' and account_status = 'A'"; break; case 'groups': $table = 'account'; $required = "account_type = 'g' and account_status = 'A'"; break; case 'projects': $table = 'project'; $required = "project_status = 'A'"; #if user is not admin, retrict this query to the projects user can view by extending queryend if ($user_id != '1') { $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'))"; } break; case 'classes': #$table = 'resource'; $table = 'resource, s3db_rule'; $required = "iid = '0'"; $select = str_replace('project_id', 's3db_rule.project_id', $select); $select = str_replace('notes', 's3db_resource.notes', $select); if ($where['project_id'] != '') { $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); } #restrict the query to the rules where user is allowed $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); break; case 'instances': $table = 'resource'; $required = "iid = '1'"; #to avoid having to call s3list again, created this function that simulates finding user classes $classes = findUserClasses($user_id, $db); if (!is_array($classes)) { return $no_output . '<message>User does not have permission in any classes</message>'; } $classes_list = create_class_id_list($classes); $query_end = str_replace("and project_id " . $regexp . " '" . $user_project_list . "'", "and resource_class_id " . $regexp . " '" . $classes_list . "'", $query_end); break; case 'rules': $table = 'rule'; $required = "rule_id !='0'"; if ($where['project_id'] != '') { $query_end = str_replace("and project_id = '" . $project_id . "'", "and (project_id " . $regexp . " '^" . $project_id . "\$' or permission " . $regexp . " '(_|^)" . $project_id . "_')", $query_end); if ($where['class_id'] != '') { $class_info = s3info('class', $where['class_id'], $db); $query_end = str_replace("and class_id = '" . $where['class_id'] . "'", "and subject = '" . $class_info['entity'] . "'", $query_end); } } 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) $class_info = s3info('class', $where['class_id'], $db); $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. } else { $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); } break; case 'statements': $table = 'statement'; $required = "status ='A'"; #user only has permission to a number of statement, those where he has permission on rule. Permission on rule propagates to permission on statement #alternative to calling s3list again: $rules = findUserRules($user_id, $db); #echo '<pre>';print_r($rules); #exit; if (!is_array($rules)) { return $no_output . '<message>User does not have permission in any rules</message>'; } else { $user_rule_list = create_rule_id_list($rules); $query_end = str_replace("and project_id " . $regexp . " '" . $user_project_list . "'", "and rule_id " . $regexp . " '" . $user_rule_list . "'", $query_end); } break; } #POSSIBLY MOVE THIS PART TO A SEPARATE FUNCTION!! $sql = "select " . $select . " from s3db_" . $table . " where " . $required . " " . $query_end . $order_by; #echo $sql.'<br>'; #exit; $db->query($sql, __LINE__, __FILE__); while ($db->next_record()) { $resultStr .= "\$data[] = Array("; if ($extracol != '') { $resultStr .= "'" . $extracol . "'=>'" . $db->f($SQLfun) . "',"; } foreach ($cols as $col) { $resultStr .= "'" . $col . "'=>'" . addslashes($db->f($col)) . "'"; if ($col != end($cols)) { $resultStr .= ","; } } $resultStr .= ");"; } #evaluate the long string eval($resultStr); #echo '<pre>';print_r($data); if (is_array($data)) { if (!$nomap) { #include stuff relevant for each element foreach ($data as $element_info) { #$element_info['dataAcl'] = instanceAcl(array('instance_info'=>$element_info, 'user_id'=>$user_id, 'db'=>$db)); $data1[] = include_all(array('elements' => $from, 'element_info' => $element_info, 'user_id' => $user_id, 'db' => $db)); } $data = $data1; } } else { $data = $no_output . '<message>Your query returned no results</message>'; } #echo '<pre>';print_r($data); return $data; }
function remoteURIOLD($uid, $key, $user_id, $db) { #function remoteURI performs a call on a remote Did for retrieving information on a specific s3id #syntax: remoteURI($uid, $key, $db) #uid should be a concatenation of Did and user_id. Did is either a URL or an alphanumeric string that can be called on mothership #echo $uid; #find this user's id #$local_user = $GLOBALS['Did'].'/'.'U'.$user_id; #$myip = captureIp(); #$myip = ($myip!='')?$myip:$_SERVER['SERVER_NAME']; #$local_user = (($_SERVER['HTTPS']!='')?'https://':'http://'.$myip.'/'.strtok($_SERVER['PHP_SELF'], '/')).'/'.'U'.$user_id; #test Did. Is it a url? or a way to find a url? #ereg('(.*)(/|_)(D|U|G|P|C|R|I|S)([0-9]+$)', $uid, $out); #ereg('(D(.*)|http://(.*)|https://(.*))(_|/)(U|G|P|C|R|I|S)([0-9]+$|D|http://|https://)', $uid, $out); $local_user = S3DB_URI_BASE . '/' . 'U' . $user_id; #echo $local_user;exit; $uid_info = uid($uid); #echo $uid; #echo '<pre>';print_r($uid_info);exit; $letter = substr($uid_info['uid'], 0, 1); #echo $uid; if (ereg('^(U|G|P|C|R|I|S)', $uid)) { $uid = substr($uid, 1, strlen($uid)); #if uid brings a letter, leave just a the id $Did = substr($uid_info['Did'], 1, strlen($uid_info['Did'])); } else { $Did = $uid_info['Did']; } $remoteId = $uid_info['uid']; #echo $Did;exit; #echo http_test_existance($Did);exit; #test Did. if is not url, must find url first #First let's try calling the remote resource without authientication; it might be a public resource ereg('^(D|http.*)/(D|P|C|R|I|S|G|U)([0-9]+)', $uid, $uid_in_remote); $did_call = $Did . '/URI.php?uid=' . $uid_in_remote[2] . $uid_in_remote[3] . '&format=php'; $did_data = stream_get_contents(@fopen($did_call, 'r')); $msg = unserialize($did_data); $msg = $msg[0]; #$msg=html2cell($did_data);$msg = $msg[2]; if ($msg['uri'] != '') { #Good, it's a public resource return $msg; } $did_call = $Did . '/URI.php?key=' . $key . '&user_id=' . $local_user . '&uid=' . $uid_in_remote[2] . $uid_in_remote[3]; $did_data = stream_get_contents(@fopen($did_call, 'r')); if ($did_data == '') { $did_url = findDidUrl($Did, $db); #internal - does it exist on inside table? $dateDiff_min = (strtotime(date('Y-m-d H:i:s')) - strtotime($did_url['checked_valid'])) / 60; #did_url empty? Mothership working?#checked no longer than an hour? if (empty($did_url['url']) || $dateDiff_min > 60) { $mothership = $uid_info['MS'] != '' ? $uid_info['MS'] : $GLOBALS['s3db_info']['deployment']['mothership']; #because s3db.org is under sourceforge, find the real url of that mother ship first. if (ereg('http://s3db.org|http://www.s3db.org', $mothership)) { if (http_test_existance('http://s3db.org/ms.txt')) { $handle = fopen('http://s3db.org/ms.txt', 'rb'); $real_ms = stream_get_contents($handle); fclose($handle); } else { $real_ms = 'http://s3db.virtual.vps-host.net/central/'; } if (ereg('frameset', $real_ms)) { ereg('src="(http.*" )', $real_ms, $out); if (http_test_existance(trim($out[1], "\" "))) { $mothership = fread(fopen(trim($out[1], "\" "), 'r'), '100'); } } } if (http_test_existance($mothership)) { #call mothership, find true url $true_url = fread(fopen($mothership . '/s3rl.php?Did=' . $Did, 'r'), '100000'); #echo '<pre>';print_r($true_url);exit; if (!empty($true_url)) { $data = html2cell($true_url); } #echo '<pre>data';print_r($data);exit; $data[2]['deployment_id'] = substr($Did, 1, strlen($Did)); if (http_test_existance(trim($data[2]['url']))) { $data[2]['checked_valid'] = date('Y-m-d H:i:s'); } else { $data[2]['checked_valid'] = ''; } #now update true url in local if (empty($did_url)) { insertDidUrl($data[2], $db); } else { updateDidUrl($data[2], $db); } #and define the variable $url = trim($data[2]['url']); } else { #motherhsips seems to be down... try asking the url that gave the this uid for a URL. #need the url from the deployment where this ID is being shared from. } } else { $url = trim($did_url['url']); } #echo '<pre>';print_r($did_url);exit; } else { $url = $Did; } #secho $url; #build the call url $url = substr($url, -1) == '/' ? $url : $url . '/'; $key = $key != '' ? $key : get_user_key($user_id, $db); $url2call = $url . 'URI.php?uid=' . $remoteId . '&key=' . $key . '&user_id=' . $local_user; #echo $url2call;exit; if (!http_test_existance($url2call)) { return $GLOBALS['messages']['something_does_not_exist'] . '<message>' . $remoteId . ' does not appear to be a valid remote resource</message>'; } $data = array('uid' => $remoteId, 'key' => $key, 'user_id' => $local_user); #now try to access it. I am assuming user already has access in the remote resource $h = fopen($url2call, 'r'); $urldata = fread($h, '10000'); if ($urldata == '') { return "could not find user on the url provided"; } else { #now, which part of the data am I waiting? what element is this? #$relevant_fields = $GLOBALS['dbstruct'][$GLOBALS['s3codes'][substr($remoteId, 0,1)]]; $element = $GLOBALS['s3codes'][substr($remoteId, 0, 1)]; $id_name = $GLOBALS['s3ids'][$element]; #some remote header require translation $remote_resource_names = array('created_by' => 'user_id', 'project_owner' => 'user_id', 'resource_id' => ereg('I|S', substr($remoteId, 0, 1)) ? 'instance_id' : 'class_id', 'subject_id' => 'class_id', 'object_id' => 'class_id', 'verb_id' => 'instance_id'); $data = html2cell($urldata); #echo 'before or after?<pre>';print_r($data); if (is_array($data)) { $relevant_fields = $data[1]; $data = $data[2]; $relevant_data = array_intersect_key($data, array_flip($relevant_fields)); #whatever points to resources must come with the remote ID foreach ($relevant_data as $fieldName => $fieldData) { if (in_array($fieldName, array_keys($remote_resource_names)) || ereg('_id$', $fieldName) && !ereg('http://|https://|_', $fieldData)) { $uidLetter = $remote_resource_names[$fieldName] != '' ? strtoupper(substr($remote_resource_names[$fieldName], 0, 1)) : strtoupper(substr($fieldName, 0, 1)); #echo $fieldName; if ($fieldData != '') { $DidData[$fieldName] = $Did . '/' . $uidLetter . $fieldData; } } else { $DidData[$fieldName] = $fieldData; } } #translate old acl into new permission_levels if ($DidData['acl'] != '' && strlen($DidData['acl']) == '1') { $DidData['acl'] = $DidData['acl'] == '3' ? '222' : ($DidData['acl'] == '2' && ereg('I|S', $letter) ? '222' : ($DidData['acl'] == '2' && ereg('P|C|R', $letter) ? '202' : ($DidData['acl'] == '1' && ereg('P|C|R', $letter) ? '201' : ($DidData['acl'] == '1' && ereg('I|S', $letter) ? '211' : ($DidData['acl'] == '0' ? '000' : '000'))))); } #return the original uid to the apporpriate id_name $DidData[$id_name] = $uid; #figure out if user also has local permission on this resource $info = $DidData; $id = $letter . $uid; $P = permissionOnResource(compact('info', 'key', 'user_id', 'db', 'id')); #given permission on 2 deploykents, (local+rmote), find which one user has the most permission if ($P != '' && $DidData['acl'] != '') { $view = max(array(substr($DidData['acl'], 0, 1), substr($P, 0, 1))); $change = max(array(substr($DidData['acl'], 1, 1), substr($P, 1, 1))); $add_data = max(array(substr($DidData['acl'], 2, 1), substr($P, 2, 1))); $DidData['acl'] = $view . $change . $add_data; } else { $DidData['acl'] = $P != '' ? $P : $DidData['acl']; } $element_info = $DidData; #echo '<pre>';print_r($element_info); #Define if ser can view or not view data. View is the first number in the 3 d code. It ranges from 0 to 2 if (ereg('^2', $element_info['acl']) || ereg('^1', $element_info['acl']) && $element_info['created_by'] == $user_id) { #2 means user can view anything associated with this resource (downstream). 1 means he can see, as long as resource was created by himself $element_info['view'] = '1'; #yes, access is granted. } else { $element_info['view'] = '0'; #no, sorry :-( } #Decide if user can change (update) or not change data on resource $change_digit = substr($element_info['acl'], 1, strlen($element_info['acl'])); #it is the second digit who specifies this if (ereg('^2', $change_digit) || ereg('^1', $change_digit) && $element_info['created_by'] == $user_id) { $element_info['change'] = '1'; } else { $element_info['change'] = '0'; #nope. } #can user insert data in this resource? Information is in the very last digit. In case it only has 2 digits, reading th last digit will work too because it propagates if (ereg('2$', $element_info['acl']) || ereg('1$', $element_info['acl']) && $element_info['created_by'] == $user_id) { $element_info['add_data'] = '1'; } else { $element_info['add_data'] = '0'; } #create the element "delete", in case it is eventually created...For now it is the same as change $element_info['delete'] = $element_info['change']; $element_info['delete_data'] = $element_info['add_data']; return $element_info; } else { #return ($GLOBALS['messages']['something_went_wrong'].'<message> Deployment '.$Did.' responded: '.$urldata.'</message>'); return formatReturn($GLOBALS['error_codes']['no_results'], 'Deployment ' . $Did . ' responded: ' . $urldata, $format, ''); } } #echo $resp; }
function filterDataForQuery($pack) { extract($pack); $letter = letter($uid); $info_ID = $GLOBALS['COREletterInv'][$letter]; $uid_info = uid($uid); $uid_info['uid'] = $info['uid'] != '' ? $info['uid'] : $uid_info['uid']; $info['uid'] = ereg_replace('^D', 'D|', $uid_info['Did']) . ($letter != 'U' ? '|U|' . $user_id : '') . '|' . $letter . '|' . $info[$info_ID] . '|'; if (substr($info['acl'], 0, 1) == '0' || substr($info[$acl], 0, 1) == '1' && createdBy($uid, $db) != $user_id) { $info = array(); } if ($s3ql['where'] != '') { foreach ($s3ql['where'] as $query_field => $query_value) { #map the query_field first. because s3ql was transformed. To avoid being deleted if (in_array($query_field, $GLOBALS['s3map'][$GLOBALS['s3codes'][$letter] . 's']) && $info[$query_field] != $query_value) { $query_field = @array_search($query_field, $GLOBALS['s3map'][$elements]); } $whereLetter = letter($query_field); if (in_array($query_field, $GLOBALS['COREids']) && ereg('^(U|G)$', $letter) && $letter . $query_value != $whereLetter . $query_value) { $D = array('shared_with' => $uid, 'uid' => $whereLetter . $query_value, 'strictsharedwith' => 1, 'stricuid' => 1, 'db' => $db, 'user_id' => $user_id, 'stream' => 'upstream'); ##Look for shared_with in uid instead of uid in shared_with $info['permissionOnResource'] = permissionOnResource($D); #echo '<pre>';print_r($info);exit; } #echo '<pre>';print_r($info);exit; $tmp = $GLOBALS['s3codes'][$letter]; if ($info[$query_field] != $query_value && in_array($query_field, $GLOBALS['queriable'][$tmp])) { if (!in_array($query_field, $cols) && !in_array($query_field, $GLOBALS['COREids'])) { #is there regular expresion in the query? if (ereg("!=\\'(.*)\\'", stripslashes($query_value), $regout)) { if ($info[$query_field] == $regout[1]) { $info = array(); } } else { $info = array(); } } } } } return $info; }