protected function getProxiedFuture()
 {
     if (!$this->future) {
         $params = $this->params;
         if (!$this->action) {
             throw new Exception(pht('You must %s!', 'setRawGitHubQuery()'));
         }
         if (!$this->accessToken) {
             throw new Exception(pht('You must %s!', 'setAccessToken()'));
         }
         $uri = new PhutilURI('https://api.github.com/');
         $uri->setPath('/' . ltrim($this->action, '/'));
         $future = new HTTPSFuture($uri);
         $future->setData($this->params);
         $future->addHeader('Authorization', 'token ' . $this->accessToken);
         // NOTE: GitHub requires a 'User-Agent' header.
         $future->addHeader('User-Agent', __CLASS__);
         $future->setMethod($this->method);
         foreach ($this->headers as $header) {
             list($key, $value) = $header;
             $future->addHeader($key, $value);
         }
         $this->future = $future;
     }
     return $this->future;
 }
 public static function getServerStatus()
 {
     $uri = PhabricatorEnv::getEnvConfig('notification.server-uri');
     $uri = new PhutilURI($uri);
     $uri->setPath('/status/');
     list($body) = id(new HTTPSFuture($uri))->setTimeout(3)->resolvex();
     $status = json_decode($body, true);
     if (!is_array($status)) {
         throw new Exception(pht('Expected JSON response from notification server, received: %s', $body));
     }
     return $status;
 }
Example #3
0
 protected function run()
 {
     $argv = $this->getArgv();
     if (count($argv) !== 1) {
         throw new Exception(pht('Usage: %s %s', __CLASS__, '<json_config_file>'));
     }
     $json_raw = Filesystem::readFile($argv[0]);
     try {
         $config = phutil_json_decode($json_raw);
     } catch (PhutilJSONParserException $ex) {
         throw new PhutilProxyException(pht("File '%s' is not valid JSON!", $argv[0]), $ex);
     }
     $nick = idx($config, 'nick', 'phabot');
     $handlers = idx($config, 'handlers', array());
     $protocol_adapter_class = idx($config, 'protocol-adapter', 'PhabricatorIRCProtocolAdapter');
     $this->pollFrequency = idx($config, 'poll-frequency', 1);
     $this->config = $config;
     foreach ($handlers as $handler) {
         $obj = newv($handler, array($this));
         $this->handlers[] = $obj;
     }
     $ca_bundle = idx($config, 'https.cabundle');
     if ($ca_bundle) {
         HTTPSFuture::setGlobalCABundleFromPath($ca_bundle);
     }
     $conduit_uri = idx($config, 'conduit.uri');
     if ($conduit_uri) {
         $conduit_token = idx($config, 'conduit.token');
         // Normalize the path component of the URI so users can enter the
         // domain without the "/api/" part.
         $conduit_uri = new PhutilURI($conduit_uri);
         $conduit_host = (string) $conduit_uri->setPath('/');
         $conduit_uri = (string) $conduit_uri->setPath('/api/');
         $conduit = new ConduitClient($conduit_uri);
         if ($conduit_token) {
             $conduit->setConduitToken($conduit_token);
         } else {
             $conduit_user = idx($config, 'conduit.user');
             $conduit_cert = idx($config, 'conduit.cert');
             $response = $conduit->callMethodSynchronous('conduit.connect', array('client' => __CLASS__, 'clientVersion' => '1.0', 'clientDescription' => php_uname('n') . ':' . $nick, 'host' => $conduit_host, 'user' => $conduit_user, 'certificate' => $conduit_cert));
         }
         $this->conduit = $conduit;
     }
     // Instantiate Protocol Adapter, for now follow same technique as
     // handler instantiation
     $this->protocolAdapter = newv($protocol_adapter_class, array());
     $this->protocolAdapter->setConfig($this->config)->connect();
     $this->runLoop();
     $this->protocolAdapter->disconnect();
 }
 public function getRedirectURI()
 {
     if (strlen($this->getAlias())) {
         $path = '/u/' . $this->getAlias();
     } else {
         $path = '/u/' . $this->getID();
     }
     $short_domain = PhabricatorEnv::getEnvConfig('phurl.short-uri');
     if (!$short_domain) {
         return $path;
     }
     $uri = new PhutilURI($short_domain);
     $uri->setPath($path);
     return (string) $uri;
 }
 protected function validateHost($host)
 {
     if (!$host) {
         // If the client doesn't send a host key, don't complain. We should in
         // the future, but this change isn't severe enough to bump the protocol
         // version.
         // TODO: Remove this once the protocol version gets bumped past 2 (i.e.,
         // require the host key be present and valid).
         return;
     }
     $host = new PhutilURI($host);
     $host->setPath('/');
     $host = (string) $host;
     $self = PhabricatorEnv::getProductionURI('/');
     if ($self !== $host) {
         throw new Exception("Your client is connecting to this install as '{$host}', but it is " . "configured as '{$self}'. The client and server must use the exact " . "same URI to identify the install. Edit your .arcconfig or " . "phabricator/conf so they agree on the URI for the install.");
     }
 }
Example #6
0
 protected function getProxiedFuture()
 {
     if (!$this->future) {
         $params = $this->params;
         if (!$this->action) {
             throw new Exception(pht('You must %s!', 'setRawSlackQuery()'));
         }
         if (!$this->accessToken) {
             throw new Exception(pht('You must %s!', 'setAccessToken()'));
         }
         $uri = new PhutilURI('https://slack.com/');
         $uri->setPath('/api/' . $this->action);
         $uri->setQueryParam('token', $this->accessToken);
         $future = new HTTPSFuture($uri);
         $future->setData($this->params);
         $future->setMethod($this->method);
         $this->future = $future;
     }
     return $this->future;
 }
 public function processRequest()
 {
     $uri = PhabricatorEnv::getEnvConfig('notification.server-uri');
     $uri = new PhutilURI($uri);
     $uri->setPath('/status/');
     $future = id(new HTTPSFuture($uri))->setTimeout(3);
     try {
         list($body) = $future->resolvex();
         $body = json_decode($body, true);
         if (!is_array($body)) {
             throw new Exception("Expected JSON response from server!");
         }
         $status = $this->renderServerStatus($body);
     } catch (Exception $ex) {
         $status = new AphrontErrorView();
         $status->setTitle("Notification Server Issue");
         $status->appendChild('Unable to determine server status. This probably means the server ' . 'is not in great shape. The specific issue encountered was:' . '<br />' . '<br />' . '<strong>' . phutil_escape_html(get_class($ex)) . '</strong> ' . nl2br(phutil_escape_html($ex->getMessage())));
     }
     return $this->buildStandardPageResponse($status, array('title' => 'Aphlict Server Status'));
 }
 protected function getProxiedFuture()
 {
     if (!$this->future) {
         $params = $this->params;
         if (!$this->action) {
             throw new Exception(pht('You must %s!', 'setRawAsanaQuery()'));
         }
         if (!$this->accessToken) {
             throw new Exception(pht('You must %s!', 'setAccessToken()'));
         }
         $uri = new PhutilURI('https://app.asana.com/');
         $uri->setPath('/api/1.0/' . ltrim($this->action, '/'));
         $future = new HTTPSFuture($uri);
         $future->setData($this->params);
         $future->addHeader('Authorization', 'Bearer ' . $this->accessToken);
         $future->setMethod($this->method);
         $this->future = $future;
     }
     return $this->future;
 }
 protected function getProxiedFuture()
 {
     if (!$this->future) {
         $params = $this->params;
         if (!$this->action) {
             throw new Exception("You must setRawWordPressQuery()!");
         }
         if (!$this->accessToken) {
             throw new Exception("You must setAccessToken()!");
         }
         $uri = new PhutilURI('https://public-api.wordpress.com/');
         $uri->setPath('/rest/v1/' . ltrim($this->action, '/'));
         $future = new HTTPSFuture($uri);
         $future->setData($this->params);
         $future->setMethod($this->method);
         // NOTE: This is how WordPress.com REST API authenticates
         $future->addHeader('Authorization', 'Bearer ' . $this->accessToken);
         $this->future = $future;
     }
     return $this->future;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $alt = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
     $uri = new PhutilURI($alt);
     $alt_domain = $uri->getDomain();
     if ($alt_domain && $alt_domain != $request->getHost()) {
         return id(new AphrontRedirectResponse())->setURI($uri->setPath($request->getPath()));
     }
     $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $this->phid);
     if (!$file) {
         return new Aphront404Response();
     }
     if (!$file->validateSecretKey($this->key)) {
         return new Aphront403Response();
     }
     $data = $file->loadFileData();
     $response = new AphrontFileResponse();
     $response->setContent($data);
     $response->setCacheDurationInSeconds(60 * 60 * 24 * 30);
     $is_view = $file->isViewableInBrowser();
     if ($is_view) {
         $response->setMimeType($file->getViewableMimeType());
     } else {
         if (!$request->isHTTPPost()) {
             // NOTE: Require POST to download files. We'd rather go full-bore and
             // do a real CSRF check, but can't currently authenticate users on the
             // file domain. This should blunt any attacks based on iframes, script
             // tags, applet tags, etc., at least. Send the user to the "info" page
             // if they're using some other method.
             return id(new AphrontRedirectResponse())->setURI(PhabricatorEnv::getProductionURI($file->getBestURI()));
         }
         $response->setMimeType($file->getMimeType());
         $response->setDownload($file->getName());
     }
     return $response;
 }
Example #11
0
 protected function getProxiedFuture()
 {
     if (!$this->future) {
         $params = $this->params;
         if (!$this->action) {
             throw new Exception('You must setRawTwitchQuery()!');
         }
         if (!$this->accessToken) {
             throw new Exception('You must setAccessToken()!');
         }
         $uri = new PhutilURI('https://api.twitch.tv/');
         $uri->setPath('/kraken/' . ltrim($this->action, '/'));
         $uri->setQueryParam('oauth_token', $this->accessToken);
         $future = new HTTPSFuture($uri);
         $future->setData($this->params);
         $future->setMethod($this->method);
         // NOTE: This is how the Twitch API is versioned.
         $future->addHeader('Accept', 'application/vnd.twitchtv.2+json');
         // NOTE: This is required to avoid rate limiting.
         $future->addHeader('Client-ID', $this->clientID);
         $this->future = $future;
     }
     return $this->future;
 }
Example #12
0
 public function getViewURI()
 {
     if (!$this->getPHID()) {
         throw new Exception("You must save a file before you can generate a view URI.");
     }
     $alt = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
     if ($alt) {
         $path = '/file/alt/' . $this->getSecretKey() . '/' . $this->getPHID() . '/';
         $uri = new PhutilURI($alt);
         $uri->setPath($path);
         return (string) $uri;
     } else {
         return '/file/view/' . $this->getPHID() . '/';
     }
 }
 private function getURIObject()
 {
     // Users can provide Git/SCP-style URIs in the form "user@host:path".
     // In the general case, these are not equivalent to any "ssh://..." form
     // because the path is relative.
     if ($this->isBuiltin()) {
         $builtin_protocol = $this->getForcedProtocol();
         $builtin_domain = $this->getForcedHost();
         $raw_uri = "{$builtin_protocol}://{$builtin_domain}";
     } else {
         $raw_uri = $this->getURI();
     }
     $port = $this->getForcedPort();
     $default_ports = array('ssh' => 22, 'http' => 80, 'https' => 443);
     $uri = new PhutilURI($raw_uri);
     // Make sure to remove any password from the URI before we do anything
     // with it; this should always be provided by the associated credential.
     $uri->setPass(null);
     $protocol = $this->getForcedProtocol();
     if ($protocol) {
         $uri->setProtocol($protocol);
     }
     if ($port) {
         $uri->setPort($port);
     }
     // Remove any explicitly set default ports.
     $uri_port = $uri->getPort();
     $uri_protocol = $uri->getProtocol();
     $uri_default = idx($default_ports, $uri_protocol);
     if ($uri_default && $uri_default == $uri_port) {
         $uri->setPort(null);
     }
     $user = $this->getForcedUser();
     if ($user) {
         $uri->setUser($user);
     }
     $host = $this->getForcedHost();
     if ($host) {
         $uri->setDomain($host);
     }
     $path = $this->getForcedPath();
     if ($path) {
         $uri->setPath($path);
     }
     return $uri;
 }
Example #14
0
 if ($force_conduit) {
     $conduit_uri = $force_conduit;
 } else {
     $conduit_uri = $configuration_manager->getConfigFromAnySource('phabricator.uri');
     if ($conduit_uri === null) {
         $conduit_uri = $configuration_manager->getConfigFromAnySource('default');
     }
 }
 if ($conduit_uri) {
     // Set the URI path to '/api/'. TODO: Originally, I contemplated letting
     // you deploy Phabricator somewhere other than the domain root, but ended
     // up never pursuing that. We should get rid of all "/api/" silliness
     // in things users are expected to configure. This is already happening
     // to some degree, e.g. "arc install-certificate" does it for you.
     $conduit_uri = new PhutilURI($conduit_uri);
     $conduit_uri->setPath('/api/');
     $conduit_uri = (string) $conduit_uri;
 }
 $workflow->setConduitURI($conduit_uri);
 // Apply global CA bundle from configs.
 $ca_bundle = $configuration_manager->getConfigFromAnySource('https.cabundle');
 if ($ca_bundle) {
     $ca_bundle = Filesystem::resolvePath($ca_bundle, $working_copy->getProjectRoot());
     HTTPSFuture::setGlobalCABundleFromPath($ca_bundle);
 }
 $blind_key = 'https.blindly-trust-domains';
 $blind_trust = $configuration_manager->getConfigFromAnySource($blind_key);
 if ($blind_trust) {
     HTTPSFuture::setBlindlyTrustDomains($blind_trust);
 }
 if ($need_conduit) {
 private function makeInternalURI($uri_string)
 {
     $uri = new PhutilURI($uri_string);
     $proto = $uri->getProtocol();
     if ($proto !== 'svn+ssh') {
         throw new Exception(pht('Protocol for URI "%s" MUST be "svn+ssh".', $uri_string));
     }
     $path = $uri->getPath();
     // Subversion presumably deals with this, but make sure there's nothing
     // skethcy going on with the URI.
     if (preg_match('(/\\.\\./)', $path)) {
         throw new Exception(pht('String "/../" is invalid in path specification "%s".', $uri_string));
     }
     $repository = $this->loadRepository($path);
     $path = preg_replace('(^/diffusion/[A-Z]+)', rtrim($repository->getLocalPath(), '/'), $path);
     if (preg_match('(^/diffusion/[A-Z]+/\\z)', $path)) {
         $path = rtrim($path, '/');
     }
     $uri->setPath($path);
     // If this is happening during the handshake, these are the base URIs for
     // the request.
     if ($this->externalBaseURI === null) {
         $pre = (string) id(clone $uri)->setPath('');
         $this->externalBaseURI = $pre . '/diffusion/' . $repository->getCallsign();
         $this->internalBaseURI = $pre . rtrim($repository->getLocalPath(), '/');
     }
     return (string) $uri;
 }
 private function makeInternalURI($uri_string)
 {
     if ($this->isProxying) {
         return $uri_string;
     }
     $uri = new PhutilURI($uri_string);
     $repository = $this->getRepository();
     $path = $this->getPathFromSubversionURI($uri_string);
     $external_base = $this->getBaseRequestPath();
     // Replace "/diffusion/X" in the request with the repository local path,
     // so "/diffusion/X/master/" becomes "/path/to/repository/X/master/".
     $local_path = rtrim($repository->getLocalPath(), '/');
     $path = $local_path . substr($path, strlen($external_base));
     // NOTE: We are intentionally NOT removing username information from the
     // URI. Subversion retains it over the course of the request and considers
     // two repositories with different username identifiers to be distinct and
     // incompatible.
     $uri->setPath($path);
     // If this is happening during the handshake, these are the base URIs for
     // the request.
     if ($this->externalBaseURI === null) {
         $pre = (string) id(clone $uri)->setPath('');
         $external_path = $external_base;
         $external_path = $this->normalizeSVNPath($external_path);
         $this->externalBaseURI = $pre . $external_path;
         $internal_path = rtrim($repository->getLocalPath(), '/');
         $internal_path = $this->normalizeSVNPath($internal_path);
         $this->internalBaseURI = $pre . $internal_path;
     }
     return (string) $uri;
 }
Example #17
0
 public function run()
 {
     $argv = $this->getArgv();
     if (count($argv) !== 1) {
         throw new Exception("usage: PhabricatorIRCBot <json_config_file>");
     }
     $json_raw = Filesystem::readFile($argv[0]);
     $config = json_decode($json_raw, true);
     if (!is_array($config)) {
         throw new Exception("File '{$argv[0]}' is not valid JSON!");
     }
     $server = idx($config, 'server');
     $port = idx($config, 'port', 6667);
     $handlers = idx($config, 'handlers', array());
     $pass = idx($config, 'pass');
     $nick = idx($config, 'nick', 'phabot');
     $user = idx($config, 'user', $nick);
     $ssl = idx($config, 'ssl', false);
     $nickpass = idx($config, 'nickpass');
     $this->config = $config;
     if (!preg_match('/^[A-Za-z0-9_`[{}^|\\]\\-]+$/', $nick)) {
         throw new Exception("Nickname '{$nick}' is invalid!");
     }
     foreach ($handlers as $handler) {
         $obj = newv($handler, array($this));
         $this->handlers[] = $obj;
     }
     $conduit_uri = idx($config, 'conduit.uri');
     if ($conduit_uri) {
         $conduit_user = idx($config, 'conduit.user');
         $conduit_cert = idx($config, 'conduit.cert');
         // Normalize the path component of the URI so users can enter the
         // domain without the "/api/" part.
         $conduit_uri = new PhutilURI($conduit_uri);
         $conduit_uri->setPath('/api/');
         $conduit_uri = (string) $conduit_uri;
         $conduit = new ConduitClient($conduit_uri);
         $response = $conduit->callMethodSynchronous('conduit.connect', array('client' => 'PhabricatorIRCBot', 'clientVersion' => '1.0', 'clientDescription' => php_uname('n') . ':' . $nick, 'user' => $conduit_user, 'certificate' => $conduit_cert));
         $this->conduit = $conduit;
     }
     $errno = null;
     $error = null;
     if (!$ssl) {
         $socket = fsockopen($server, $port, $errno, $error);
     } else {
         $socket = fsockopen('ssl://' . $server, $port, $errno, $error);
     }
     if (!$socket) {
         throw new Exception("Failed to connect, #{$errno}: {$error}");
     }
     $ok = stream_set_blocking($socket, false);
     if (!$ok) {
         throw new Exception("Failed to set stream nonblocking.");
     }
     $this->socket = $socket;
     $this->writeCommand('USER', "{$user} 0 * :{$user}");
     if ($pass) {
         $this->writeCommand('PASS', "{$pass}");
     }
     $this->writeCommand('NICK', "{$nick}");
     $this->runSelectLoop();
 }
 protected final function getURI($path)
 {
     $base_uri = new PhutilURI($this->bot->getConfig('conduit.uri'));
     $base_uri->setPath($path);
     return (string) $base_uri;
 }
 public function testURIGeneration()
 {
     $uri = new PhutilURI('http://example.com');
     $uri->setPath('bar');
     $this->assertEqual('http://example.com/bar', $uri->__toString());
 }
 public static function getJIRAIssueBrowseURIFromJIRARestURI($uri, $object_id)
 {
     $uri = new PhutilURI($uri);
     // The JIRA install might not be at the domain root, so we may need to
     // keep an initial part of the path, like "/jira/". Find the API specific
     // part of the URI, strip it off, then replace it with the web version.
     $path = $uri->getPath();
     $pos = strrpos($path, 'rest/api/2/issue/');
     if ($pos === false) {
         return null;
     }
     $path = substr($path, 0, $pos);
     $path = $path . 'browse/' . $object_id;
     $uri->setPath($path);
     return (string) $uri;
 }
 private function determineConduitURI()
 {
     $uri = $this->getArgument('uri');
     if (count($uri) > 1) {
         throw new ArcanistUsageException(pht('Specify at most one URI.'));
     } else {
         if (count($uri) == 1) {
             $uri = reset($uri);
         } else {
             $conduit_uri = $this->getConduitURI();
             if (!$conduit_uri) {
                 throw new ArcanistUsageException(pht('Specify an explicit URI or run this command from within a ' . 'project which is configured with a %s.', '.arcconfig'));
             }
             $uri = $conduit_uri;
         }
     }
     $uri_object = new PhutilURI($uri);
     if (!$uri_object->getProtocol() || !$uri_object->getDomain()) {
         throw new ArcanistUsageException(pht('Server URI "%s" must include a protocol and domain. It should be ' . 'in the form "%s".', $uri, 'https://phabricator.example.com/'));
     }
     $uri_object->setPath('/api/');
     return (string) $uri_object;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $viewer_is_anonymous = !$user->isLoggedIn();
     $params = array_filter(array('status' => $request->getStr('status'), 'order' => $request->getStr('order')));
     $default_filter = $viewer_is_anonymous ? 'all' : 'active';
     $filters = $this->getFilters();
     $this->filter = $this->selectFilter($filters, $this->filter, $default_filter);
     // Redirect from search to canonical URL.
     $phid_arr = $request->getArr('view_user');
     if ($phid_arr) {
         $view_user = id(new PhabricatorUser())->loadOneWhere('phid = %s', head($phid_arr));
         $base_uri = '/differential/filter/' . $this->filter . '/';
         if ($view_user) {
             // This is a user, so generate a pretty URI.
             $uri = $base_uri . phutil_escape_uri($view_user->getUserName()) . '/';
         } else {
             // We're assuming this is a mailing list, generate an ugly URI.
             $uri = $base_uri;
             $params['phid'] = head($phid_arr);
         }
         $uri = new PhutilURI($uri);
         $uri->setQueryParams($params);
         return id(new AphrontRedirectResponse())->setURI($uri);
     }
     $uri = new PhutilURI('/differential/filter/' . $this->filter . '/');
     $uri->setQueryParams($params);
     $username = '';
     if ($this->username) {
         $view_user = id(new PhabricatorUser())->loadOneWhere('userName = %s', $this->username);
         if (!$view_user) {
             return new Aphront404Response();
         }
         $username = phutil_escape_uri($this->username) . '/';
         $uri->setPath('/differential/filter/' . $this->filter . '/' . $username);
         $params['phid'] = $view_user->getPHID();
     } else {
         $phid = $request->getStr('phid');
         if (strlen($phid)) {
             $params['phid'] = $phid;
         }
     }
     // Fill in the defaults we'll actually use for calculations if any
     // parameters are missing.
     $params += array('phid' => $user->getPHID(), 'status' => 'all', 'order' => 'modified');
     $side_nav = new AphrontSideNavView();
     foreach ($filters as $filter) {
         list($filter_name, $display_name) = $filter;
         if ($filter_name) {
             $href = clone $uri;
             $href->setPath('/differential/filter/' . $filter_name . '/' . $username);
             if ($filter_name == $this->filter) {
                 $class = 'aphront-side-nav-selected';
             } else {
                 $class = null;
             }
             $item = phutil_render_tag('a', array('href' => (string) $href, 'class' => $class), phutil_escape_html($display_name));
         } else {
             $item = phutil_render_tag('span', array(), phutil_escape_html($display_name));
         }
         $side_nav->addNavItem($item);
     }
     $panels = array();
     $handles = array();
     $controls = $this->getFilterControls($this->filter);
     if ($this->getFilterRequiresUser($this->filter) && !$params['phid']) {
         // In the anonymous case, we still want to let you see some user's
         // list, but we don't have a default PHID to provide (normally, we use
         // the viewing user's). Show a warning instead.
         $warning = new AphrontErrorView();
         $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
         $warning->setTitle('User Required');
         $warning->appendChild('This filter requires that a user be specified above.');
         $panels[] = $warning;
     } else {
         $query = $this->buildQuery($this->filter, $params['phid']);
         $pager = null;
         if ($this->getFilterAllowsPaging($this->filter)) {
             $pager = new AphrontPagerView();
             $pager->setOffset($request->getInt('page'));
             $pager->setPageSize(1000);
             $pager->setURI($uri, 'page');
             $query->setOffset($pager->getOffset());
             $query->setLimit($pager->getPageSize() + 1);
         }
         foreach ($controls as $control) {
             $this->applyControlToQuery($control, $query, $params);
         }
         $revisions = $query->execute();
         if ($pager) {
             $revisions = $pager->sliceResults($revisions);
         }
         $views = $this->buildViews($this->filter, $params['phid'], $revisions);
         $view_objects = array();
         foreach ($views as $view) {
             if (empty($view['special'])) {
                 $view_objects[] = $view['view'];
             }
         }
         $phids = array_mergev(mpull($view_objects, 'getRequiredHandlePHIDs'));
         $phids[] = $params['phid'];
         $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
         foreach ($views as $view) {
             if (empty($view['special'])) {
                 $view['view']->setHandles($handles);
             }
             $panel = new AphrontPanelView();
             $panel->setHeader($view['title']);
             $panel->appendChild($view['view']);
             if ($pager) {
                 $panel->appendChild($pager);
             }
             $panels[] = $panel;
         }
     }
     $filter_form = id(new AphrontFormView())->setMethod('GET')->setAction('/differential/filter/' . $this->filter . '/')->setUser($user);
     foreach ($controls as $control) {
         $control_view = $this->renderControl($control, $handles, $uri, $params);
         $filter_form->appendChild($control_view);
     }
     $filter_form->addHiddenInput('status', $params['status'])->addHiddenInput('order', $params['order'])->appendChild(id(new AphrontFormSubmitControl())->setValue('Filter Revisions'));
     $filter_view = new AphrontListFilterView();
     $filter_view->appendChild($filter_form);
     if (!$viewer_is_anonymous) {
         $create_uri = new PhutilURI('/differential/diff/create/');
         $filter_view->addButton(phutil_render_tag('a', array('href' => (string) $create_uri, 'class' => 'green button'), 'Create Revision'));
     }
     $side_nav->appendChild($filter_view);
     foreach ($panels as $panel) {
         $side_nav->appendChild($panel);
     }
     return $this->buildStandardPageResponse($side_nav, array('title' => 'Differential Home'));
 }
Example #23
0
 /**
  * Get the fully-qualified production URI for a static resource path.
  *
  * @task read
  */
 public static function getCDNURI($path)
 {
     $alt = self::getEnvConfig('security.alternate-file-domain');
     if (!$alt) {
         $alt = self::getEnvConfig('phabricator.base-uri');
     }
     $uri = new PhutilURI($alt);
     $uri->setPath($path);
     return (string) $uri;
 }
 private function executeRequest($path, array $data, $method = 'GET')
 {
     $uri = new PhutilURI($this->uri);
     $uri->setPath($this->index);
     $uri->appendPath($path);
     $data = json_encode($data);
     $future = new HTTPSFuture($uri, $data);
     if ($method != 'GET') {
         $future->setMethod($method);
     }
     if ($this->getTimeout()) {
         $future->setTimeout($this->getTimeout());
     }
     list($body) = $future->resolvex();
     if ($method != 'GET') {
         return null;
     }
     try {
         return phutil_json_decode($body);
     } catch (PhutilJSONParserException $ex) {
         throw new PhutilProxyException(pht('ElasticSearch server returned invalid JSON!'), $ex);
     }
 }
Example #25
0
 /**
  * Build a new @{class:HTTPSFuture} which proxies this request to another
  * node in the cluster.
  *
  * IMPORTANT: This is very dangerous!
  *
  * The future forwards authentication information present in the request.
  * Proxied requests must only be sent to trusted hosts. (We attempt to
  * enforce this.)
  *
  * This is not a general-purpose proxying method; it is a specialized
  * method with niche applications and severe security implications.
  *
  * @param string URI identifying the host we are proxying the request to.
  * @return HTTPSFuture New proxy future.
  *
  * @phutil-external-symbol class PhabricatorStartup
  */
 public function newClusterProxyFuture($uri)
 {
     $uri = new PhutilURI($uri);
     $domain = $uri->getDomain();
     $ip = gethostbyname($domain);
     if (!$ip) {
         throw new Exception(pht('Unable to resolve domain "%s"!', $domain));
     }
     if (!PhabricatorEnv::isClusterAddress($ip)) {
         throw new Exception(pht('Refusing to proxy a request to IP address ("%s") which is not ' . 'in the cluster address block (this address was derived by ' . 'resolving the domain "%s").', $ip, $domain));
     }
     $uri->setPath($this->getPath());
     $uri->setQueryParams(self::flattenData($_GET));
     $input = PhabricatorStartup::getRawInput();
     $future = id(new HTTPSFuture($uri))->addHeader('Host', self::getHost())->addHeader('X-Phabricator-Cluster', true)->setMethod($_SERVER['REQUEST_METHOD'])->write($input);
     if (isset($_SERVER['PHP_AUTH_USER'])) {
         $future->setHTTPBasicAuthCredentials($_SERVER['PHP_AUTH_USER'], new PhutilOpaqueEnvelope(idx($_SERVER, 'PHP_AUTH_PW', '')));
     }
     $headers = array();
     $seen = array();
     // NOTE: apache_request_headers() might provide a nicer way to do this,
     // but isn't available under FCGI until PHP 5.4.0.
     foreach ($_SERVER as $key => $value) {
         if (preg_match('/^HTTP_/', $key)) {
             // Unmangle the header as best we can.
             $key = str_replace('_', ' ', $key);
             $key = strtolower($key);
             $key = ucwords($key);
             $key = str_replace(' ', '-', $key);
             $headers[] = array($key, $value);
             $seen[$key] = true;
         }
     }
     // In some situations, this may not be mapped into the HTTP_X constants.
     // CONTENT_LENGTH is similarly affected, but we trust cURL to take care
     // of that if it matters, since we're handing off a request body.
     if (empty($seen['Content-Type'])) {
         if (isset($_SERVER['CONTENT_TYPE'])) {
             $headers[] = array('Content-Type', $_SERVER['CONTENT_TYPE']);
         }
     }
     foreach ($headers as $header) {
         list($key, $value) = $header;
         switch ($key) {
             case 'Host':
             case 'Authorization':
                 // Don't forward these headers, we've already handled them elsewhere.
                 unset($headers[$key]);
                 break;
             default:
                 break;
         }
     }
     foreach ($headers as $header) {
         list($key, $value) = $header;
         $future->addHeader($key, $value);
     }
     return $future;
 }
 protected function performPost($endpoint, $data = null)
 {
     $uri = new PhutilURI($this->server);
     $uri->setPath($endpoint);
     $payload = json_encode($data);
     list($output) = id(new HTTPSFuture($uri))->setMethod('POST')->addHeader('Content-Type', 'application/json')->addHeader('Authorization', $this->getAuthorizationHeader())->setData($payload)->resolvex();
     $output = trim($output);
     if (strlen($output)) {
         return json_decode($output, true);
     }
     return true;
 }
 private function executeRequest($path, array $data, $is_write = false)
 {
     $uri = new PhutilURI($this->uri);
     $data = json_encode($data);
     $uri->setPath($path);
     $future = new HTTPSFuture($uri, $data);
     if ($is_write) {
         $future->setMethod('PUT');
     }
     if ($this->getTimeout()) {
         $future->setTimeout($this->getTimeout());
     }
     list($body) = $future->resolvex();
     if ($is_write) {
         return null;
     }
     $body = json_decode($body, true);
     if (!is_array($body)) {
         throw new Exception("elasticsearch server returned invalid JSON!");
     }
     return $body;
 }
 private function determineConduitURI()
 {
     $uri = $this->getArgument('uri');
     if (count($uri) > 1) {
         throw new ArcanistUsageException("Specify at most one URI.");
     } else {
         if (count($uri) == 1) {
             $uri = reset($uri);
         } else {
             $conduit_uri = $this->getConduitURI();
             if (!$conduit_uri) {
                 throw new ArcanistUsageException("Specify an explicit URI or run this command from within a project " . "which is configured with a .arcconfig.");
             }
             $uri = $conduit_uri;
         }
     }
     $uri = new PhutilURI($uri);
     $uri->setPath('/api/');
     return (string) $uri;
 }
 /**
  * Get the repository's HTTP clone/checkout URI, if one exists.
  */
 public function getHTTPCloneURIObject()
 {
     if (!$this->isHosted()) {
         if ($this->shouldUseHTTP()) {
             return $this->getRemoteURIObject();
         } else {
             return null;
         }
     }
     $serve_http = $this->getServeOverHTTP();
     if ($serve_http === self::SERVE_OFF) {
         return null;
     }
     $uri = PhabricatorEnv::getProductionURI($this->getURI());
     $uri = new PhutilURI($uri);
     if ($this->isGit()) {
         $uri->setPath($uri->getPath() . $this->getCloneName() . '.git');
     } else {
         if ($this->isHg()) {
             $uri->setPath($uri->getPath() . $this->getCloneName() . '/');
         }
     }
     return $uri;
 }
 private function getRawHTTPCloneURIObject()
 {
     $uri = PhabricatorEnv::getProductionURI($this->getURI());
     $uri = new PhutilURI($uri);
     if ($this->isGit()) {
         $uri->setPath($uri->getPath() . $this->getCloneName() . '.git');
     } else {
         if ($this->isHg()) {
             $uri->setPath($uri->getPath() . $this->getCloneName() . '/');
         }
     }
     return $uri;
 }