/** * Just redirect to the search server * * @param array $args */ public function query($args = array()) { $add_live_data = isset($args['lived']) && $args['lived']; unset($args['lived']); $idx = isset($args['i']) ? $args['i'] : 'active-sources'; $opts = array('url' => sprintf("%s/%s/search", AIR2_SEARCH_URI, $idx), 'cookie_name' => AIR2_AUTH_TKT_NAME, 'params' => $args, 'GET' => true); $search_proxy = new Search_Proxy($opts); $rs = $search_proxy->response(); // record zippyness // detect gzip magic bytes since we've already discarded the HTTP headers $zip = false; if (substr($rs['json'], 0, 2) == "‹") { $zip = true; } $rs['gzip'] = $zip; // set a code, based on response $code = AIRAPI::BAD_DATA; $htc = $rs['response']['http_code']; if (isset(self::$STAT_TO_API[$htc])) { $code = self::$STAT_TO_API[$htc]; } // add live data to the search response if ($add_live_data && $code == AIRAPI::OKAY) { $index = isset($args['i']) ? $args['i'] : null; $this->add_live_data($rs['json'], $zip, $index); } /* * Add some extra 'AIRAPI'-ish data to response. Note that this won't make * it to the browser, because search results are handled specially by air2. */ $rs['method'] = 'query'; $rs['success'] = $code == AIRAPI::OKAY; $rs['code'] = $code; $rs['api'] = $this->describe(); return $rs; }
/** * Sends email to user indicated in email POST param. * This method proxies through to the authn/ application for now. */ public function send_password_email() { // validity checks if ($this->method != 'POST') { header('Allow: POST', true, 405); $this->response(array('success' => false), 405); exit; } $email = $this->input->post('email'); if (!$email) { header('X-AIR: "email" required', true, 400); $this->response(array('success' => false), 400); exit; } // fire the remote call $proxy = new Search_Proxy(array('url' => 'https://www.publicinsightnetwork.org/authn/new_account', 'params' => array('email' => $email))); $response = $proxy->response(); if ($response['response']['http_code'] != '200') { header('X-AIR: Send mail failed', false, 401); $this->response(array('success' => false), 401); exit; } $this->response(array('success' => true), 201); }
/** * Does remote HTTP request to PIN SSO service to check $password. * * @param string $username * @param string $password * @return boolean */ private function check_pin_sso($username, $password) { $proxy = new Search_Proxy(array('url' => AIR2_PIN_SSO_AUTH, 'cookie_name' => AIR2_PIN_SSO_TKT, 'params' => array('username' => $username, 'password' => $password))); $response = $proxy->response(); //Carper::carp(var_export($response, true)); if ($response['response']['http_code'] != 200) { return false; } return true; }
/** * Getting the public responses to display * * @return void * @param unknown $inq_uuid (optional) */ public function search($inq_uuid = null) { $query_term = $this->input->get('q'); $resp_format = $this->input->get('t'); $api_key = $this->input->get('a'); if (!$resp_format) { $resp_format = 'JSON'; } // "view" only used for errors // otherwise proxy response sets its own headers // we do not have any HTML view, so if that is detected, // it was the default. override with our local response format detection. if ($this->airoutput->view == 'html') { $this->airoutput->view = strtolower($resp_format); $this->airoutput->format = $this->router->get_content_type_for_view($this->airoutput->view); } elseif (!$this->input->get('t')) { $resp_format = strtoupper($this->airoutput->view); } $api_key_rec = null; if (!strlen($api_key)) { $this->response(array('success' => false, 'error' => 'API Key Required'), 401); return; } else { $api_key_rec = APIKey::find('APIKey', $api_key); if (!$api_key_rec || !$api_key_rec->ak_approved) { $this->response(array('success' => false, 'error' => 'Invalid API Key'), 403); return; } // ok key. log it. $ip_address = $this->input->server('REMOTE_ADDR'); $api_stat = new APIStat(); $api_stat->APIKey = $api_key_rec; $api_stat->as_ip_addr = $ip_address; $api_stat->save(); } // validity checks if ($this->method != 'GET') { header('Allow: GET', true, 405); $this->response(array('success' => false), 405); return; } if (!strlen($query_term)) { $this->response(array('success' => false, 'error' => '"q" param required'), 400); return; } if ($inq_uuid) { $query_term = "(" . $query_term . ") AND inq_uuid={$inq_uuid}"; } $airuser = new AirUser(); $tkt = $airuser->get_tkt($api_key_rec->ak_email, 0); $tktname = null; $tktval = null; foreach ($tkt as $k => $v) { $tktname = $k; $tktval = $v; } $opts = array("url" => AIR2_SEARCH_URI . '/public-responses/search', "cookie_name" => $tktname, "params" => array('t' => $resp_format), "tkt" => $tktval, "query" => $query_term, "GET" => true); $search_proxy = new Search_Proxy($opts); $response = $search_proxy->response(); $body = $response['json']; $this->airoutput->format = $response['response']['content_type']; $this->airoutput->send_headers($response['response']['http_code']); // if JSONP requested, wrap response if ($this->input->get('callback')) { echo $this->input->get('callback') . '(' . $body . ');'; } else { echo $body; } }
/** * Get stats data for an organization * * @param string $org_uuid */ public function get_org_stats($org_uuid) { if ($this->view != 'json') { $this->show_415(); } $org = AIR2_Record::find('Organization', $org_uuid); if (!$org) { show_404(); } // we do our own "view" here since we are just proxying for search server. $search_proxy = new Search_Proxy(array('url' => AIR2_SEARCH_URI . '/report/org', 'cookie_name' => AIR2_AUTH_TKT_NAME, 'params' => array('org_name' => $org->org_name))); $response = $search_proxy->response(); // set headers if ($response['response']['http_code'] != 200) { header('X-AIR2: server error', false, $response['response']['http_code']); } if ($this->input->get_post('gzip')) { header("Content-Encoding: gzip"); } if (preg_match('/application\\/json/', $this->input->server('HTTP_ACCEPT'))) { header("Content-Type: application/json; charset=utf-8"); } else { header("Content-Type: text/javascript; charset=utf-8"); } // respond echo $response['json']; }
/** * Add the results of a search (submissions or source) to a bin * * @param User $u * @param Bin $bin * @param array $params * @param string $notes * @return array $counts */ public static function add_search($u, $bin, $params, $notes = null) { if (!isset($params['i']) || !isset($params['q']) || !isset($params['total'])) { throw new Exception("Invalid search parameters - req'd: i, q, total"); } $i = $params['i']; $q = $params['q']; $M = isset($params['M']) ? $params['M'] : null; $total = $params['total']; // sanity check $valid_indexes = array('sources', 'active-sources', 'primary-sources', 'responses', 'fuzzy-sources', 'fuzzy-active-sources', 'fuzzy-primary-sources', 'fuzzy-responses', 'strict-sources', 'strict-active-sources', 'strict-primary-sources', 'strict-responses'); if (!in_array($i, $valid_indexes)) { throw new Exception("Invalid search type '{$i}'"); } // make sure we have an auth tkt $tkt = isset($_COOKIE[AIR2_AUTH_TKT_NAME]) ? $_COOKIE[AIR2_AUTH_TKT_NAME] : null; if (!$tkt) { $airuser = new AirUser(); $tkt = $airuser->get_tkt($u->user_username, $u->user_id); $tkt = $tkt[AIR2_AUTH_TKT_NAME]; } // call the search server $proxy = new Search_Proxy(array('url' => sprintf("%s/%s/search", AIR2_SEARCH_URI, $i), 'cookie_name' => AIR2_AUTH_TKT_NAME, 'query' => $q, 'params' => array('u' => 1, 'limit' => $total, 'M' => $M), 'tkt' => $tkt, 'GET' => true)); $rsp = $proxy->response(); //error_log(var_export($rsp, 1)); $json = json_decode($rsp['json'], true); if (!$json['success']) { throw new Exception("Search server returned error: " . $json['error']); } // check the total against the expected total if ($json['total'] != $total) { throw new Exception("Search returned unexpected total! Expected " . $json['total'] . ", got {$rsp_total}. Aborting operation!"); } // add sources or responses if ($i == 'responses' || $i == 'fuzzy-responses' || $i == 'strict-responses') { return self::add_submissions($bin, $json['results'], $notes); } else { return self::add_sources($bin, $json['results'], $notes); } }