+class RemotesubscribeAction extends Action
+{
+ var $nickname;
+ var $profile_url;
+ var $err;
+
+ function prepare($args)
+ {
+ parent::prepare($args);
+
+ if (common_logged_in()) {
+ $this->clientError(_('You can use the local subscription!'));
+ return false;
+ }
+
+ $this->nickname = $this->trimmed('nickname');
+ $this->profile_url = $this->trimmed('profile_url');
+
+ return true;
+ }
+
+ function handle($args)
+ {
+ parent::handle($args);
+
+ if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ # CSRF protection
+ $token = $this->trimmed('token');
+ if (!$token || $token != common_session_token()) {
+ $this->showForm(_('There was a problem with your session token. '.
+ 'Try again, please.'));
+ return;
+ }
+ $this->remoteSubscription();
+ } else {
+ $this->showForm();
+ }
+ }
+
+ function showForm($err=null)
+ {
+ $this->err = $err;
+ $this->showPage();
+ }
+
+ function showPageNotice()
+ {
+ if ($this->err) {
+ $this->element('div', 'error', $this->err);
+ } else {
+ $inst = sprintf(_('To subscribe, you can [login](%%%%action.%s%%%%),' .
+ ' or [register](%%%%action.%s%%%%) a new ' .
+ ' account. If you already have an account ' .
+ ' on a [compatible microblogging site](%%doc.openmublog%%), ' .
+ ' enter your profile URL below.'),
+ (!common_config('site','openidonly')) ? 'login' : 'openidlogin',
+ (!common_config('site','openidonly')) ? 'register' : 'openidlogin');
+ $output = common_markup_to_html($inst);
+ $this->elementStart('div', 'instructions');
+ $this->raw($output);
+ $this->elementEnd('div');
+ }
+ }
+
+ function title()
+ {
+ return _('Remote subscribe');
+ }
+
+ function showContent()
+ {
+ # id = remotesubscribe conflicts with the
+ # button on profile page
+ $this->elementStart('form', array('id' => 'form_remote_subscribe',
+ 'method' => 'post',
+ 'class' => 'form_settings',
+ 'action' => common_local_url('remotesubscribe')));
+ $this->elementStart('fieldset');
+ $this->element('legend', _('Subscribe to a remote user'));
+ $this->hidden('token', common_session_token());
+
+ $this->elementStart('ul', 'form_data');
+ $this->elementStart('li');
+ $this->input('nickname', _('User nickname'), $this->nickname,
+ _('Nickname of the user you want to follow'));
+ $this->elementEnd('li');
+ $this->elementStart('li');
+ $this->input('profile_url', _('Profile URL'), $this->profile_url,
+ _('URL of your profile on another compatible microblogging service'));
+ $this->elementEnd('li');
+ $this->elementEnd('ul');
+ $this->submit('submit', _('Subscribe'));
+ $this->elementEnd('fieldset');
+ $this->elementEnd('form');
+ }
+
+ function remoteSubscription()
+ {
+ $user = $this->getUser();
+
+ if (!$user) {
+ $this->showForm(_('No such user.'));
+ return;
+ }
+
+ $this->profile_url = $this->trimmed('profile_url');
+
+ if (!$this->profile_url) {
+ $this->showForm(_('No such user.'));
+ return;
+ }
+
+ if (!Validate::uri($this->profile_url, array('allowed_schemes' => array('http', 'https')))) {
+ $this->showForm(_('Invalid profile URL (bad format)'));
+ return;
+ }
+
+ $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
+ $yadis = Auth_Yadis_Yadis::discover($this->profile_url, $fetcher);
+
+ if (!$yadis || $yadis->failed) {
+ $this->showForm(_('Not a valid profile URL (no YADIS document).'));
+ return;
+ }
+
+ # XXX: a little liberal for sites that accidentally put whitespace before the xml declaration
+
+ $xrds =& Auth_Yadis_XRDS::parseXRDS(trim($yadis->response_text));
+
+ if (!$xrds) {
+ $this->showForm(_('Not a valid profile URL (no XRDS defined).'));
+ return;
+ }
+
+ $omb = $this->getOmb($xrds);
+
+ if (!$omb) {
+ $this->showForm(_('Not a valid profile URL (incorrect services).'));
+ return;
+ }
+
+ if (omb_service_uri($omb[OAUTH_ENDPOINT_REQUEST]) ==
+ common_local_url('requesttoken'))
+ {
+ $this->showForm(_('That\'s a local profile! Login to subscribe.'));
+ return;
+ }
+
+ if (User::staticGet('uri', omb_local_id($omb[OAUTH_ENDPOINT_REQUEST]))) {
+ $this->showForm(_('That\'s a local profile! Login to subscribe.'));
+ return;
+ }
+
+ list($token, $secret) = $this->requestToken($omb);
+
+ if (!$token || !$secret) {
+ $this->showForm(_('Couldn\'t get a request token.'));
+ return;
+ }
+
+ $this->requestAuthorization($user, $omb, $token, $secret);
+ }
+
+ function getUser()
+ {
+ $user = null;
+ if ($this->nickname) {
+ $user = User::staticGet('nickname', $this->nickname);
+ }
+ return $user;
+ }
+
+ function getOmb($xrds)
+ {
+ static $omb_endpoints = array(OMB_ENDPOINT_UPDATEPROFILE, OMB_ENDPOINT_POSTNOTICE);
+ static $oauth_endpoints = array(OAUTH_ENDPOINT_REQUEST, OAUTH_ENDPOINT_AUTHORIZE,
+ OAUTH_ENDPOINT_ACCESS);
+ $omb = array();
+
+ # XXX: the following code could probably be refactored to eliminate dupes
+
+ $oauth_services = omb_get_services($xrds, OAUTH_DISCOVERY);
+
+ if (!$oauth_services) {
+ return null;
+ }
+
+ $oauth_service = $oauth_services[0];
+
+ $oauth_xrd = $this->getXRD($oauth_service, $xrds);
+
+ if (!$oauth_xrd) {
+ return null;
+ }
+
+ if (!$this->addServices($oauth_xrd, $oauth_endpoints, $omb)) {
+ return null;
+ }
+
+ $omb_services = omb_get_services($xrds, OMB_NAMESPACE);
+
+ if (!$omb_services) {
+ return null;
+ }
+
+ $omb_service = $omb_services[0];
+
+ $omb_xrd = $this->getXRD($omb_service, $xrds);
+
+ if (!$omb_xrd) {
+ return null;
+ }
+
+ if (!$this->addServices($omb_xrd, $omb_endpoints, $omb)) {
+ return null;
+ }