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); }
private static function determineAppCanvasUrl(&$params) { //get the api_key for the app and retrieve the current canvas $admin_rest = RingsideSocialUtils::getAdminClient(); $appKey = isset($_REQUEST['api_key']) ? $_REQUEST['api_key'] : NULL; $props = $admin_rest->admin_getAppProperties("canvas_url", null, NULL, $appKey); if ($props != null) { $params['app'] = $props["canvas_url"]; } else { throw new Exception('unknown application key supplied: ' . $params['appKey']); } }
public function execute() { // TODO: This ONLY will work if API and Social tiers are co-located! $response = array(); // Finish the API session, because we need to start a social session session_regenerate_id(true); $_SESSION = array(); $network_session = new RingsideSocialSession(); $rest = RingsideSocialUtils::getAdminClient(); $session_key = $rest->auth_createAppSession($this->uid, RingsideSocialConfig::$apiKey, false); $network_session->addApiSessionKey(RingsideSocialConfig::$apiKey, $session_key); $network_session->setNetwork($this->user_network_key); //$network_session->addApiSessionKey($apiKey, $session_key); $network_session->setUserId($this->uid); // TODO: Do user identity mapping right now //$network_session->setPrincipalId($pid); //$network_session->setTrust($trust_key); //$network_session->setCallbackUrl($social_callback); $network_session->setLoggedIn(true); $response[self::RESPONSE_SOCIAL_SESSION]['session_id'] = $network_session->getSessionKey(); $response[self::RESPONSE_SOCIAL_SESSION]['initial_expiry'] = $network_session->getExpiry(); session_write_close(); return $response; }
/** * Convenience method which will look up an apps secret given that its api_key was provided * when the token was constructed. * * @return unknown api_secret */ public function getAppSecret() { $adminClient = RingsideSocialUtils::getAdminClient(); $api_key = $this->getAppId(); $app_properties = $adminClient->admin_getAppProperties(array('api_key', 'secret_key', 'canvas_url'), null, null, $api_key); $secretKey = $app_properties['secret_key']; return $secretKey; }
public function execute(RingsideSocialClientInterface $socialClient) { $coreApp = $this->canvasUrl != null ? $this->plugin($this->canvasUrl) : false; $text = 'empty'; $status = 200; $callback = ''; // if this is not a core (aka system) app, then make a remote call to the remote app // otherwise, render the results of the system app via a local call if ($coreApp === false) { $text = null; try { $adminClient = RingsideSocialUtils::getAdminClient(); $result = $adminClient->admin_getAppProperties("application_name,use_iframe,api_key,secret_key,callback_url,application_id", $this->appId, $this->canvasUrl, null, $socialClient->getCurrentNetwork()); $callback = isset($result['callback_url']) ? $result['callback_url'] : ''; $apiKey = isset($result['api_key']) ? $result['api_key'] : ''; $apiSecret = isset($result['secret_key']) ? $result['secret_key'] : ''; $canvasType = isset($result['use_iframe']) ? $result['use_iframe'] : ''; $applicationid = isset($result['application_id']) ? $result['application_id'] : ''; $networkSession = $socialClient->getNetworkSession(); $principalId = $networkSession->getPrincipalId(); $apiSessionKeyApp = RingsideSocialUtils::getApiSessionKey($apiKey, $apiSecret, $socialClient->getNetworkSession()); $apiClientApplication = new RingsideApiClientsRest($apiKey, $apiSecret, $apiSessionKeyApp, null, $socialClient->getCurrentNetwork()); $isAppAdded = false; if ($socialClient->inSession()) { $isAppAdded = $apiClientApplication->users_isAppAdded(); $idmaps = $apiClientApplication->users_mapToPrincipal(array($socialClient->getCurrentUser())); $nuser = null; if (!empty($idmaps) && null != $socialClient->getCurrentUser()) { foreach ($idmaps as $idmap) { if ($idmap['uid'] == $socialClient->getCurrentUser()) { $nuser = $idmap['pid']; } } } // TODO: Move setting network user in network session into login.php and map.php? $networkSession->setPrincipalId($nuser); } $headers = array(); $fbmlText = $this->renderRemote($callback, $apiKey, $apiSecret, $canvasType, $isAppAdded, $apiSessionKeyApp, $socialClient, $headers, $status); // error_log("Status for $callback is $status"); if ($fbmlText !== null && !empty($fbmlText)) { if (strncmp($headers['content-type'], 'text/html', 9) === 0) { $this->raw = false; $text = $this->renderFbml($fbmlText, $socialClient->getNetworkSession(), $apiClientApplication, $applicationid); // Need $socialUrl if (include 'LocalSettings.php') { $extra_end_scripts = <<<EOF <script type='text/javascript'><!-- if ( typeof Ajax != 'undefined' ) { Ajax.API_KEY='{$apiKey}'; Ajax.RENDER_URL='{$socialUrl}/render.php'; Ajax.PROXY_URL='{$socialUrl}/proxyjs.php'; } //--></script> EOF; // These are ONLY emitted for FBML remote applications to support FBJS! $text .= $extra_end_scripts; } } else { if (strncmp($headers['content-type'], 'text/', 5) === 0) { // Send all other text (text/xml, text/css, etc.) back raw $this->raw = true; $text = $fbmlText; } else { error_log("No way to handle content type " . $headers['content-type']); $this->error = RingsideSocialUtils::SOCIAL_ERROR_RENDER_EXCEPTION; } } } else { if ($status < 200) { $text = "The application did not finish processing prior to the timeout."; } else { if ($status < 300) { $text = "The application returned an HTTP status code of 200 but no content."; } else { if ($status < 400) { $text = "The application returned too many redirects."; } else { if ($status < 500) { $text = "The application is configured to point to an incorrect page."; } else { if ($status < 600) { $text = "The application encountered an error during processing."; } } } } } } } catch (Exception $exception) { error_log("Remote Render Exception : " . $exception->getMessage()); error_log($exception->getTraceAsString()); $this->error = RingsideSocialUtils::SOCIAL_ERROR_NO_SUCH_PAGE; } } else { // making a request to a local system app try { $apiSessionKey = RingsideSocialUtils::getApiSessionKey(RingsideSocialConfig::$apiKey, RingsideSocialConfig::$secretKey, $socialClient->getNetworkSession()); $apiClientSocial = new RingsideApiClientsRest(RingsideSocialConfig::$apiKey, RingsideSocialConfig::$secretKey, $apiSessionKey); $callback = "System Application " . $this->canvasUrl; error_log("Rendering system application {$callback}"); $fbmlText = $this->renderLocal(RingsideSocialConfig::$apiKey, RingsideSocialConfig::$secretKey, $apiSessionKey, $socialClient); if (isset($coreApp->canvas_type) && $coreApp->canvas_type == RingsideAppsCommon::CANVASTYPE_IFRAME) { $text = $fbmlText; } else { if ($socialClient->inSession()) { $apiSessionKey = RingsideSocialUtils::getApiSessionKey(RingsideSocialConfig::$apiKey, RingsideSocialConfig::$secretKey, $socialClient->getNetworkSession()); $apiClientSocial = new RingsideApiClientsRest(RingsideSocialConfig::$apiKey, RingsideSocialConfig::$secretKey, $apiSessionKey); } $text = $this->renderFbml($fbmlText, $socialClient->getNetworkSession(), $apiClientSocial, $socialClient->getCurrentUser()); } } catch (Exception $exception) { error_log("Remote Local Exception : " . $exception->getMessage()); error_log($exception->getTraceAsString()); $this->error = RingsideSocialUtils::SOCIAL_ERROR_NO_SUCH_PAGE; } } $response = array(); if (!empty($text)) { $response['content'] = $text; } if ($this->iframe != null) { $response['iframe'] = $this->iframe; } if ($this->redirect != null) { $response['redirect'] = $this->redirect; } if ($this->error != null) { $response['error'] = $this->error; } $response['status'] = $status; if (empty($response)) { $response['error'] = "The URL {$callback} returned no data"; } $response['raw'] = $this->raw; return $response; }
public function execute($params) { $this->debug('Entering'); $this->debugVar($params); $network_session = null; /* foreach($params as $k => $v) { error_log("RingsideSocialServerRender: $k=$v"); } */ // Recreate Session if we have it error_log("Parameters for widget render are: " . var_export($params, true)); error_log("PHPSESSID=" . (isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : '<empty>')); 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 = $network_session->getUserId(); if (isset($_REQUEST['uid'])) { // TODO: SECURITY: I don't think we should just be able to override the uid. $uid = $_REQUEST['uid']; // TODO: SECURITY: This shouldn't be a valid way to log in. $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']); error_log("PHPSESSID says session is as follows: " . var_export($network_session, true)); $uid = $network_session->getUserId(); if (!isset($uid)) { // The user has a network session but is not logged in // Run as an anonymous user $trust = new RingsideSocialApiTrust($_REQUEST); $network_session = $trust->getAnonymousSession(); } } else { // Not logged in, so login via annonymous user $trust = new RingsideSocialApiTrust($_REQUEST); $network_session = $trust->getAnonymousSession(); } } $api_session_key = $network_session->getApiSessionKey($params['api_key']); if (null == $api_session_key) { $rest = RingsideSocialUtils::getAdminClient(); $app_props = $rest->admin_getAppProperties(array('secret_key'), null, null, $params['api_key'], $network_session->getNetwork()); error_log("Adding API key for " . $params['api_key'] . " to social session for user " . $network_session->getUserID()); RingsideSocialUtils::getApiSessionKey($params['api_key'], $app_props['secret_key'], $network_session); } else { error_log("Using API session key {$api_session_key} for user " . $network_session->getUserID()); } if (array_key_exists('method', $params)) { $method = $params['method']; if (strcasecmp($method, 'fbml') == 0 && array_key_exists('fbml', $params)) { $fbml = $params['fbml']; //error_log("fbml: $fbml"); $render = new RingsideSocialApiRenderFBML($params); $result = $render->render($network_session, $fbml); //error_log("content: ".$result['content']); return isset($result['content']) ? $result['content'] : $result['error']; } else { if (strcasecmp($method, 'app') == 0) { $social = new RingsideSocialClientLocal(RingsideWebConfig::$networkKey, null, $network_session->getSessionKey()); $inSession = $social->inSession(); error_log("User " . ($inSession ? 'is' : 'is not') . " in session"); if ($inSession) { $path = ''; if (array_key_exists('path', $params)) { $path = $params['path']; } $view = 'canvas'; if (array_key_exists('view', $params)) { $view = $params['view']; } //error_log("About to render: ".$params['app']." view: $view, path: $path"); $rest = RingsideSocialUtils::getAdminClient(); $app_props = $rest->admin_getAppProperties(array('application_id', 'canvas_url'), null, null, $params['api_key'], null, $network_session->getNetwork()); $domain_props = $rest->admin_getDomainProperties(array('resize_url'), null, $network_session->getNetwork()); $content = $social->render($view, $app_props['application_id'], $app_props['canvas_url'], $path); // TODO: Is this where error reporting should happen? //error_log("content: $content"); if (isset($domain_props['resize_url'])) { $content = "<html><head><script type=\"text/javascript\">\n function resizeIframe(id) {\n var iframe = document.getElementById( 'xdiframe' );\n var wrapper = document.getElementById( 'wrapper' );\n var height = Math.max( document.body.offsetHeight, document.body.scrollHeight );\n var width = Math.max( document.body.offsetWidth, document.body.scrollWidth );\n iframe.src = '{$domain_props['resize_url']}?height='+height+'&width='+width+'&id='+id;\n }\n</script></head><body onload=\"resizeIframe('if_" . $params['api_key'] . "');\">" . $content . "<iframe id='xdiframe' width='1' height='1' frameborder='0'/></body></html>"; } return $content; } else { echo "<error>User not Logged in!</error>"; } } } } else { error_log("No method specified for render request"); } }
$snid = isset($_REQUEST['snid']) ? $_REQUEST['snid'] : null; $api_key = isset($_REQUEST['api_key']) ? $_REQUEST['api_key'] : null; $canvas = isset($_REQUEST['canvas']) ? true : false; $network = isset($_REQUEST['network']) ? true : false; $social_session_key = isset($_REQUEST['social_session_key']) ? $_REQUEST['social_session_key'] : null; $sig = ''; $network_session = null; $authorities = null; try { // We are expecting a social session key in the request, this can help us understand the current map request // the network it is coming from and more. // In the map process not sure where we need this, but its good to load it here. $network_session = new RingsideSocialSession($social_session_key); // The mapping process is happening relative to some NETWORK, the user might not be logged in to the DEPLOYED NETWORK. // And we should not care. However we have to ask some system questions. $ringside_rest = RingsideSocialUtils::getAdminClient($snid); $authorities = $ringside_rest->admin_getTrustInfo(); } catch (Exception $e) { include "ringside/templates/error.tpl"; return; } $this_authority = null; foreach ($authorities as $authority) { if ($authority['trust_key'] == $snid) { $this_authority = $authority; break; } } $hiddenInputs = <<<heredoc <input type="hidden" name="method" value="bindmap" /> <input type="hidden" name="next" value="{$next}" />
/** * 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>'; }
<?php /** * Document this file. * * @author Jason Kinner <*****@*****.**> */ require_once 'ringside/api/clients/RingsideApiClients.php'; require_once 'ringside/social/RingsideSocialUtils.php'; if (isset($_REQUEST['social_session_key'])) { $client = RingsideSocialUtils::getAdminClient(); $domain_info = $client->admin_getDomainProperties(array('secret_key'), null, $_REQUEST['network_key']); error_log("For network " . $_REQUEST['network_key'] . ", the values are: " . var_export($domain_info, true)); $secret = $domain_info['secret_key']; $params = array('social_session_key' => $_GET['social_session_key'], 'next' => $_GET['next']); error_log("Verifying signature with params: " . var_export($params, true) . " and secret '{$secret}'"); $check_sig = Facebook::generate_sig($params, $secret); if ($check_sig == $_REQUEST['sig']) { $social_session_key = $_GET['social_session_key']; error_log("Site connect signature verified. Setting cookie."); setcookie('PHPSESSID', $social_session_key); $next = $_REQUEST['next']; // TODO: Think about restricting this redirect to the registered site's domain, like app login redirection if (strpos($next, '?') !== false) { $next .= "&"; } else { $next .= "?"; } $params = array('sc_social_session_key' => $social_session_key, 'sc_sig' => Facebook::generate_sig(array('social_session_key' => $social_session_key), $domain_info['secret'])); $next .= http_build_query($params); header('Location: ' . $next, null, 302);