/** * For RFC6415 and HTTP URIs, fetch the host-meta file * and look for LRDD templates */ public function discover($uri) { // This is allowed for RFC6415 but not the 'WebFinger' RFC7033. $try_schemes = array('https', 'http'); $scheme = mb_strtolower(parse_url($uri, PHP_URL_SCHEME)); switch ($scheme) { case 'acct': if (!Discovery::isAcct($uri)) { throw new Exception('Bad resource URI: ' . $uri); } // We can't use parse_url data for this, since the 'host' // entry is only set if the scheme has '://' after it. list($user, $domain) = explode('@', parse_url($uri, PHP_URL_PATH)); break; case 'http': case 'https': $domain = mb_strtolower(parse_url($uri, PHP_URL_HOST)); $try_schemes = array($scheme); break; default: throw new Exception('Unable to discover resource descriptor endpoint.'); } foreach ($try_schemes as $scheme) { $url = $scheme . '://' . $domain . '/.well-known/host-meta'; try { $response = self::fetchUrl($url); $this->xrd->loadString($response->getBody()); } catch (Exception $e) { common_debug('LRDD could not load resource descriptor: ' . $url . ' (' . $e->getMessage() . ')'); continue; } return $this->xrd->links; } throw new Exception('Unable to retrieve resource descriptor links.'); }
/** * Class handler. * * @param array $args array of arguments * * @return void */ function handle($args) { parent::handle($args); $datastore = new ApiStatusNetOAuthDataStore(); $server = new OAuthServer($datastore); $hmac_method = new OAuthSignatureMethod_HMAC_SHA1(); $server->add_signature_method($hmac_method); $atok = $app = null; // XXX: Insist that oauth_token and oauth_verifier be populated? // Spec doesn't say they MUST be. try { $req = OAuthRequest::from_request(); $this->reqToken = $req->get_parameter('oauth_token'); $this->verifier = $req->get_parameter('oauth_verifier'); $app = $datastore->getAppByRequestToken($this->reqToken); $atok = $server->fetch_access_token($req); } catch (Exception $e) { common_log(LOG_WARNING, 'API OAuthException - ' . $e->getMessage()); common_debug(var_export($req, true)); $code = $e->getCode(); $this->clientError($e->getMessage(), empty($code) ? 401 : $code, 'text'); return; } if (empty($atok)) { // Token exchange failed -- log it $msg = sprintf('API OAuth - Failure exchanging OAuth request token for access token, ' . 'request token = %s, verifier = %s', $this->reqToken, $this->verifier); common_log(LOG_WARNING, $msg); // TRANS: Client error given from the OAuth API when the request token or verifier is invalid. $this->clientError(_('Invalid request token or verifier.'), 400, 'text'); } else { common_log(LOG_INFO, sprintf("Issued access token '%s' for application %d (%s).", $atok->key, $app->id, $app->name)); $this->showAccessToken($atok); } }
protected function doPost() { try { $request = Subscription_queue::pkeyGet(array('subscriber' => $this->scoped->id, 'subscribed' => $this->target->id)); if ($request instanceof Subscription_queue) { $request->abort(); } } catch (AlreadyFulfilledException $e) { common_debug('Tried to cancel a non-existing pending subscription'); } if (GNUsocial::isAjax()) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); // TRANS: Title after unsubscribing from a group. $this->element('title', null, _m('TITLE', 'Unsubscribed')); $this->elementEnd('head'); $this->elementStart('body'); $subscribe = new SubscribeForm($this, $this->target); $subscribe->show(); $this->elementEnd('body'); $this->endHTML(); exit; } common_redirect(common_local_url('subscriptions', array('nickname' => $this->scoped->getNickname())), 303); }
function handle($args) { parent::handle($args); if (common_is_real_login()) { $this->clientError(_('Already logged in.')); } else { if ($_SERVER['REQUEST_METHOD'] == 'POST') { $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token. Try again, please.')); return; } if ($this->arg('create')) { if (!$this->boolean('license')) { $this->showForm(_('You can\'t register if you don\'t agree to the license.'), $this->trimmed('newname')); return; } $this->createNewUser(); } else { if ($this->arg('connect')) { $this->connectUser(); } else { common_debug(print_r($this->args, true), __FILE__); $this->showForm(_('Something weird happened.'), $this->trimmed('newname')); } } } else { $this->tryLogin(); } } }
function handle($args) { parent::handle($args); $secret = common_config('facebook', 'secret'); $sig = ''; ksort($_POST); foreach ($_POST as $key => $val) { if (substr($key, 0, 7) == 'fb_sig_') { $sig .= substr($key, 7) . '=' . $val; } } $sig .= $secret; $verify = md5($sig); if ($verify == $this->arg('fb_sig')) { $flink = Foreign_link::getByForeignID($this->arg('fb_sig_user'), 2); common_debug("Removing foreign link to Facebook - local user ID: {$flink->user_id}, Facebook ID: {$flink->foreign_id}"); $result = $flink->delete(); if (!$result) { common_log_db_error($flink, 'DELETE', __FILE__); $this->serverError(_('Couldn\'t remove Facebook user.')); return; } } else { # Someone bad tried to remove facebook link? common_log(LOG_ERR, "Someone from {$_SERVER['REMOTE_ADDR']} " . 'unsuccessfully tried to remove a foreign link to Facebook!'); } }
/** * Menu item for personal subscriptions/groups area * * @param Action $action action being executed * * @return boolean hook return */ function onEndAccountSettingsNav($action) { $action_name = $action->trimmed('action'); common_debug("ACTION NAME = " . $action_name); $action->menuItem(common_local_url('mirrorsettings'), _m('MENU', 'Mirroring'), _m('Configure mirroring of posts from other feeds'), $action_name === 'mirrorsettings'); return true; }
function onStartNoticeSave($notice) { $args = $this->testArgs($notice); common_debug("Blogspamnet args = " . print_r($args, TRUE)); $request = xmlrpc_encode_request('testComment', array($args)); $context = stream_context_create(array('http' => array('method' => "POST", 'header' => "Content-Type: text/xml\r\n" . "User-Agent: " . $this->userAgent(), 'content' => $request))); $file = file_get_contents($this->baseUrl, false, $context); $response = xmlrpc_decode($file); if (xmlrpc_is_fault($response)) { throw new ServerException("{$response['faultString']} ({$response['faultCode']})", 500); } else { common_debug("Blogspamnet results = " . $response); if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) { throw new ServerException(sprintf(_("Error from %s: %s"), $this->baseUrl, $match[2]), 500); } else { if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) { throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400); } else { if (preg_match('/^OK$/', $response)) { // don't do anything } else { throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500); } } } } return true; }
function __construct($connection, Profile $owner, Action $out = null) { parent::__construct($out); common_debug("ConnectedAppsList constructor"); $this->connection = $connection; $this->owner = $owner; }
function onStartNoticeSave($notice) { $args = $this->testArgs($notice); common_debug("Blogspamnet args = " . print_r($args, TRUE)); $requestBody = xmlrpc_encode_request('testComment', array($args)); $request = new HTTPClient($this->baseUrl, HTTPClient::METHOD_POST); $request->setHeader('Content-Type', 'text/xml'); $request->setBody($requestBody); $httpResponse = $request->send(); $response = xmlrpc_decode($httpResponse->getBody()); if (xmlrpc_is_fault($response)) { throw new ServerException("{$response['faultString']} ({$response['faultCode']})", 500); } else { common_debug("Blogspamnet results = " . $response); if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) { throw new ServerException(sprintf(_("Error from %s: %s"), $this->baseUrl, $match[2]), 500); } else { if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) { throw new ClientException(sprintf(_("Spam checker results: %s"), $match[2]), 400); } else { if (preg_match('/^OK$/', $response)) { // don't do anything } else { throw new ServerException(sprintf(_("Unexpected response from %s: %s"), $this->baseUrl, $response), 500); } } } } return true; }
function prepare($args) { parent::prepare($args); common_debug('IndexAction -> redirect -> ' . $this->lang); common_redirect(common_get_route('home', array('lang' => $this->lang)), 303); return true; }
/** * Take arguments for running * * @param array $args $_REQUEST args * * @return boolean success flag */ function prepare($args) { parent::prepare($args); common_debug("apitimelinetag prepare()"); $this->tag = $this->arg('tag'); $this->notices = $this->getNotices(); return true; }
/** * Take arguments for running * * @param array $args $_REQUEST args * * @return boolean success flag * */ function prepare($args) { parent::prepare($args); $this->callback = $this->arg('oauth_callback'); if (!empty($this->callback)) { common_debug("callback: {$this->callback}"); } return true; }
/** * Initialization. * * @param array $args Web and URL arguments * * @return boolean false if user doesn't exist */ function prepare($args) { parent::prepare($args); $this->url = $this->arg('url'); $this->challenge = $this->arg('challenge'); common_debug("args = " . var_export($this->args, true)); common_debug('url = ' . $this->url . ' challenge = ' . $this->challenge); return true; }
public static function fromUrl($url, $depth = 0) { common_debug('MentionURL: trying to find a profile for ' . $url); $url = preg_replace('#https?://#', 'https://', $url); try { $profile = Profile::fromUri($url); } catch (UnknownUriException $ex) { } if (!$profile instanceof Profile) { $profile = self::findProfileByProfileURL($url); } $url = str_replace('https://', 'http://', $url); if (!$profile instanceof Profile) { try { $profile = Profile::fromUri($url); } catch (UnknownUriException $ex) { } } if (!$profile instanceof Profile) { $profile = self::findProfileByProfileURL($url); } if (!$profile instanceof Profile) { $hcard = mention_url_representative_hcard($url); if (!$hcard) { return null; } $mention_profile = new Mention_url_profile(); $mention_profile->query('BEGIN'); $profile = new Profile(); $profile->profileurl = $hcard['url'][0]; $profile->fullname = $hcard['name'][0]; preg_match('/\\/([^\\/]+)\\/*$/', $profile->profileurl, $matches); if (!$hcard['nickname']) { $hcard['nickname'] = array($matches[1]); } $profile->nickname = $hcard['nickname'][0]; $profile->created = common_sql_now(); $mention_profile->profile_id = $profile->insert(); if (!$mention_profile->profile_id) { $mention_profile->query('ROLLBACK'); return null; } $mention_profile->profileurl = $profile->profileurl; if (!$mention_profile->insert()) { $mention_profile->query('ROLLBACK'); if ($depth > 0) { return null; } else { return self::fromUrl($url, $depth + 1); } } else { $mention_profile->query('COMMIT'); } } return $profile; }
function getHreflangs() { $hreflangs = array(); $langs = common_config('site', 'langs'); common_debug('Langs:' . print_r($langs, true)); foreach ($langs as $key => $lang) { $hreflangs[] = array('lang' => $key, 'href' => common_get_route('home', array('lang' => $key))); } return $hreflangs; }
/** * For HTTP IDs fetch the URL and look for Link headers. * * @todo fail out of WebFinger URIs faster */ public function discover($uri) { $response = self::fetchUrl($uri, HTTPClient::METHOD_HEAD); $link_header = $response->getHeader('Link'); if (empty($link_header)) { throw new Exception('No Link header found'); } common_debug('LRDD LinkHeader found: ' . var_export($link_header, true)); return self::parseHeader($link_header); }
private static function initDb() { global $config; $database = common_config('db', 'database'); if (empty($database)) { common_debug('No database configured.'); return; } $dbOptions = $config['db']; require_once INSTALLDIR . '/lib/db.php'; }
public function getAliases() { $aliases = array(); try { // Try to create an acct: URI if we're dealing with a profile $aliases[] = $this->reconstructAcct(); } catch (WebFingerReconstructionException $e) { common_debug("WebFinger reconstruction for Profile failed (id={$this->object->id})"); } return array_merge($aliases, parent::getAliases()); }
public function __construct($object_uri, $msg = null) { $this->object_uri = $object_uri; if ($msg === null) { // TRANS: Exception text shown when no object found with certain URI // TRANS: %s is the URI. $msg = sprintf(_('No object found with URI "%s"'), $this->object_uri); common_debug(__CLASS__ . ': ' . $msg); } parent::__construct($msg, 404); }
/** * Complete a pending subscription, as we've got approval of some sort. * * @return Subscription */ public function complete() { $subscriber = Profile::getKV('id', $this->subscriber); $subscribed = Profile::getKV('id', $this->subscribed); try { $sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE); $this->delete(); } catch (AlreadyFulfilledException $e) { common_debug('Tried to start a subscription which already existed.'); } return $sub; }
public function onCreateFileImageThumbnailSource(File $file, &$imgPath, $media = null) { // If we are on a private node, we won't do any remote calls (just as a precaution until // we can configure this from config.php for the private nodes) if (common_config('site', 'private')) { return true; } if ($media !== 'image') { return true; } // If there is a local filename, it is either a local file already or has already been downloaded. if (!empty($file->filename)) { return true; } $this->checkWhitelist($file->getUrl()); // First we download the file to memory and test whether it's actually an image file $imgData = HTTPClient::quickGet($file->getUrl()); common_debug(sprintf('Downloading remote file id==%u with URL: %s', $file->id, $file->getUrl())); $info = @getimagesizefromstring($imgData); if ($info === false) { throw new UnsupportedMediaException(_('Remote file format was not identified as an image.'), $file->getUrl()); } elseif (!$info[0] || !$info[1]) { throw new UnsupportedMediaException(_('Image file had impossible geometry (0 width or height)')); } $filehash = hash(File::FILEHASH_ALG, $imgData); try { // Exception will be thrown before $file is set to anything, so old $file value will be kept $file = File::getByHash($filehash); //FIXME: Add some code so we don't have to store duplicate File rows for same hash files. } catch (NoResultException $e) { $filename = $filehash . '.' . common_supported_mime_to_ext($info['mime']); $fullpath = File::path($filename); // Write the file to disk if it doesn't exist yet. Throw Exception on failure. if (!file_exists($fullpath) && file_put_contents($fullpath, $imgData) === false) { throw new ServerException(_('Could not write downloaded file to disk.')); } // Updated our database for the file record $orig = clone $file; $file->filehash = $filehash; $file->filename = $filename; $file->width = $info[0]; // array indexes documented on php.net: $file->height = $info[1]; // https://php.net/manual/en/function.getimagesize.php // Throws exception on failure. $file->updateWithKeys($orig, 'id'); } // Get rid of the file from memory unset($imgData); $imgPath = $file->getPath(); return false; }
/** * Show the form for ChooseTheme * @return void */ function showContent() { $site_theme = common_config('site', 'theme'); $prefs = $this->scoped->getPref('chosen_theme', 'theme', $site_theme); if ($prefs === null) { common_debug('No chosen theme found in database for user.'); } //Get a list of available themes on instance $available_themes = Theme::listAvailable(); $chosenone = array_search($prefs, $available_themes, true); $form = new ChooseThemeForm($this, $chosenone); $form->show(); }
function prepare($args) { parent::prepare($args); $id = $this->arg('id'); if (!$id) { $this->clientError(_('No ID.')); return false; } common_debug("Got ID {$id}"); $this->group = User_group::staticGet('id', $id); if (!$this->group) { $this->clientError(_('No such group.'), 404); return false; } return true; }
function prepare($args) { parent::prepare($args); $id = $this->arg('id'); if (!$id) { // TRANS: Client error displayed referring to a group's permalink without providing a group ID. $this->clientError(_('No ID.')); } common_debug("Got ID {$id}"); $this->group = User_group::getKV('id', $id); if (!$this->group) { // TRANS: Client error displayed referring to a group's permalink for a non-existing group ID. $this->clientError(_('No such group.'), 404); } return true; }
public function onEndCheckPassword($nickname, $password, $authenticatedUser) { if ($authenticatedUser instanceof User) { // We'll trust this IP for this user and remove failed logins for the database.. $authenticatedUser->delPref(self::FAILED_LOGIN_IP_SECTION, $this->client_ip); return true; } // See if we have an unauthed user from before. If not, it might be because the User did // not exist yet (such as autoregistering with LDAP, OpenID etc.). if ($this->unauthed_user instanceof User) { // And if the login failed, we'll increment the attempt count. common_debug(sprintf('Failed login tests for user %s from IP %s', $this->unauthed_user->getNickname(), $this->client_ip)); $this->unauthed_user->setPref(self::FAILED_LOGIN_IP_SECTION, $this->client_ip, ++$this->failed_attempts); } return true; }
function timeline($args, $apidata) { parent::handle($args); common_debug("in tags api action"); $this->auth_user = $apidata['user']; $tag = $apidata['api_arg']; if (empty($tag)) { $this->clientError('Not Found', 404, $apidata['content-type']); return; } $sitename = common_config('site', 'name'); $title = sprintf(_("Notices tagged with %s"), $tag); $taguribase = common_config('integration', 'taguri'); $id = "tag:{$taguribase}:TagTimeline:" . $tag; $link = common_local_url('tag', array('tag' => $tag)); $subtitle = sprintf(_('Updates tagged with %1$s on %2$s!'), $tag, $sitename); $page = (int) $this->arg('page', 1); $count = (int) $this->arg('count', 20); $max_id = (int) $this->arg('max_id', 0); $since_id = (int) $this->arg('since_id', 0); $since = $this->arg('since'); # XXX: support max_id, since_id, and since arguments $notice = Notice_tag::getStream($tag, ($page - 1) * $count, $count + 1); switch ($apidata['content-type']) { case 'xml': $this->show_xml_timeline($notice); break; case 'rss': $this->show_rss_timeline($notice, $title, $link, $subtitle, $suplink); break; case 'atom': if (isset($apidata['api_arg'])) { $selfuri = common_root_url() . 'api/laconica/tags/timeline/' . $apidata['api_arg'] . '.atom'; } else { $selfuri = common_root_url() . 'api/laconica/tags/timeline.atom'; } $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, $suplink, $selfuri); break; case 'json': $this->show_json_timeline($notice); break; default: $this->clientError(_('API method not found!'), $code = 404); } }
/** * Class handler. * * @param array $args query arguments * * @return boolean false if user doesn't exist */ function handle($args) { parent::handle($args); try { common_debug('getting request from env variables', __FILE__); common_remove_magic_from_request(); $req = OAuthRequest::from_request(); common_debug('getting a server', __FILE__); $server = omb_oauth_server(); common_debug('fetching the access token', __FILE__); $token = $server->fetch_access_token($req); common_debug('got this token: "' . print_r($token, true) . '"', __FILE__); common_debug('printing the access token', __FILE__); print $token; } catch (OAuthException $e) { $this->serverError($e->getMessage()); } }
function timeline($args, $apidata) { parent::handle($args); common_debug("in groups api action"); $this->auth_user = $apidata['user']; $group = $this->get_group($apidata['api_arg'], $apidata); if (empty($group)) { $this->clientError('Not Found', 404, $apidata['content-type']); return; } $sitename = common_config('site', 'name'); $title = sprintf(_("%s timeline"), $group->nickname); $taguribase = common_config('integration', 'taguri'); $id = "tag:{$taguribase}:GroupTimeline:" . $group->id; $link = common_local_url('showgroup', array('nickname' => $group->nickname)); $subtitle = sprintf(_('Updates from %1$s on %2$s!'), $group->nickname, $sitename); $page = (int) $this->arg('page', 1); $count = (int) $this->arg('count', 20); $max_id = (int) $this->arg('max_id', 0); $since_id = (int) $this->arg('since_id', 0); $since = $this->arg('since'); $notice = $group->getNotices(($page - 1) * $count, $count, $since_id, $max_id, $since); switch ($apidata['content-type']) { case 'xml': $this->show_xml_timeline($notice); break; case 'rss': $this->show_rss_timeline($notice, $title, $link, $subtitle, $suplink); break; case 'atom': if (isset($apidata['api_arg'])) { $selfuri = common_root_url() . 'api/laconica/groups/timeline/' . $apidata['api_arg'] . '.atom'; } else { $selfuri = common_root_url() . 'api/laconica/groups/timeline.atom'; } $this->show_atom_timeline($notice, $title, $id, $link, $subtitle, $suplink, $selfuri); break; case 'json': $this->show_json_timeline($notice); break; default: $this->clientError(_('API method not found!'), $code = 404); } }
public function onCreateFileImageThumbnailSource(File $file, &$imgPath, $media = null) { // The calling function might accidentally pass application/ogg videos. // If that's a problem, let's fix it in the calling function. if ($media !== 'video' || empty($file->filename)) { return true; } // Let's save our frame to a temporary file. If we fail, remove it. $imgPath = tempnam(sys_get_temp_dir(), 'socialthumb-'); $result = exec('avconv -i ' . escapeshellarg($file->getPath()) . ' -vcodec mjpeg -vframes 1 -f image2 -an ' . escapeshellarg($imgPath)); if (!getimagesize($imgPath)) { common_debug('exec of "avconv" produced a bad/nonexisting image it seems'); @unlink($imgPath); $imgPath = null; // pretend we didn't touch it return true; } return false; }
function prepare($args) { common_debug("UserrssAction"); parent::prepare($args); $nickname = $this->trimmed('nickname'); $this->user = User::staticGet('nickname', $nickname); $this->tag = $this->trimmed('tag'); if (!$this->user) { $this->clientError(_('No such user.')); return false; } else { if (!empty($this->tag)) { $this->notices = $this->getTaggedNotices(); } else { $this->notices = $this->getNotices(); } return true; } }