function omb_oauth_server() { static $server = null; if (is_null($server)) { $server = new OAuthServer(omb_oauth_datastore()); $server->add_signature_method(omb_hmac_sha1()); } return $server; }
function requestAuthorization($user, $omb, $token, $secret) { $con = omb_oauth_consumer(); $tok = new OAuthToken($token, $secret); $url = omb_service_uri($omb[OAUTH_ENDPOINT_AUTHORIZE]); # XXX: Is this the right thing to do? Strip off GET params and make them # POST params? Seems wrong to me. $parsed = parse_url($url); $params = array(); parse_str($parsed['query'], $params); $req = OAuthRequest::from_consumer_and_token($con, $tok, 'GET', $url, $params); # We send over a ton of information. This lets the other # server store info about our user, and it lets the current # user decide if they really want to authorize the subscription. $req->set_parameter('omb_version', OMB_VERSION_01); $req->set_parameter('omb_listener', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST])); $req->set_parameter('omb_listenee', $user->uri); $req->set_parameter('omb_listenee_profile', common_profile_url($user->nickname)); $req->set_parameter('omb_listenee_nickname', $user->nickname); $req->set_parameter('omb_listenee_license', common_config('license', 'url')); $profile = $user->getProfile(); if (!$profile) { common_log_db_error($user, 'SELECT', __FILE__); $this->serverError(_('User without matching profile')); return; } if (!is_null($profile->fullname)) { $req->set_parameter('omb_listenee_fullname', $profile->fullname); } if (!is_null($profile->homepage)) { $req->set_parameter('omb_listenee_homepage', $profile->homepage); } if (!is_null($profile->bio)) { $req->set_parameter('omb_listenee_bio', $profile->bio); } if (!is_null($profile->location)) { $req->set_parameter('omb_listenee_location', $profile->location); } $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); if ($avatar) { $req->set_parameter('omb_listenee_avatar', $avatar->url); } # XXX: add a nonce to prevent replay attacks $req->set_parameter('oauth_callback', common_local_url('finishremotesubscribe')); # XXX: test to see if endpoint accepts this signature method $req->sign_request(omb_hmac_sha1(), $con, $tok); # store all our info here $omb['listenee'] = $user->nickname; $omb['listener'] = omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]); $omb['token'] = $token; $omb['secret'] = $secret; # call doesn't work after bounce back so we cache; maybe serialization issue...? $omb['access_token_url'] = omb_service_uri($omb[OAUTH_ENDPOINT_ACCESS]); $omb['post_notice_url'] = omb_service_uri($omb[OMB_ENDPOINT_POSTNOTICE]); $omb['update_profile_url'] = omb_service_uri($omb[OMB_ENDPOINT_UPDATEPROFILE]); common_ensure_session(); $_SESSION['oauth_authorization_request'] = $omb; # Redirect to authorization service common_redirect($req->to_url()); return; }
function access_token($omb) { common_debug('starting request for access token', __FILE__); $con = omb_oauth_consumer(); $tok = new OAuthToken($omb['token'], $omb['secret']); common_debug('using request token "' . $tok . '"', __FILE__); $url = $omb['access_token_url']; common_debug('using access token url "' . $url . '"', __FILE__); # XXX: Is this the right thing to do? Strip off GET params and make them # POST params? Seems wrong to me. $parsed = parse_url($url); $params = array(); parse_str($parsed['query'], $params); $req = OAuthRequest::from_consumer_and_token($con, $tok, "POST", $url, $params); $req->set_parameter('omb_version', OMB_VERSION_01); # XXX: test to see if endpoint accepts this signature method $req->sign_request(omb_hmac_sha1(), $con, $tok); # We re-use this tool's fetcher, since it's pretty good common_debug('posting to access token url "' . $req->get_normalized_http_url() . '"', __FILE__); common_debug('posting request data "' . $req->to_postdata() . '"', __FILE__); $fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); $result = $fetcher->post($req->get_normalized_http_url(), $req->to_postdata(), array('User-Agent: Laconica/' . LACONICA_VERSION)); common_debug('got result: "' . print_r($result, true) . '"', __FILE__); if ($result->status != 200) { return null; } parse_str($result->body, $return); return array($return['oauth_token'], $return['oauth_token_secret']); }
function omb_update_profile($profile, $remote_profile, $subscription) { $user = User::staticGet($profile->id); $con = omb_oauth_consumer(); $token = new OAuthToken($subscription->token, $subscription->secret); $url = $remote_profile->updateprofileurl; $parsed = parse_url($url); $params = array(); parse_str($parsed['query'], $params); $req = OAuthRequest::from_consumer_and_token($con, $token, "POST", $url, $params); $req->set_parameter('omb_version', OMB_VERSION_01); $req->set_parameter('omb_listenee', $user->uri); $req->set_parameter('omb_listenee_profile', common_profile_url($profile->nickname)); $req->set_parameter('omb_listenee_nickname', $profile->nickname); # We use blanks to force emptying any existing values in these optional fields $req->set_parameter('omb_listenee_fullname', $profile->fullname ? $profile->fullname : ''); $req->set_parameter('omb_listenee_homepage', $profile->homepage ? $profile->homepage : ''); $req->set_parameter('omb_listenee_bio', $profile->bio ? $profile->bio : ''); $req->set_parameter('omb_listenee_location', $profile->location ? $profile->location : ''); $avatar = $profile->getAvatar(AVATAR_PROFILE_SIZE); $req->set_parameter('omb_listenee_avatar', $avatar ? $avatar->url : ''); $req->sign_request(omb_hmac_sha1(), $con, $token); # We re-use this tool's fetcher, since it's pretty good $fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); common_debug('request URL = ' . $req->get_normalized_http_url(), __FILE__); common_debug('postdata = ' . $req->to_postdata(), __FILE__); $result = $fetcher->post($req->get_normalized_http_url(), $req->to_postdata(), array('User-Agent: Laconica/' . LACONICA_VERSION)); common_debug('Got HTTP result "' . print_r($result, true) . '"', __FILE__); if (empty($result) || !$result) { common_debug("Unable to contact " . $req->get_normalized_http_url()); } else { if ($result->status == 403) { # not authorized, don't send again common_debug('403 result, deleting subscription', __FILE__); $subscription->delete(); return false; } else { if ($result->status != 200) { common_debug('Error status ' . $result->status, __FILE__); return false; } else { # success! parse_str($result->body, $return); if (isset($return['omb_version']) && $return['omb_version'] === OMB_VERSION_01) { return true; } else { return false; } } } } }
function getSignatureMethod(&$req) { $signature_method = @$req->get_parameter("oauth_signature_method"); if (!$signature_method) { $signature_method = "PLAINTEXT"; } if ($signature_method != 'HMAC-SHA1') { throw new OAuthException("Signature method '{$signature_method}' not supported."); } return omb_hmac_sha1(); }