function authenticate_remote_user($key, $url) { #URL contains info on user in the last part of the path. (for example: URL=https://ibl.mdanderson.org/s3db/U4) #$user_id_info = uid($url); $user_id_info = uid_resolve($url); if (ereg_replace('^D', '', $user_id_info['Did']) == ereg_replace('^D', '', $GLOBALS['s3db_info']['deployment']['Did'])) { #same uri as local, authentication failed return 1; exit; } $db = CreateObject('s3dbapi.db'); $db->Halt_On_Error = 'no'; $db->Host = $GLOBALS['s3db_info']['server']['db']['db_host']; $db->Type = $GLOBALS['s3db_info']['server']['db']['db_type']; $db->Database = $GLOBALS['s3db_info']['server']['db']['db_name']; $db->User = $GLOBALS['s3db_info']['server']['db']['db_user']; $db->Password = $GLOBALS['s3db_info']['server']['db']['db_pass']; $db->connect(); #Find URL list($did_url) = DidURL($user_id_info, $db); if (!$did_url) { return 4; exit; } #Validate User in remote; ##This is done by calling the apifunction keyCheck, which requires a key and a user_id; $call1 = $did_url . 'keyCheck.php?key=' . $key . '&user_id=' . $user_id_info['uid'] . '&format=php'; $tmpKC = @fopen($call1, 'r'); if (!$tmpKC) { return 4; exit; } $keyValidated = stream_get_contents($tmpKC); $keyValidated = unserialize($keyValidated); $keyValidated = $keyValidated[0]; if ($keyValidated['error_code'] == 0) { #User was validated with uid associated with remote deployment; These users cannot write anything is this deployment and their permissions are limited to the resources they were granted permission on. A filter is implemented that can be changed by the creator (Remote) insert_access_log(array('user_id' => $user_id_info['condensed'], 'db' => $db)); ##Temporarily copy the key for this user $I = array('key_id' => $key, 'account_id' => $user_id_info['condensed'], 'expires' => date('Y-m-d H:i:s', time() + 1 * 60 * 60), 'notes' => 'Key for remote user created automatically by the API. Expires in 1 hour.'); add_entry('access_keys', $I, $db); delete_expired_keys($date, $db); return 0; exit; } else { return 1; exit; } }
function remoteURI($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) if (is_array($uid)) { $uid_info = $uid; } else { $uid_info = uid_resolve($uid); } $local_user = S3DB_URI_BASE . '/' . 'U' . $user_id; $letter = letter($uid_info['uid']); $uid = $uid_info['uid']; if (ereg('^[UGPCRIS]', $letter)) { $numeric_id = substr($uid, 1, strlen($uid)); #if uid brings a letter, leave just a the id $numeric_did = substr($uid_info['did'], 1, strlen($uid_info['did'])); } ##If Did is not a url, it must be found first $a = @fopen($numeric_did, 'r'); if (!$a) { list($did_url) = DidURL($uid_info, $db); } else { $did_url = $numeric_did; fclose($a); } #First let's try calling the remote resource without authentication; it might be a public resource $did_query = trim($did_url) . 'URI.php?uid=' . $uid . '&format=php'; $tmpH = @fopen($did_query, 'r'); if (!$tmpH) { #could not read or is not an S3DB deployment $return = "Deployment " . $did_url . " does not appear to be a valid url"; } else { $tmpData = stream_get_contents($tmpH); $uid_info = unserialize($tmpData); $uid_info = $uid_info[0]; ##when is a "no permission" error code, tyr again with the key; all others, exit if ($uid_info['error_code'] != '' && $uid_info['error_code'] != '5') { return $uid_info[0]['message']; } elseif ($uid_info['error_code'] == '5') { $did_query .= '?key=' . $key . '&user_id=' . $local_user; $tmpH = @fopen($did_query, 'r'); $tmpData = stream_get_contents($tmpH); $uid_info = unserialize($tmpData); $uid_info = $uid_info[0]; } $return = $uid_info; } #now update true url in local if (!$did_is_local) { insertDidUrl($did_info, $db); } else { if (!$did_is_recent) { #if check was not valid, do not update that field if ($tmpH) { $did_info['checked_valid'] = date('Y-m-d G:i:s'); } updateDidUrl($did_info, $db); } } return $return; }
function retrieveUIDInfo($Z) { extract($Z); if ($s3ql['where'][$id] != '') { $element_name = $s3element; $id_name = $id; $letterSub = letter($id_name); $core = $GLOBALS['s3codes'][$letterSub]; #is this remote? uid_resolve will return that information #$uid_info = uid($letterSub.$s3ql['where'][$id_name]); $uid_info = uid_resolve($s3ql['where'][$id_name]); //if uid_info does not contain a uid, attempt to build a simpe uid appending the letter to the beginning of the string if (!$uid_info['uid']) { $uid_info = uid_resolve($letterSub . $s3ql['where'][$id_name]); } if (!$uid_info['uid']) { $uid = $letterSub . $s3ql['where'][$id_name]; } else { $uid = $uid_info['uid']; } //check first if uid is local; even when Did is different, it may have been created locally //This will happen in the majority of cases $islocal = isLocal($uid, $db); if ($islocal) { $id = strtoupper(substr($element_name, 0, 1)) . $s3ql['where'][$id_name]; $localuid = $letterSub . $s3ql['where'][$id_name]; $element_info = URI($localuid, $user_id, $db); if ($element_info['acl'] == '') { $element_info['acl'] = permission4Resource(array('shared_with' => 'U' . $user_id, 'uid' => $id, 'db' => $db, 'user_id' => $user_id, 'strictuid' => 1, 'strictsharedwith' => 1)); } if ($id_name == $element . "_id") { if (!is_array($element_info)) { if ($uid_info['uid'] != '') { $forbidden = array('#', ':', '/'); $test_str = str_split($uid_info['uid']); foreach ($forbidden as $f) { if (array_search($f, $test_str)) { return formatReturn($GLOBALS['error_codes']['wrong_inputs'], 'Please do not use any of the following character when specifying IDs: ' . array_reduce($forbidden, "comma_split"), $s3ql['format'], ''); } } } $element_info = array('to_create' => '1'); } else { #echo '<pre>';print_r($element_info); $element_info['to_create'] = '0'; #only valid when resource being inserted in another resource. } } } else { #try external URI (external) but only for uid that are not being inserted and there is not indication of literal data #This UID can only be remote if it has a Did or URL attached. Does it? #Furthermomre, if Did is the same as local, it was eliminated by is_local query //ereg('^(D)|http|(s3db:|ldap:|ftp:|smtp:){0,1}(.*):(.*)',$uid_info['uid'],$try); $local_did = substr($GLOBALS['Did'], 0, 1) == 'D' ? $GLOBALS['Did'] : "D" . $GLOBALS['Did']; if ($uid_info['did'] == '' || $uid_info['did'] == $local_did) { #uh ho, it's not local nor remote, this might be a uid that someone is trying to create; #So let's check whether there is data to create it. Diff must be empty because it's the result of the difference between what is needed and what is provided. if (empty($diff) && $id_name == $GLOBALS['COREids'][$s3ql['insert']]) { $element_info = array('to_create' => 1); return $element_info; } else { #Problem - id cannot be found and cannot be created :-( $element_info = array(); return $element_info; } } else { #what is the actual did of the element? $uid_did = $uid_info['did']; if ($id_name == $GLOBALS['COREids'][$s3ql['insert']] && !empty($diff)) { $element_info['to_create'] = '1'; } else { #all this checks because remoteURI is a query that may take some time or fail if remote did not responding $msg = remoteURI($uid_info, $key, $user_id, $db); if (!is_array($msg)) { return $msg; } else { $element_info = $msg; $element_info['is_remote'] = '1'; if ($uid_info['letter'] == 'U' && count($input_ids) == 2) { ##For consistency purposes, an account fo this remote user will be created at this point with current user as parent. User is created with a filter by default that prevents him from adding to this deployment. Parent user (or its ancestrors can then change this default filter to grant more permission to the remote user); $user_email = $user_info['account_email']; $remote_user_info = $element_info; $remote_user_id = $uid_info['condensed']; bindRemoteUser(compact('remote_user_id', 'user_id', 'db', 'remote_user_info', 'user_email')); } } } } } } return $element_info; }