/**
  * 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);
     }
 }