示例#1
0
 public function execute($api_key, $callback_url, $params)
 {
     $admin_client = RingsideSocialUtils::getAdminClient();
     // TODO: SECURITY: Possibly security hole. We're signing and giving the signed payload to any URL, just by using the API key, which is public. A 3rd-party could hijack the signed payload and implement an offline brute force attack on the secret key
     $app_props = $admin_client->admin_getAppProperties("application_id,application_name,api_key,secret_key,callback_url", null, null, $api_key);
     // From RingsideSocialServerRender:
     // Recreate Session if we have it
     if (array_key_exists('social_session_key', $params)) {
         $session_key = $params['social_session_key'];
         $network_session = new RingsideSocialSession($session_key);
         $uid = $network_session->getUserId();
         if (null == $uid || strlen($uid) == 0) {
             setcookie('social_session_key', $network_session->getSessionKey());
             $uid = $_REQUEST['uid'];
             $network_session->setUserId($uid);
             $network_session->setLoggedIn(true);
         }
     } else {
         if (isset($_COOKIE['PHPSESSID'])) {
             // Optimization if user is already logged into web front-end
             $network_session = new RingsideSocialSession($_COOKIE['PHPSESSID']);
             $uid = $network_session->getUserId();
         } else {
             // Not logged in, so login via annonymous user
             $trust = new RingsideSocialApiTrust($request);
             $network_session = $trust->getAnonymousSession();
         }
     }
     $ctx = self::buildCallContext($api_key, $network_session);
     $sig_params = $ctx->getParameters($app_props['secret_key']);
     $req_params = array_merge($params, $sig_params);
     //		error_log("Ajax Proxy to $callback_url with params:".var_export($req_params, true));
     $result = RingsideSocialUtils::get_request($callback_url, $req_params, $headers);
     echo str_replace('+', '+', $result);
 }
 public function renderRemote($callbackUrl, $apiKey, $secretKey, $canvasType, $isAppAdded, $sessionKey, RingsideSocialClientInterface $socialClient, &$headers, &$status)
 {
     //      error_log( "renderRemote : enter ($callbackUrl) ($apiKey)  " );
     $response = null;
     if (!empty($this->path)) {
         //         error_log( "renderRemote : path set" );
         $callbackUrl .= $this->path;
     }
     // Create openFB request.
     $ctx = new RingsideSocialAppContext();
     $ctx->setFlavor($this->flavor);
     if ($canvasType == RingsideSocialApiRender::CANVASTYPE_IFRAME || $canvasType == RingsideSocialApiRender::CANVASTYPE_OS) {
         $ctx->setIFrame(1);
     } else {
         $ctx->setIFrame(0);
     }
     $ctx->setInCanvas(1);
     $ctx->setTime(time());
     if ($socialClient->inSession()) {
         // We don't know whether the app is added unless the user is logged in, so don't send that part of the context
         $ctx->setIsAppAdded($isAppAdded);
         $ctx->setUser($socialClient->getCurrentUser());
         $ctx->setSessionKey($sessionKey);
         //      $ctx->setProfileUpdateTime();
         $ctx->setExpires(0);
         if ($socialClient->getNetworkSession()->getPrincipalId()) {
             $ctx->setPrincipalId($socialClient->getNetworkSession()->getPrincipalId());
         }
     }
     $ctx->setApiKey($apiKey);
     $ctx->setRequestMethod($_SERVER['REQUEST_METHOD']);
     $ctx->setNetworkId($socialClient->getCurrentNetwork());
     //      $ctx->setDeployedNetwork( RingsideSocialConfig::$apiKey );
     //      $ctx->setHostNetwork(RingsideSocialConfig::$apiKey);
     $ctx->setSocialSessionKey($socialClient->getNetworkSession()->getSessionKey());
     $deployed_ctx = new RingsideSocialAppContext(array(), RingsideSocialConfig::$apiKey);
     //      $deployed_ctx->setRestUrl(RingsideApiClientsConfig::$serverUrl);
     //      $deployed_ctx->setLoginUrl(RingsideApiClientsConfig::$webUrl.'/login.php');
     //      $deployed_ctx->setCanvasUrl(RingsideApiClientsConfig::$webUrl.'/canvas.php');
     //      $ctx->addNetwork($deployed_ctx);
     $cbReq = $ctx->getParameters($secretKey);
     //      error_log(var_export($cbReq, true));
     /*
      * Special case if we are to return an IFRAME, then the only thing we are returning is the
      * URL to ship out.  It is up to the returning application to place this inside some form of content
      * frame.
      */
     if ($this->flavor == 'canvas' && $canvasType == RingsideSocialApiRender::CANVASTYPE_IFRAME) {
         $callbackQuery = http_build_query(array_merge($cbReq, $this->params));
         // TODO iframe generationg is off should be more expressive and configurable.
         $this->iframe = "{$callbackUrl}?{$callbackQuery}";
         //         error_log( "renderRemote: iframe : " . $this->iframe );
     } else {
         if ($this->flavor == 'canvas' && $canvasType == RingsideSocialApiRender::CANVASTYPE_OS) {
             //Open Social Gadget description is the $callbackUrl
             $callbackQuery = http_build_query(array_merge($cbReq, $this->params));
             // We also need to define fbsig_owner_id if the param id is present
             if (array_key_exists('id', $this->params)) {
                 $callbackQuery . '&fb_sig_owner_id=' . $this->params['id'];
             }
             //TODO These parm options should be configurable
             $callbackQuery = $callbackQuery . '&view=canvas&synd=ringside&nocache=1';
             //If you change this you must change container.js
             $this->iframe = RingsideApiClientsConfig::$socialUrl . "/gadgets/ifr?url=" . urlencode($callbackUrl) . "&{$callbackQuery}";
             if (isset($this->params['forceIFrame']) && $this->params['forceIFrame'] == 'true') {
                 $headers['content-type'] = 'text/html';
                 $response = "<iframe width='100%' frameborder='0' src='" . $this->iframe . "' height='" . $this->params['forceIFrameHeight'] . "'/>";
             }
             //         error_log( "renderRemote: OS iframe : " . $this->iframe );
         } else {
             $response = RingsideSocialUtils::get_request($callbackUrl, array_merge($cbReq, $this->params), $headers, $status);
             if (isset($headers['location'])) {
                 $this->redirect = $headers['location'];
             }
         }
     }
     return $response;
 }
 /**
  * Re-routes an api request to another network. If trust.php is used as a rest server URL
  * and a path info is provided such that the request looks like the one below:
  * 
  *        http://localhost/trust.php/facebook/footprints/restserver.php 
  *            or
  *        http://localhost/trust.php/{network}/{canvas url}/{restserver path}
  *  
  * Attempts to remap and resign the api call using the app's secret on the new network
  * and then to change the uid to the equivelent uid on the forgin network.
  * 
  * The api call is then re-signed and issued and the response is returned.
  * 
  * @param unknown_type $params
  */
 private static function proxy_app_request(&$params)
 {
     $matches = array();
     // All these special cases are to ensure we aren't adding an additional "/" character to the URL.
     preg_match(',^/([^/]*)/([^/]*)(/?.*)$,', $_SERVER['PATH_INFO'], $matches);
     $network_key = $matches[1];
     $canvas_url = $matches[2];
     $rest = $matches[3];
     if ($rest == '') {
         $rest = '/';
     }
     if ($network_key != RingsideSocialConfig::$apiKey) {
         $skey = isset($_REQUEST['fb_sig_session_key']) ? $_REQUEST['fb_sig_session_key'] : '';
         $apiKey = isset($_REQUEST['fb_sig_api_key']) ? $_REQUEST['fb_sig_api_key'] : '';
         $ringside_rest = self::createRestClient($params['fb_sig_session_key']);
         $admin_rest = RingsideSocialUtils::getAdminClient();
         $props = $admin_rest->admin_getAppProperties("application_id,application_name,api_key,secret_key,callback_url", null, $canvas_url, NULL);
         $network_app_props = $admin_rest->admin_getAppKeys(null, null, $props['api_key']);
         $network_api_key = $props['api_key'];
         $network_secret = $props['secret_key'];
         self::getApiKeyAndSecretForNetwork($network_key, $network_app_props, $network_api_key, $network_secret);
         $network_session = new RingsideSocialSession($params['fb_sig_session_key']);
         $idmaps = $ringside_rest->users_mapToPrincipal(array($params['fb_sig_user']), $network_key, $props['application_id']);
         // Create openFB request. These are just overrides for the original request.
         $has_fb_sig = isset($params['fb_sig']);
         $cbReq = array();
         // We can't append fb_sig unless Facebook has already passed fb_sig; this would prevent the app's client from creating a session during login
         if ($has_fb_sig) {
             if (isset($params['fb_sig_nuser'])) {
                 // Since we're proxying a request, do NOT forward the user mapping!
                 unset($params['fb_sig_nuser']);
             }
             $cbReq['fb_sig_flavor'] = 'canvas';
             //				      $cbReq['fb_sig_in_iframe'] = 0;
             $cbReq['fb_sig_nid'] = $network_key;
             // The social session key needs to be for _this_ social session!
             $cbReq['fb_sig_soc_session_key'] = $network_session->getSessionKey();
             if (!empty($idmaps) && isset($idmaps[0]) && $idmaps[0] !== null) {
                 $cbReq['fb_sig_nuser'] = $idmaps[0]['pid'];
             }
         }
         // error_log("cbReq social session key is {$cbReq['fb_sig_soc_session_key']}; params is $fb_sig_soc_session_key");
         // TODO: Set up social session key for trust-based proxy
         // $cbReq['fb_sig_soc_session_key'] = ;
         $req_params = array_merge($params, $cbReq);
         error_log("Invoking {$canvas_url} with params: " . var_export($req_params, true));
         // Now, we need to re-sign the parameters, since we've added the "nid" and "nuser" fb_sig params
         if ($has_fb_sig) {
             unset($req_params['fb_sig']);
             $sig = RingsideSocialUtils::makeSig($req_params, $network_secret, 'fb_sig');
             $req_params['fb_sig'] = $sig;
         }
         //					error_log("Logged in user is principal ".$pids[0]);
         //					error_log("Proxying to app callback URL ".$props['callback_url']);
         $headers = array();
         $callback_url = self::safe_append_url($props['callback_url'], $rest);
         $result = RingsideSocialUtils::get_request($callback_url, $req_params, $headers);
         //					error_log("Result: $result");
         if (isset($headers['location'])) {
             $proxy_redir_url = self::buildProxyUrl($props['callback_url'], $headers['location']);
             error_log("Proxying for redirect to {$proxy_redir_url}");
             // Build the remote network's callback_url
             // We'll redirect _within_ the frame (the commented-out script will redirect the _top_ of the frame
             if (isset($params['fb_sig_in_iframe']) && 0 != $params['fb_sig_in_iframe']) {
                 //							RingsideWebUtils::redirect($headers['location']);
                 $apps_url = RingsideApiClientsConfig::$webUrl . '/canvas.php';
                 if ($nid == 'facebook') {
                     $apps_url = 'http://apps.facebook.com/';
                 }
                 //							$real_location = self::buildProxyUrl($props['callback_url'], $headers['location']);
                 //							echo "<script>top.location.href='".$real_location."';</script>";
                 RingsideWebUtils::redirect($proxy_redir_url);
             } else {
                 //							$real_location = self::buildProxyUrl($props['callback_url'], $headers['location']);
                 if (isset($params['fb_sig_in_canvas']) && 0 != $params['fb_sig_in_canvas']) {
                     echo "<fb:redirect url='{$proxy_redir_url}'/>";
                 } else {
                     RingsideWebUtils::redirect($proxy_redir_url);
                 }
             }
             return;
         }
         echo $result;
         return;
     }
     // Map network user to principal
     // Rewrite fb_sig
     // Proxy to callback_url
     echo '<ERROR>Unknown Callback_Url!</ERROR>';
 }