public function buildResponseString() { $console = $this->getConsole(); if ($console) { // NOTE: We're stripping query parameters here both for readability and // to mitigate BREACH and similar attacks. The parameters are available // in the "Request" tab, so this should not impact usability. See T3684. $uri = $this->getRequest()->getRequestURI(); $uri = new PhutilURI($uri); $uri->setQueryParams(array()); Javelin::initBehavior('dark-console', array('uri' => (string) $uri, 'key' => $console->getKey($this->getRequest()), 'color' => $console->getColor(), 'quicksand' => $this->getRequest()->isQuicksand())); } // Flatten the response first, so we initialize any behaviors and metadata // we need to. $content = array('payload' => $this->content); $this->encodeJSONForHTTPResponse($content); $response = CelerityAPI::getStaticResourceResponse(); $request = $this->getRequest(); if ($request) { $viewer = $request->getViewer(); if ($viewer) { $postprocessor_key = $viewer->getUserSetting(PhabricatorAccessibilitySetting::SETTINGKEY); if (strlen($postprocessor_key)) { $response->setPostprocessorKey($postprocessor_key); } } } $object = $response->buildAjaxResponse($content['payload'], $this->error); $response_json = $this->encodeJSONForHTTPResponse($object); return $this->addJSONShield($response_json); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); if ($request->isFormPost()) { $uri = new PhutilURI('/fact/chart/'); $uri->setQueryParam('y1', $request->getStr('y1')); return id(new AphrontRedirectResponse())->setURI($uri); } $types = array('+N:*', '+N:DREV', 'updated'); $engines = PhabricatorFactEngine::loadAllEngines(); $specs = PhabricatorFactSpec::newSpecsForFactTypes($engines, $types); $facts = id(new PhabricatorFactAggregate())->loadAllWhere('factType IN (%Ls)', $types); $rows = array(); foreach ($facts as $fact) { $spec = $specs[$fact->getFactType()]; $name = $spec->getName(); $value = $spec->formatValueForDisplay($user, $fact->getValueX()); $rows[] = array(phutil_escape_html($name), phutil_escape_html($value)); } $table = new AphrontTableView($rows); $table->setHeaders(array('Fact', 'Value')); $table->setColumnClasses(array('wide', 'n')); $panel = new AphrontPanelView(); $panel->setHeader('Facts!'); $panel->appendChild($table); $chart_form = $this->buildChartForm(); return $this->buildStandardPageResponse(array($chart_form, $panel), array('title' => 'Facts!')); }
protected function applyCustomInternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { case PhameBlogTransaction::TYPE_NAME: return $object->setName($xaction->getNewValue()); case PhameBlogTransaction::TYPE_SUBTITLE: return $object->setSubtitle($xaction->getNewValue()); case PhameBlogTransaction::TYPE_DESCRIPTION: return $object->setDescription($xaction->getNewValue()); case PhameBlogTransaction::TYPE_FULLDOMAIN: $new_value = $xaction->getNewValue(); if (strlen($new_value)) { $uri = new PhutilURI($new_value); $domain = $uri->getDomain(); $object->setDomain($domain); } else { $object->setDomain(null); } $object->setDomainFullURI($new_value); return; case PhameBlogTransaction::TYPE_PROFILEIMAGE: return $object->setProfileImagePHID($xaction->getNewValue()); case PhameBlogTransaction::TYPE_HEADERIMAGE: return $object->setHeaderImagePHID($xaction->getNewValue()); case PhameBlogTransaction::TYPE_STATUS: return $object->setStatus($xaction->getNewValue()); case PhameBlogTransaction::TYPE_PARENTSITE: return $object->setParentSite($xaction->getNewValue()); case PhameBlogTransaction::TYPE_PARENTDOMAIN: return $object->setParentDomain($xaction->getNewValue()); } return parent::applyCustomInternalTransaction($object, $xaction); }
public static function newFromRawCorpus($corpus) { $obj = new ArcanistDifferentialCommitMessage(); $obj->rawCorpus = $corpus; // Parse older-style "123" fields, or newer-style full-URI fields. // TODO: Remove support for older-style fields. $match = null; if (preg_match('/^Differential Revision:\\s*(.*)/im', $corpus, $match)) { $revision_id = trim($match[1]); if (strlen($revision_id)) { if (preg_match('/^D?\\d+$/', $revision_id)) { $obj->revisionID = (int) trim($revision_id, 'D'); } else { $uri = new PhutilURI($revision_id); $path = $uri->getPath(); $path = trim($path, '/'); if (preg_match('/^D\\d+$/', $path)) { $obj->revisionID = (int) trim($path, 'D'); } else { throw new ArcanistUsageException("Invalid 'Differential Revision' field. The field should have a " . "Phabricator URI like 'http://phabricator.example.com/D123', " . "but has '{$match[1]}'."); } } } } $pattern = '/^git-svn-id:\\s*([^@]+)@(\\d+)\\s+(.*)$/m'; if (preg_match($pattern, $corpus, $match)) { $obj->gitSVNBaseRevision = $match[1] . '@' . $match[2]; $obj->gitSVNBasePath = $match[1]; $obj->gitSVNUUID = $match[3]; } return $obj; }
public function processRequest() { $request = $this->getRequest(); if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { return new Aphront400Response(); } if ($request->getUser()->getPHID()) { $view = new AphrontRequestFailureView(); $view->setHeader('Already Logged In'); $view->appendChild('<p>You are already logged in.</p>'); $view->appendChild('<div class="aphront-failure-continue">' . '<a class="button" href="/">Return Home</a>' . '</div>'); return $this->buildStandardPageResponse($view, array('title' => 'Already Logged In')); } $token = $this->token; $email = $request->getStr('email'); $target_user = id(new PhabricatorUser())->loadOneWhere('email = %s', $email); if (!$target_user || !$target_user->validateEmailToken($token)) { $view = new AphrontRequestFailureView(); $view->setHeader('Unable to Login'); $view->appendChild('<p>The authentication information in the link you clicked is ' . 'invalid or out of date. Make sure you are copy-and-pasting the ' . 'entire link into your browser. You can try again, or request ' . 'a new email.</p>'); $view->appendChild('<div class="aphront-failure-continue">' . '<a class="button" href="/login/email/">Send Another Email</a>' . '</div>'); return $this->buildStandardPageResponse($view, array('title' => 'Email Sent')); } $session_key = $target_user->establishSession('web'); $request->setCookie('phusr', $target_user->getUsername()); $request->setCookie('phsid', $session_key); if (PhabricatorEnv::getEnvConfig('account.editable')) { $next = '/settings/page/password/?token=' . $token; } else { $next = '/'; } $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams(array('phusr' => $target_user->getUsername(), 'next' => $next)); return id(new AphrontRedirectResponse())->setURI((string) $uri); }
public function processControllerRequest(PhortuneProviderController $controller, AphrontRequest $request) { $cart = $controller->loadCart($request->getInt('cartID')); if (!$cart) { return new Aphront404Response(); } switch ($controller->getAction()) { case 'checkout': $return_uri = $this->getControllerURI('charge', array('cartID' => $cart->getID())); $cancel_uri = $this->getControllerURI('cancel', array('cartID' => $cart->getID())); $total_in_cents = $cart->getTotalPriceInCents(); $price = PhortuneCurrency::newFromUSDCents($total_in_cents); $result = $this->newPaypalAPICall()->setRawPayPalQuery('SetExpressCheckout', array('PAYMENTREQUEST_0_AMT' => $price->formatBareValue(), 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(), 'RETURNURL' => $return_uri, 'CANCELURL' => $cancel_uri, 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale'))->resolve(); $uri = new PhutilURI('https://www.sandbox.paypal.com/cgi-bin/webscr'); $uri->setQueryParams(array('cmd' => '_express-checkout', 'token' => $result['TOKEN'])); return id(new AphrontRedirectResponse())->setIsExternal(true)->setURI($uri); case 'charge': var_dump($_REQUEST); break; case 'cancel': var_dump($_REQUEST); break; } throw new Exception("The rest of this isn't implemented yet."); }
protected function didValidateOption(PhabricatorConfigOption $option, $value) { $key = $option->getKey(); if ($key == 'phabricator.base-uri' || $key == 'phabricator.production-uri') { $uri = new PhutilURI($value); $protocol = $uri->getProtocol(); if ($protocol !== 'http' && $protocol !== 'https') { throw new PhabricatorConfigValidationException(pht("Config option '%s' is invalid. The URI must start with " . "%s' or '%s'.", 'http://', 'https://', $key)); } $domain = $uri->getDomain(); if (strpos($domain, '.') === false) { throw new PhabricatorConfigValidationException(pht("Config option '%s' is invalid. The URI must contain a dot " . "('%s'), like '%s', not just a bare name like '%s'. Some web " . "browsers will not set cookies on domains with no TLD.", '.', 'http://example.com/', 'http://example/', $key)); } $path = $uri->getPath(); if ($path !== '' && $path !== '/') { throw new PhabricatorConfigValidationException(pht("Config option '%s' is invalid. The URI must NOT have a path, " . "e.g. '%s' is OK, but '%s' is not. Phabricator must be installed " . "on an entire domain; it can not be installed on a path.", $key, 'http://phabricator.example.com/', 'http://example.com/phabricator/')); } } if ($key === 'phabricator.timezone') { $old = date_default_timezone_get(); $ok = @date_default_timezone_set($value); @date_default_timezone_set($old); if (!$ok) { throw new PhabricatorConfigValidationException(pht("Config option '%s' is invalid. The timezone identifier must " . "be a valid timezone identifier recognized by PHP, like '%s'. " . "\n You can find a list of valid identifiers here: %s", $key, 'America/Los_Angeles', 'http://php.net/manual/timezones.php')); } } }
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; }
protected function getProxyCommand() { $uri = new PhutilURI($this->proxyURI); $username = AlmanacKeys::getClusterSSHUser(); if ($username === null) { throw new Exception(pht('Unable to determine the username to connect with when trying ' . 'to proxy an SSH request within the Phabricator cluster.')); } $port = $uri->getPort(); $host = $uri->getDomain(); $key_path = AlmanacKeys::getKeyPath('device.key'); if (!Filesystem::pathExists($key_path)) { throw new Exception(pht('Unable to proxy this SSH request within the cluster: this device ' . 'is not registered and has a missing device key (expected to ' . 'find key at "%s").', $key_path)); } $options = array(); $options[] = '-o'; $options[] = 'StrictHostKeyChecking=no'; $options[] = '-o'; $options[] = 'UserKnownHostsFile=/dev/null'; // This is suppressing "added <address> to the list of known hosts" // messages, which are confusing and irrelevant when they arise from // proxied requests. It might also be suppressing lots of useful errors, // of course. Ideally, we would enforce host keys eventually. $options[] = '-o'; $options[] = 'LogLevel=quiet'; // NOTE: We prefix the command with "@username", which the far end of the // connection will parse in order to act as the specified user. This // behavior is only available to cluster requests signed by a trusted // device key. return csprintf('ssh %Ls -l %s -i %s -p %s %s -- %s %Ls', $options, $username, $key_path, $port, $host, '@' . $this->getUser()->getUsername(), $this->getOriginalArguments()); }
/** * Makes sure a given custom blog uri is properly configured in DNS * to point at this Phabricator instance. If there is an error in * the configuration, return a string describing the error and how * to fix it. If there is no error, return an empty string. * * @return string */ public function validateCustomDomain($custom_domain) { $example_domain = 'blog.example.com'; $label = pht('Invalid'); // note this "uri" should be pretty busted given the desired input // so just use it to test if there's a protocol specified $uri = new PhutilURI($custom_domain); if ($uri->getProtocol()) { return array($label, pht('The custom domain should not include a protocol. Just provide ' . 'the bare domain name (for example, "%s").', $example_domain)); } if ($uri->getPort()) { return array($label, pht('The custom domain should not include a port number. Just provide ' . 'the bare domain name (for example, "%s").', $example_domain)); } if (strpos($custom_domain, '/') !== false) { return array($label, pht('The custom domain should not specify a path (hosting a Phame ' . 'blog at a path is currently not supported). Instead, just provide ' . 'the bare domain name (for example, "%s").', $example_domain)); } if (strpos($custom_domain, '.') === false) { return array($label, pht('The custom domain should contain at least one dot (.) because ' . 'some browsers fail to set cookies on domains without a dot. ' . 'Instead, use a normal looking domain name like "%s".', $example_domain)); } if (!PhabricatorEnv::getEnvConfig('policy.allow-public')) { $href = PhabricatorEnv::getProductionURI('/config/edit/policy.allow-public/'); return array(pht('Fix Configuration'), pht('For custom domains to work, this Phabricator instance must be ' . 'configured to allow the public access policy. Configure this ' . 'setting %s, or ask an administrator to configure this setting. ' . 'The domain can be specified later once this setting has been ' . 'changed.', phutil_tag('a', array('href' => $href), pht('here')))); } return null; }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); if ($request->isFormPost()) { $uri = new PhutilURI('/fact/chart/'); $uri->setQueryParam('y1', $request->getStr('y1')); return id(new AphrontRedirectResponse())->setURI($uri); } $types = array('+N:*', '+N:DREV', 'updated'); $engines = PhabricatorFactEngine::loadAllEngines(); $specs = PhabricatorFactSpec::newSpecsForFactTypes($engines, $types); $facts = id(new PhabricatorFactAggregate())->loadAllWhere('factType IN (%Ls)', $types); $rows = array(); foreach ($facts as $fact) { $spec = $specs[$fact->getFactType()]; $name = $spec->getName(); $value = $spec->formatValueForDisplay($viewer, $fact->getValueX()); $rows[] = array($name, $value); } $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Fact'), pht('Value'))); $table->setColumnClasses(array('wide', 'n')); $panel = new PHUIObjectBoxView(); $panel->setHeaderText(pht('Facts')); $panel->setTable($table); $chart_form = $this->buildChartForm(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Home')); $title = pht('Facts'); return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild(array($chart_form, $panel)); }
public function markupDocumentLink($matches) { $link = trim($matches[1]); $name = trim(idx($matches, 2, $link)); if (empty($matches[2])) { $name = explode('/', trim($name, '/')); $name = end($name); } $uri = new PhutilURI($link); $slug = $uri->getPath(); $fragment = $uri->getFragment(); $slug = PhabricatorSlug::normalize($slug); $slug = PhrictionDocument::getSlugURI($slug); $href = (string) id(new PhutilURI($slug))->setFragment($fragment); if ($this->getEngine()->getState('toc')) { $text = $name; } else { if ($this->getEngine()->isTextMode()) { return PhabricatorEnv::getProductionURI($href); } else { $text = $this->newTag('a', array('href' => $href, 'class' => 'phriction-link'), $name); } } return $this->getEngine()->storeText($text); }
protected function renderInput() { self::requireLib(); $uri = new PhutilURI(PhabricatorEnv::getEnvConfig('phabricator.base-uri')); $protocol = $uri->getProtocol(); $use_ssl = $protocol == 'https'; return phutil_safe_html(recaptcha_get_html(PhabricatorEnv::getEnvConfig('recaptcha.public-key'), $error = null, $use_ssl)); }
public function getBrowseURI() { if (!$this->isBrowsable()) { return null; } $uri = new PhutilURI('/typeahead/browse/' . get_class($this) . '/'); $uri->setQueryParams($this->parameters); return (string) $uri; }
protected function getProviderConfigurationHelp() { $login_uri = PhabricatorEnv::getURI($this->getLoginURI()); $uri = new PhutilURI(PhabricatorEnv::getProductionURI('/')); $https_note = null; if ($uri->getProtocol() !== 'https') { $https_note = pht('NOTE: Amazon **requires** HTTPS, but your Phabricator install does ' . 'not use HTTPS. **You will not be able to add Amazon as an ' . 'authentication provider until you configure HTTPS on this install**.'); } return pht("%s\n\n" . "To configure Amazon OAuth, create a new 'API Project' here:" . "\n\n" . "http://login.amazon.com/manageApps" . "\n\n" . "Use these settings:" . "\n\n" . " - **Allowed Return URLs:** Add this: `%s`" . "\n\n" . "After completing configuration, copy the **Client ID** and " . "**Client Secret** to the fields above.", $https_note, $login_uri); }
private function getUserInfo() { if ($this->userInfo === null) { $uri = new PhutilURI('https://api.twitter.com/1.1/users/show.json'); $uri->setQueryParams(array('user_id' => $this->getAccountID())); $data = $this->newOAuth1Future($uri)->setMethod('GET')->resolveJSON(); $this->userInfo = $data; } return $this->userInfo; }
private function buildLoginMenu() { $controller = $this->getController(); $uri = new PhutilURI('/auth/start/'); if ($controller) { $path = $controller->getRequest()->getPath(); $uri->setQueryParam('next', $path); } $bar_item = id(new PHUIListItemView())->addClass('core-menu-item')->setName(pht('Log In'))->setIcon('fa-sign-in')->setHref($uri)->setAural(pht('Log In')); return id(new PHUIMainMenuView())->setOrder(900)->setMenuBarItem($bar_item); }
public function render() { $handles = $this->handles; require_celerity_resource('maniphest-task-summary-css'); $list = new PHUIObjectItemListView(); if ($this->noDataString) { $list->setNoDataString($this->noDataString); } else { $list->setNoDataString(pht('No tasks.')); } $status_map = ManiphestTaskStatus::getTaskStatusMap(); $color_map = ManiphestTaskPriority::getColorMap(); $priority_map = ManiphestTaskPriority::getTaskPriorityMap(); if ($this->showBatchControls) { Javelin::initBehavior('maniphest-list-editor'); } foreach ($this->tasks as $task) { $item = id(new PHUIObjectItemView())->setUser($this->getUser())->setObject($task)->setObjectName('T' . $task->getID())->setHeader($task->getTitle())->setHref('/T' . $task->getID()); if ($task->getOwnerPHID()) { $owner = $handles[$task->getOwnerPHID()]; $item->addByline(pht('Assigned: %s', $owner->renderLink())); } $status = $task->getStatus(); $pri = idx($priority_map, $task->getPriority()); $status_name = idx($status_map, $task->getStatus()); $tooltip = pht('%s, %s', $status_name, $pri); $icon = ManiphestTaskStatus::getStatusIcon($task->getStatus()); $color = idx($color_map, $task->getPriority(), 'grey'); if ($task->isClosed()) { $item->setDisabled(true); $color = 'grey'; } $item->setStatusIcon($icon . ' ' . $color, $tooltip); $item->addIcon('none', phabricator_datetime($task->getDateModified(), $this->getUser())); if ($this->showSubpriorityControls) { $item->setGrippable(true); } if ($this->showSubpriorityControls || $this->showBatchControls) { $item->addSigil('maniphest-task'); } $project_handles = array_select_keys($handles, array_reverse($task->getProjectPHIDs())); $item->addAttribute(id(new PHUIHandleTagListView())->setLimit(4)->setNoDataString(pht('No Projects'))->setSlim(true)->setHandles($project_handles)); $item->setMetadata(array('taskID' => $task->getID())); if ($this->showBatchControls) { $href = new PhutilURI('/maniphest/task/edit/' . $task->getID() . '/'); if (!$this->showSubpriorityControls) { $href->setQueryParam('ungrippable', 'true'); } $item->addAction(id(new PHUIListItemView())->setIcon('fa-pencil')->addSigil('maniphest-edit-task')->setHref($href)); } $list->addItem($item); } return $list; }
public function processAddFactorForm(AphrontFormView $form, AphrontRequest $request, PhabricatorUser $user) { $totp_token_type = PhabricatorAuthTOTPKeyTemporaryTokenType::TOKENTYPE; $key = $request->getStr('totpkey'); if (strlen($key)) { // If the user is providing a key, make sure it's a key we generated. // This raises the barrier to theoretical attacks where an attacker might // provide a known key (such attacks are already prevented by CSRF, but // this is a second barrier to overcome). // (We store and verify the hash of the key, not the key itself, to limit // how useful the data in the table is to an attacker.) $temporary_token = id(new PhabricatorAuthTemporaryTokenQuery())->setViewer($user)->withTokenResources(array($user->getPHID()))->withTokenTypes(array($totp_token_type))->withExpired(false)->withTokenCodes(array(PhabricatorHash::digest($key)))->executeOne(); if (!$temporary_token) { // If we don't have a matching token, regenerate the key below. $key = null; } } if (!strlen($key)) { $key = self::generateNewTOTPKey(); // Mark this key as one we generated, so the user is allowed to submit // a response for it. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); id(new PhabricatorAuthTemporaryToken())->setTokenResource($user->getPHID())->setTokenType($totp_token_type)->setTokenExpires(time() + phutil_units('1 hour in seconds'))->setTokenCode(PhabricatorHash::digest($key))->save(); unset($unguarded); } $code = $request->getStr('totpcode'); $e_code = true; if ($request->getExists('totp')) { $okay = self::verifyTOTPCode($user, new PhutilOpaqueEnvelope($key), $code); if ($okay) { $config = $this->newConfigForUser($user)->setFactorName(pht('Mobile App (TOTP)'))->setFactorSecret($key); return $config; } else { if (!strlen($code)) { $e_code = pht('Required'); } else { $e_code = pht('Invalid'); } } } $form->addHiddenInput('totp', true); $form->addHiddenInput('totpkey', $key); $form->appendRemarkupInstructions(pht('First, download an authenticator application on your phone. Two ' . 'applications which work well are **Authy** and **Google ' . 'Authenticator**, but any other TOTP application should also work.')); $form->appendInstructions(pht('Launch the application on your phone, and add a new entry for ' . 'this Phabricator install. When prompted, scan the QR code or ' . 'manually enter the key shown below into the application.')); $prod_uri = new PhutilURI(PhabricatorEnv::getProductionURI('/')); $issuer = $prod_uri->getDomain(); $uri = urisprintf('otpauth://totp/%s:%s?secret=%s&issuer=%s', $issuer, $user->getUsername(), $key, $issuer); $qrcode = $this->renderQRCode($uri); $form->appendChild($qrcode); $form->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Key'))->setValue(phutil_tag('strong', array(), $key))); $form->appendInstructions(pht('(If given an option, select that this key is "Time Based", not ' . '"Counter Based".)')); $form->appendInstructions(pht('After entering the key, the application should display a numeric ' . 'code. Enter that code below to confirm that you have configured ' . 'the authenticator correctly:')); $form->appendChild(id(new PHUIFormNumberControl())->setLabel(pht('TOTP Code'))->setName('totpcode')->setValue($code)->setError($e_code)); }
protected function loadOAuthAccountData() { $uri = new PhutilURI('https://api.amazon.com/user/profile'); $uri->setQueryParam('access_token', $this->getAccessToken()); $future = new HTTPSFuture($uri); list($body) = $future->resolvex(); try { return phutil_json_decode($body); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Expected valid JSON response from Amazon account data request.'), $ex); } }
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; }
protected function loadOAuthAccountData() { $uri = new PhutilURI('https://api.amazon.com/user/profile'); $uri->setQueryParam('access_token', $this->getAccessToken()); $future = new HTTPSFuture($uri); list($body) = $future->resolvex(); $data = json_decode($body, true); if (!is_array($data)) { throw new Exception("Expected valid JSON response from Amazon account data request, " . "got: " . $body); } return $data; }
public static function getGitHubPath($uri) { $uri_object = new PhutilURI($uri); $domain = $uri_object->getDomain(); $domain = phutil_utf8_strtolower($domain); switch ($domain) { case 'github.com': case 'www.github.com': return $uri_object->getPath(); default: return null; } }
private function validateURI($raw_uri) { $uri = new PhutilURI($raw_uri); $protocol = $uri->getProtocol(); if (!strlen($protocol)) { throw new Exception(pht('Unable to identify the protocol for URI "%s". URIs must be ' . 'fully qualified and have an identifiable protocol.', $raw_uri)); } $protocol_key = 'uri.allowed-protocols'; $protocols = PhabricatorEnv::getEnvConfig($protocol_key); if (empty($protocols[$protocol])) { throw new Exception(pht('URI "%s" does not have an allowable protocol. Configure ' . 'protocols in `%s`. Allowed protocols are: %s.', $raw_uri, $protocol_key, implode(', ', array_keys($protocols)))); } }
public function handleRequest(AphrontRequest $request) { $show_prototypes = PhabricatorEnv::getEnvConfig('phabricator.show-prototypes'); if (!$show_prototypes) { throw new Exception(pht('Show prototypes is disabled. Set `phabricator.show-prototypes` to `true` to use the image proxy')); } $viewer = $request->getViewer(); $img_uri = $request->getStr('uri'); // Validate the URI before doing anything PhabricatorEnv::requireValidRemoteURIForLink($img_uri); $uri = new PhutilURI($img_uri); $proto = $uri->getProtocol(); if (!in_array($proto, array('http', 'https'))) { throw new Exception(pht('The provided image URI must be either http or https')); } // Check if we already have the specified image URI downloaded $cached_request = id(new PhabricatorFileExternalRequest())->loadOneWhere('uriIndex = %s', PhabricatorHash::digestForIndex($img_uri)); if ($cached_request) { return $this->getExternalResponse($cached_request); } $ttl = PhabricatorTime::getNow() + phutil_units('7 days in seconds'); $external_request = id(new PhabricatorFileExternalRequest())->setURI($img_uri)->setTTL($ttl); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); // Cache missed so we'll need to validate and download the image try { // Rate limit outbound fetches to make this mechanism less useful for // scanning networks and ports. PhabricatorSystemActionEngine::willTakeAction(array($viewer->getPHID()), new PhabricatorFilesOutboundRequestAction(), 1); $file = PhabricatorFile::newFromFileDownload($uri, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'canCDN' => true)); if (!$file->isViewableImage()) { $mime_type = $file->getMimeType(); $engine = new PhabricatorDestructionEngine(); $engine->destroyObject($file); $file = null; throw new Exception(pht('The URI "%s" does not correspond to a valid image file, got ' . 'a file with MIME type "%s". You must specify the URI of a ' . 'valid image file.', $uri, $mime_type)); } else { $file->save(); } $external_request->setIsSuccessful(true)->setFilePHID($file->getPHID())->save(); unset($unguarded); return $this->getExternalResponse($external_request); } catch (HTTPFutureHTTPResponseStatus $status) { $external_request->setIsSuccessful(false)->setResponseMessage($status->getMessage())->save(); return $this->getExternalResponse($external_request); } catch (Exception $ex) { // Not actually saving the request in this case $external_request->setResponseMessage($ex->getMessage()); return $this->getExternalResponse($external_request); } }
protected function loadOAuthAccountData() { $uri = new PhutilURI('https://api.github.com/user'); $uri->setQueryParam('access_token', $this->getAccessToken()); $future = new HTTPSFuture($uri); // NOTE: GitHub requires a User-Agent string. $future->addHeader('User-Agent', __CLASS__); list($body) = $future->resolvex(); try { return phutil_json_decode($body); } catch (PhutilJSONParserException $ex) { throw new PhutilProxyException(pht('Expected valid JSON response from GitHub account data request.'), $ex); } }
protected function loadOAuthAccountData() { $uri = new PhutilURI('https://api.github.com/user'); $uri->setQueryParam('access_token', $this->getAccessToken()); $future = new HTTPSFuture($uri); // NOTE: GitHub requires a User-Agent string. $future->addHeader('User-Agent', 'PhutilAuthAdapterOAuthGitHub'); list($body) = $future->resolvex(); $data = json_decode($body, true); if (!is_array($data)) { throw new Exception("Expected valid JSON response from GitHub account data request, " . "got: " . $body); } return $data; }
public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $file = id(new PhabricatorFileQuery())->setViewer($viewer)->withIDs(array($request->getURIData('id')))->executeOne(); if (!$file) { return new Aphront404Response(); } $monogram = $file->getMonogram(); $xdst = id(new PhabricatorTransformedFile())->loadAllWhere('transformedPHID = %s', $file->getPHID()); $dst_rows = array(); foreach ($xdst as $source) { $dst_rows[] = array($source->getTransform(), $viewer->renderHandle($source->getOriginalPHID())); } $dst_table = id(new AphrontTableView($dst_rows))->setHeaders(array(pht('Key'), pht('Source')))->setColumnClasses(array('', 'wide'))->setNoDataString(pht('This file was not created by transforming another file.')); $xsrc = id(new PhabricatorTransformedFile())->loadAllWhere('originalPHID = %s', $file->getPHID()); $xsrc = mpull($xsrc, 'getTransformedPHID', 'getTransform'); $src_rows = array(); $xforms = PhabricatorFileTransform::getAllTransforms(); foreach ($xforms as $xform) { $dst_phid = idx($xsrc, $xform->getTransformKey()); if ($xform->canApplyTransform($file)) { $can_apply = pht('Yes'); $view_href = $file->getURIForTransform($xform); $view_href = new PhutilURI($view_href); $view_href->setQueryParam('regenerate', 'true'); $view_text = pht('Regenerate'); $view_link = phutil_tag('a', array('class' => 'small grey button', 'href' => $view_href), $view_text); } else { $can_apply = phutil_tag('em', array(), pht('No')); $view_link = phutil_tag('em', array(), pht('None')); } if ($dst_phid) { $dst_link = $viewer->renderHandle($dst_phid); } else { $dst_link = phutil_tag('em', array(), pht('None')); } $src_rows[] = array($xform->getTransformName(), $xform->getTransformKey(), $can_apply, $dst_link, $view_link); } $src_table = id(new AphrontTableView($src_rows))->setHeaders(array(pht('Name'), pht('Key'), pht('Supported'), pht('Transform'), pht('View')))->setColumnClasses(array('wide', '', '', '', 'action')); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($monogram, '/' . $monogram); $crumbs->addTextCrumb(pht('Transforms')); $crumbs->setBorder(true); $dst_box = id(new PHUIObjectBoxView())->setHeaderText(pht('File Sources'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setTable($dst_table); $src_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Available Transforms'))->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setTable($src_table); $title = pht('%s Transforms', $file->getName()); $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-arrows-alt'); $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($dst_box, $src_box)); return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view); }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); $project_id = $request->getURIData('projectID'); $project = id(new PhabricatorProjectQuery())->setViewer($viewer)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withIDs(array($project_id))->executeOne(); if (!$project) { return new Aphront404Response(); } $this->setProject($project); $column = id(new PhabricatorProjectColumnQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$column) { return new Aphront404Response(); } $column_phid = $column->getPHID(); $view_uri = $this->getApplicationURI('/board/' . $project_id . '/'); $view_uri = new PhutilURI($view_uri); foreach ($request->getPassthroughRequestData() as $key => $value) { $view_uri->setQueryParam($key, $value); } if ($column->isDefaultColumn()) { return $this->newDialog()->setTitle(pht('Can Not Hide Default Column'))->appendParagraph(pht('You can not hide the default/backlog column on a board.'))->addCancelButton($view_uri, pht('Okay')); } if ($request->isFormPost()) { if ($column->isHidden()) { $new_status = PhabricatorProjectColumn::STATUS_ACTIVE; } else { $new_status = PhabricatorProjectColumn::STATUS_HIDDEN; } $type_status = PhabricatorProjectColumnTransaction::TYPE_STATUS; $xactions = array(id(new PhabricatorProjectColumnTransaction())->setTransactionType($type_status)->setNewValue($new_status)); $editor = id(new PhabricatorProjectColumnTransactionEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->applyTransactions($column, $xactions); return id(new AphrontRedirectResponse())->setURI($view_uri); } if ($column->isHidden()) { $title = pht('Show Column'); } else { $title = pht('Hide Column'); } if ($column->isHidden()) { $body = pht('Are you sure you want to show this column?'); } else { $body = pht('Are you sure you want to hide this column? It will no longer ' . 'appear on the workboard.'); } $dialog = $this->newDialog()->setWidth(AphrontDialogView::WIDTH_FORM)->setTitle($title)->appendChild($body)->setDisableWorkflowOnCancel(true)->addCancelButton($view_uri)->addSubmitButton($title); foreach ($request->getPassthroughRequestData() as $key => $value) { $dialog->addHiddenInput($key, $value); } return $dialog; }
private function getBareHostAndPort($host) { // Split out port information, since the command-line client requires a // separate flag for the port. $uri = new PhutilURI('mysql://' . $host); if ($uri->getPort()) { $port = $uri->getPort(); $bare_hostname = $uri->getDomain(); } else { $port = null; $bare_hostname = $host; } return array($bare_hostname, $port); }