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 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 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."); }
public function getBrowseURI() { if (!$this->isBrowsable()) { return null; } $uri = new PhutilURI('/typeahead/browse/' . get_class($this) . '/'); $uri->setQueryParams($this->parameters); return (string) $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; }
public function processRequest() { $request = $this->getRequest(); if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { return new Aphront400Response(); } $token = $this->token; $email = $request->getStr('email'); // NOTE: We need to bind verification to **addresses**, not **users**, // because we verify addresses when they're used to login this way, and if // we have a user-based verification you can: // // - Add some address you do not own; // - request a password reset; // - change the URI in the email to the address you don't own; // - login via the email link; and // - get a "verified" address you don't control. $target_email = id(new PhabricatorUserEmail())->loadOneWhere('address = %s', $email); $target_user = null; if ($target_email) { $target_user = id(new PhabricatorUser())->loadOneWhere('phid = %s', $target_email->getUserPHID()); } if (!$target_email || !$target_user || !$target_user->validateEmailToken($target_email, $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' => 'Login Failure')); } // Verify email so that clicking the link in the "Welcome" email is good // enough, without requiring users to go through a second round of email // verification. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $target_email->setIsVerified(1); $target_email->save(); $session_key = $target_user->establishSession('web'); unset($unguarded); $request->setCookie('phusr', $target_user->getUsername()); $request->setCookie('phsid', $session_key); if (PhabricatorEnv::getEnvConfig('account.editable')) { $next = (string) id(new PhutilURI('/settings/panel/password/'))->setQueryParams(array('token' => $token, 'email' => $email)); } else { $next = '/'; } $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams(array('phusr' => $target_user->getUsername(), 'next' => $next)); return id(new AphrontRedirectResponse())->setURI((string) $uri); }
protected function getProxiedFuture() { if (!$this->future) { $params = $this->params; if (!$this->params) { throw new Exception('You must setRawAWSQuery()!'); } if (!$this->getAWSAccessKey()) { throw new Exception('You must setAWSKeys()!'); } $params['AWSAccessKeyId'] = $this->getAWSAccessKey(); $params['Version'] = '2011-12-15'; $params['Timestamp'] = date('c'); $params = $this->sign($params); $uri = new PhutilURI('http://' . $this->getHost() . '/'); $uri->setQueryParams($params); $this->future = new HTTPFuture($uri); } return $this->future; }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $status = id(new PhabricatorCalendarEventQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$status) { return new Aphront404Response(); } if ($request->isFormPost()) { $status->delete(); $uri = new PhutilURI($this->getApplicationURI()); $uri->setQueryParams(array('deleted' => true)); return id(new AphrontRedirectResponse())->setURI($uri); } $dialog = new AphrontDialogView(); $dialog->setUser($user); $dialog->setTitle(pht('Really delete status?')); $dialog->appendChild(pht('Permanently delete this status? This action can not be undone.')); $dialog->addSubmitButton(pht('Delete')); $dialog->addCancelButton($this->getApplicationURI('event/')); return id(new AphrontDialogResponse())->setDialog($dialog); }
public function render() { require_celerity_resource('differential-changeset-view-css'); $changesets = $this->changesets; $output = array(); $mapping = array(); foreach ($changesets as $key => $changeset) { $file = $changeset->getFilename(); $class = 'differential-changeset'; if (!$this->editable) { $class .= ' differential-changeset-noneditable'; } $ref = $this->references[$key]; $detail_button = null; if ($this->standaloneViews) { $detail_uri = new PhutilURI($this->renderURI); $detail_uri->setQueryParams(array('ref' => $ref, 'whitespace' => $this->whitespace)); $detail_button = phutil_render_tag('a', array('class' => 'button small grey', 'href' => $detail_uri, 'target' => '_blank'), 'View Standalone / Raw'); } $uniq_id = celerity_generate_unique_node_id(); $detail = new DifferentialChangesetDetailView(); $detail->setChangeset($changeset); $detail->addButton($detail_button); $detail->appendChild(phutil_render_tag('div', array('id' => $uniq_id), '<div class="differential-loading">Loading...</div>')); $output[] = $detail->render(); $mapping[$uniq_id] = $ref; } Javelin::initBehavior('differential-populate', array('registry' => $mapping, 'whitespace' => $this->whitespace, 'uri' => $this->renderURI)); Javelin::initBehavior('differential-show-more', array('uri' => $this->renderURI, 'whitespace' => $this->whitespace)); Javelin::initBehavior('differential-comment-jump', array()); if ($this->editable) { $undo_templates = $this->renderUndoTemplates(); $revision = $this->revision; Javelin::initBehavior('differential-edit-inline-comments', array('uri' => '/differential/comment/inline/edit/' . $revision->getID() . '/', 'undo_templates' => $undo_templates)); } return '<div class="differential-review-stage" id="differential-review-stage">' . implode("\n", $output) . '</div>'; }
/** * Render a standard login/register button element. * * The `$attributes` parameter takes these keys: * * - `uri`: URI the button should take the user to when clicked. * - `method`: Optional HTTP method the button should use, defaults to GET. * * @param AphrontRequest HTTP request. * @param string Request mode string. * @param map Additional parameters, see above. * @return wild Login button. */ protected function renderStandardLoginButton(AphrontRequest $request, $mode, array $attributes = array()) { PhutilTypeSpec::checkMap($attributes, array('method' => 'optional string', 'uri' => 'string', 'sigil' => 'optional string')); $viewer = $request->getUser(); $adapter = $this->getAdapter(); if ($mode == 'link') { $button_text = pht('Link External Account'); } else { if ($mode == 'refresh') { $button_text = pht('Refresh Account Link'); } else { if ($mode == 'invite') { $button_text = pht('Register Account'); } else { if ($this->shouldAllowRegistration()) { $button_text = pht('Login or Register'); } else { $button_text = pht('Login'); } } } } $icon = id(new PHUIIconView())->setSpriteSheet(PHUIIconView::SPRITE_LOGIN)->setSpriteIcon($this->getLoginIcon()); $button = id(new PHUIButtonView())->setSize(PHUIButtonView::BIG)->setColor(PHUIButtonView::GREY)->setIcon($icon)->setText($button_text)->setSubtext($this->getProviderName()); $uri = $attributes['uri']; $uri = new PhutilURI($uri); $params = $uri->getQueryParams(); $uri->setQueryParams(array()); $content = array($button); foreach ($params as $key => $value) { $content[] = phutil_tag('input', array('type' => 'hidden', 'name' => $key, 'value' => $value)); } return phabricator_form($viewer, array('method' => idx($attributes, 'method', 'GET'), 'action' => (string) $uri, 'sigil' => idx($attributes, 'sigil')), $content); }
protected function renderResultList(array $events, PhabricatorSavedQuery $query, array $handles) { assert_instances_of($events, 'PhabricatorCalendarEvent'); $viewer = $this->requireViewer(); $list = new PHUIObjectItemListView(); foreach ($events as $event) { if ($event->getUserPHID() == $viewer->getPHID()) { $href = $this->getApplicationURI('/event/edit/' . $event->getID() . '/'); } else { $from = $event->getDateFrom(); $month = phabricator_format_local_time($from, $viewer, 'm'); $year = phabricator_format_local_time($from, $viewer, 'Y'); $uri = new PhutilURI($this->getApplicationURI()); $uri->setQueryParams(array('month' => $month, 'year' => $year)); $href = (string) $uri; } $from = phabricator_datetime($event->getDateFrom(), $viewer); $to = phabricator_datetime($event->getDateTo(), $viewer); $creator_handle = $handles[$event->getUserPHID()]; $color = $event->getStatus() == PhabricatorCalendarEvent::STATUS_AWAY ? 'red' : 'yellow'; $item = id(new PHUIObjectItemView())->setHeader($event->getTerseSummary($viewer))->setHref($href)->setBarColor($color)->addByline(pht('Creator: %s', $creator_handle->renderLink()))->addAttribute(pht('From %s to %s', $from, $to))->addAttribute(id(new PhutilUTF8StringTruncator())->setMaximumGlyphs(64)->truncateString($event->getDescription())); $list->addItem($item); } return $list; }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); $cart = id(new PhortuneCartQuery())->setViewer($viewer)->withIDs(array($id))->needPurchases(true)->executeOne(); if (!$cart) { return new Aphront404Response(); } $cancel_uri = $cart->getCancelURI(); $merchant = $cart->getMerchant(); switch ($cart->getStatus()) { case PhortuneCart::STATUS_BUILDING: return $this->newDialog()->setTitle(pht('Incomplete Cart'))->appendParagraph(pht('The application that created this cart did not finish putting ' . 'products in it. You can not checkout with an incomplete ' . 'cart.'))->addCancelButton($cancel_uri); case PhortuneCart::STATUS_READY: // This is the expected, normal state for a cart that's ready for // checkout. break; case PhortuneCart::STATUS_CHARGED: case PhortuneCart::STATUS_PURCHASING: case PhortuneCart::STATUS_HOLD: case PhortuneCart::STATUS_REVIEW: case PhortuneCart::STATUS_PURCHASED: // For these states, kick the user to the order page to give them // information and options. return id(new AphrontRedirectResponse())->setURI($cart->getDetailURI()); default: throw new Exception(pht('Unknown cart status "%s"!', $cart->getStatus())); } $account = $cart->getAccount(); $account_uri = $this->getApplicationURI($account->getID() . '/'); $methods = id(new PhortunePaymentMethodQuery())->setViewer($viewer)->withAccountPHIDs(array($account->getPHID()))->withMerchantPHIDs(array($merchant->getPHID()))->withStatuses(array(PhortunePaymentMethod::STATUS_ACTIVE))->execute(); $e_method = null; $errors = array(); if ($request->isFormPost()) { // Require CAN_EDIT on the cart to actually make purchases. PhabricatorPolicyFilter::requireCapability($viewer, $cart, PhabricatorPolicyCapability::CAN_EDIT); $method_id = $request->getInt('paymentMethodID'); $method = idx($methods, $method_id); if (!$method) { $e_method = pht('Required'); $errors[] = pht('You must choose a payment method.'); } if (!$errors) { $provider = $method->buildPaymentProvider(); $charge = $cart->willApplyCharge($viewer, $provider, $method); try { $provider->applyCharge($method, $charge); } catch (Exception $ex) { $cart->didFailCharge($charge); return $this->newDialog()->setTitle(pht('Charge Failed'))->appendParagraph(pht('Unable to make payment: %s', $ex->getMessage()))->addCancelButton($cart->getCheckoutURI(), pht('Continue')); } $cart->didApplyCharge($charge); $done_uri = $cart->getCheckoutURI(); return id(new AphrontRedirectResponse())->setURI($done_uri); } } $cart_table = $this->buildCartContentTable($cart); $cart_box = id(new PHUIObjectBoxView())->setFormErrors($errors)->setHeaderText(pht('Cart Contents'))->setTable($cart_table); $title = $cart->getName(); if (!$methods) { $method_control = id(new AphrontFormStaticControl())->setLabel(pht('Payment Method'))->setValue(phutil_tag('em', array(), pht('No payment methods configured.'))); } else { $method_control = id(new AphrontFormRadioButtonControl())->setLabel(pht('Payment Method'))->setName('paymentMethodID')->setValue($request->getInt('paymentMethodID')); foreach ($methods as $method) { $method_control->addButton($method->getID(), $method->getFullDisplayName(), $method->getDescription()); } } $method_control->setError($e_method); $account_id = $account->getID(); $payment_method_uri = $this->getApplicationURI("{$account_id}/card/new/"); $payment_method_uri = new PhutilURI($payment_method_uri); $payment_method_uri->setQueryParams(array('merchantID' => $merchant->getID(), 'cartID' => $cart->getID())); $form = id(new AphrontFormView())->setUser($viewer)->appendChild($method_control); $add_providers = $this->loadCreatePaymentMethodProvidersForMerchant($merchant); if ($add_providers) { $new_method = javelin_tag('a', array('class' => 'button grey', 'href' => $payment_method_uri), pht('Add New Payment Method')); $form->appendChild(id(new AphrontFormMarkupControl())->setValue($new_method)); } if ($methods || $add_providers) { $submit = id(new AphrontFormSubmitControl())->setValue(pht('Submit Payment'))->setDisabled(!$methods); if ($cart->getCancelURI() !== null) { $submit->addCancelButton($cart->getCancelURI()); } $form->appendChild($submit); } $provider_form = null; $pay_providers = $this->loadOneTimePaymentProvidersForMerchant($merchant); if ($pay_providers) { $one_time_options = array(); foreach ($pay_providers as $provider) { $one_time_options[] = $provider->renderOneTimePaymentButton($account, $cart, $viewer); } $one_time_options = phutil_tag('div', array('class' => 'phortune-payment-onetime-list'), $one_time_options); $provider_form = new PHUIFormLayoutView(); $provider_form->appendChild(id(new AphrontFormMarkupControl())->setLabel(pht('Pay With'))->setValue($one_time_options)); } $payment_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Choose Payment Method'))->appendChild($form)->appendChild($provider_form); $description_box = $this->renderCartDescription($cart); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('Checkout')); $crumbs->addTextCrumb($title); return $this->buildApplicationPage(array($crumbs, $cart_box, $description_box, $payment_box), array('title' => $title)); }
/** * Generate a Diffusion URI from a parameter map. Applies the correct encoding * and formatting to the URI. Parameters are: * * - `action` One of `history`, `browse`, `change`, `lastmodified`, * `branch`, `tags`, `branches`, or `revision-ref`. The action specified * by the URI. * - `repository` Repository. * - `callsign` Repository callsign. * - `branch` Optional if action is not `branch`, branch name. * - `path` Optional, path to file. * - `commit` Optional, commit identifier. * - `line` Optional, line range. * - `lint` Optional, lint code. * - `params` Optional, query parameters. * * The function generates the specified URI and returns it. * * @param map See documentation. * @return PhutilURI Generated URI. * @task uri */ public static function generateDiffusionURI(array $params) { $action = idx($params, 'action'); $repository = idx($params, 'repository'); if ($repository) { $callsign = $repository->getCallsign(); } else { $callsign = idx($params, 'callsign'); } $path = idx($params, 'path'); $branch = idx($params, 'branch'); $commit = idx($params, 'commit'); $line = idx($params, 'line'); if (strlen($callsign)) { $callsign = phutil_escape_uri_path_component($callsign) . '/'; } if (strlen($branch)) { $branch = phutil_escape_uri_path_component($branch) . '/'; } if (strlen($path)) { $path = ltrim($path, '/'); $path = str_replace(array(';', '$'), array(';;', '$$'), $path); $path = phutil_escape_uri($path); } $path = "{$branch}{$path}"; if (strlen($commit)) { $commit = str_replace('$', '$$', $commit); $commit = ';' . phutil_escape_uri($commit); } if (strlen($line)) { $line = '$' . phutil_escape_uri($line); } $req_callsign = false; $req_branch = false; $req_commit = false; switch ($action) { case 'history': case 'browse': case 'change': case 'lastmodified': case 'tags': case 'branches': case 'lint': case 'refs': $req_callsign = true; break; case 'branch': $req_callsign = true; $req_branch = true; break; case 'commit': $req_callsign = true; $req_commit = true; break; } if ($req_callsign && !strlen($callsign)) { throw new Exception(pht("Diffusion URI action '%s' requires callsign!", $action)); } if ($req_commit && !strlen($commit)) { throw new Exception(pht("Diffusion URI action '%s' requires commit!", $action)); } switch ($action) { case 'change': case 'history': case 'browse': case 'lastmodified': case 'tags': case 'branches': case 'lint': case 'pathtree': case 'refs': $uri = "/diffusion/{$callsign}{$action}/{$path}{$commit}{$line}"; break; case 'branch': if (strlen($path)) { $uri = "/diffusion/{$callsign}repository/{$path}"; } else { $uri = "/diffusion/{$callsign}"; } break; case 'external': $commit = ltrim($commit, ';'); $uri = "/diffusion/external/{$commit}/"; break; case 'rendering-ref': // This isn't a real URI per se, it's passed as a query parameter to // the ajax changeset stuff but then we parse it back out as though // it came from a URI. $uri = rawurldecode("{$path}{$commit}"); break; case 'commit': $commit = ltrim($commit, ';'); $callsign = rtrim($callsign, '/'); $uri = "/r{$callsign}{$commit}"; break; default: throw new Exception(pht("Unknown Diffusion URI action '%s'!", $action)); } if ($action == 'rendering-ref') { return $uri; } $uri = new PhutilURI($uri); if (isset($params['lint'])) { $params['params'] = idx($params, 'params', array()) + array('lint' => $params['lint']); } if (idx($params, 'params')) { $uri->setQueryParams($params['params']); } return $uri; }
public function newJIRAFuture($path, $method, $params = array()) { $uri = new PhutilURI($this->getJIRAURI($path)); if ($method == 'GET') { $uri->setQueryParams($params); $params = array(); } else { // For other types of requests, JIRA expects the request body to be // JSON encoded. $params = json_encode($params); } // JIRA returns a 415 error if we don't provide a Content-Type header. return $this->newOAuth1Future($uri, $params)->setMethod($method)->addHeader('Content-Type', 'application/json'); }
private function renderChangesetLink(DifferentialChangeset $changeset) { $display_file = $changeset->getDisplayFilename(); if ($this->standaloneViewLink) { $id = $changeset->getID(); $vs_id = idx($this->vsMap, $id); $ref = $vs_id ? $id . '/' . $vs_id : $id; $detail_uri = new PhutilURI($this->renderURI); $detail_uri->setQueryParams(array('ref' => $ref, 'whitespace' => $this->whitespace, 'revision_id' => $this->revisionID)); return phutil_render_tag('a', array('href' => $detail_uri, 'target' => '_blank'), phutil_escape_html($display_file)); } return phutil_render_tag('a', array('href' => '#' . $changeset->getAnchorName()), phutil_escape_html($display_file)); }
public function processRequest() { $current_user = $this->getRequest()->getUser(); $provider = $this->provider; if (!$provider->isProviderEnabled()) { return new Aphront400Response(); } $provider_name = $provider->getProviderName(); $provider_key = $provider->getProviderKey(); $request = $this->getRequest(); if ($request->getStr('error')) { $error_view = id(new PhabricatorOAuthFailureView())->setRequest($request); return $this->buildErrorResponse($error_view); } $error_response = $this->retrieveAccessToken($provider); if ($error_response) { return $error_response; } $userinfo_uri = new PhutilURI($provider->getUserInfoURI()); $userinfo_uri->setQueryParams(array('access_token' => $this->accessToken)); $user_json = @file_get_contents($userinfo_uri); $user_data = json_decode($user_json, true); $provider->setUserData($user_data); $provider->setAccessToken($this->accessToken); $user_id = $provider->retrieveUserID(); $provider_key = $provider->getProviderKey(); $oauth_info = $this->retrieveOAuthInfo($provider); if ($current_user->getPHID()) { if ($oauth_info->getID()) { if ($oauth_info->getUserID() != $current_user->getID()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('Already Linked to Another Account'); $dialog->appendChild('<p>The ' . $provider_name . ' account you just authorized ' . 'is already linked to another Phabricator account. Before you can ' . 'associate your ' . $provider_name . ' account with this Phabriactor ' . 'account, you must unlink it from the Phabricator account it is ' . 'currently linked to.</p>'); $dialog->addCancelButton('/settings/page/' . $provider_key . '/'); return id(new AphrontDialogResponse())->setDialog($dialog); } else { return id(new AphrontRedirectResponse())->setURI('/settings/page/' . $provider_key . '/'); } } $existing_oauth = id(new PhabricatorUserOAuthInfo())->loadOneWhere('userID = %d AND oauthProvider = %s', $current_user->getID(), $provider_key); if ($existing_oauth) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('Already Linked to an Account From This Provider'); $dialog->appendChild('<p>The account you are logged in with is already linked to a ' . $provider_name . ' account. Before you can link it to a different ' . $provider_name . ' account, you must unlink the old account.</p>'); $dialog->addCancelButton('/settings/page/' . $provider_key . '/'); return id(new AphrontDialogResponse())->setDialog($dialog); } if (!$request->isDialogFormPost()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('Link ' . $provider_name . ' Account'); $dialog->appendChild('<p>Link your ' . $provider_name . ' account to your Phabricator ' . 'account?</p>'); $dialog->addHiddenInput('token', $provider->getAccessToken()); $dialog->addHiddenInput('expires', $oauth_info->getTokenExpires()); $dialog->addHiddenInput('state', $this->oauthState); $dialog->addSubmitButton('Link Accounts'); $dialog->addCancelButton('/settings/page/' . $provider_key . '/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $oauth_info->setUserID($current_user->getID()); $this->saveOAuthInfo($oauth_info); return id(new AphrontRedirectResponse())->setURI('/settings/page/' . $provider_key . '/'); } $next_uri = $request->getCookie('next_uri', '/'); // Login with known auth. if ($oauth_info->getID()) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $known_user = id(new PhabricatorUser())->load($oauth_info->getUserID()); $request->getApplicationConfiguration()->willAuthenticateUserWithOAuth($known_user, $oauth_info, $provider); $session_key = $known_user->establishSession('web'); $this->saveOAuthInfo($oauth_info); $request->setCookie('phusr', $known_user->getUsername()); $request->setCookie('phsid', $session_key); $request->clearCookie('next_uri'); return id(new AphrontRedirectResponse())->setURI($next_uri); } $oauth_email = $provider->retrieveUserEmail(); if ($oauth_email) { $known_email = id(new PhabricatorUser())->loadOneWhere('email = %s', $oauth_email); if ($known_email) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('Already Linked to Another Account'); $dialog->appendChild('<p>The ' . $provider_name . ' account you just authorized has an ' . 'email address which is already in use by another Phabricator ' . 'account. To link the accounts, log in to your Phabricator ' . 'account and then go to Settings.</p>'); $dialog->addCancelButton('/login/'); return id(new AphrontDialogResponse())->setDialog($dialog); } } if (!$provider->isProviderRegistrationEnabled()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('No Account Registration With ' . $provider_name); $dialog->appendChild('<p>You can not register a new account using ' . $provider_name . '; ' . 'you can only use your ' . $provider_name . ' account to log into an ' . 'existing Phabricator account which you have registered through ' . 'other means.</p>'); $dialog->addCancelButton('/login/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $class = PhabricatorEnv::getEnvConfig('controller.oauth-registration'); PhutilSymbolLoader::loadClass($class); $controller = newv($class, array($this->getRequest())); $controller->setOAuthProvider($provider); $controller->setOAuthInfo($oauth_info); $controller->setOAuthState($this->oauthState); return $this->delegateToController($controller); }
private function renderViewOptionsDropdown(DifferentialChangesetDetailView $detail, $ref, DifferentialChangeset $changeset) { $meta = array(); $qparams = array('ref' => $ref, 'whitespace' => $this->whitespace); if ($this->standaloneURI) { $uri = new PhutilURI($this->standaloneURI); $uri->setQueryParams($uri->getQueryParams() + $qparams); $meta['standaloneURI'] = (string) $uri; } $repository = $this->repository; if ($repository) { try { $meta['diffusionURI'] = (string) $repository->getDiffusionBrowseURIForPath($this->user, $changeset->getAbsoluteRepositoryPath($repository, $this->diff), idx($changeset->getMetadata(), 'line:first'), $this->getBranch()); } catch (DiffusionSetupException $e) { // Ignore } } $change = $changeset->getChangeType(); if ($this->leftRawFileURI) { if ($change != DifferentialChangeType::TYPE_ADD) { $uri = new PhutilURI($this->leftRawFileURI); $uri->setQueryParams($uri->getQueryParams() + $qparams); $meta['leftURI'] = (string) $uri; } } if ($this->rightRawFileURI) { if ($change != DifferentialChangeType::TYPE_DELETE && $change != DifferentialChangeType::TYPE_MULTICOPY) { $uri = new PhutilURI($this->rightRawFileURI); $uri->setQueryParams($uri->getQueryParams() + $qparams); $meta['rightURI'] = (string) $uri; } } $user = $this->user; if ($user && $repository) { $path = ltrim($changeset->getAbsoluteRepositoryPath($repository, $this->diff), '/'); $line = idx($changeset->getMetadata(), 'line:first', 1); $callsign = $repository->getCallsign(); $editor_link = $user->loadEditorLink($path, $line, $callsign); if ($editor_link) { $meta['editor'] = $editor_link; } else { $meta['editorConfigure'] = '/settings/panel/display/'; } } $meta['containerID'] = $detail->getID(); $caret = phutil_tag('span', array('class' => 'caret'), ''); return javelin_tag('a', array('class' => 'button grey small dropdown', 'meta' => $meta, 'href' => idx($meta, 'detailURI', '#'), 'target' => '_blank', 'sigil' => 'differential-view-options'), array(pht('View Options'), $caret)); }
public function generateURI(array $params) { $req_branch = false; $req_commit = false; $action = idx($params, 'action'); switch ($action) { case 'history': case 'browse': case 'change': case 'lastmodified': case 'tags': case 'branches': case 'lint': case 'pathtree': case 'refs': break; case 'branch': // NOTE: This does not actually require a branch, and won't have one // in Subversion. Possibly this should be more clear. break; case 'commit': case 'rendering-ref': $req_commit = true; break; default: throw new Exception(pht('Action "%s" is not a valid repository URI action.', $action)); } $path = idx($params, 'path'); $branch = idx($params, 'branch'); $commit = idx($params, 'commit'); $line = idx($params, 'line'); if ($req_commit && !strlen($commit)) { throw new Exception(pht('Diffusion URI action "%s" requires commit!', $action)); } if ($req_branch && !strlen($branch)) { throw new Exception(pht('Diffusion URI action "%s" requires branch!', $action)); } if ($action === 'commit') { return $this->getCommitURI($commit); } $identifier = $this->getID(); $callsign = $this->getCallsign(); if ($callsign !== null) { $identifier = $callsign; } if (strlen($identifier)) { $identifier = phutil_escape_uri_path_component($identifier); } if (strlen($path)) { $path = ltrim($path, '/'); $path = str_replace(array(';', '$'), array(';;', '$$'), $path); $path = phutil_escape_uri($path); } if (strlen($branch)) { $branch = phutil_escape_uri_path_component($branch); $path = "{$branch}/{$path}"; } if (strlen($commit)) { $commit = str_replace('$', '$$', $commit); $commit = ';' . phutil_escape_uri($commit); } if (strlen($line)) { $line = '$' . phutil_escape_uri($line); } switch ($action) { case 'change': case 'history': case 'browse': case 'lastmodified': case 'tags': case 'branches': case 'lint': case 'pathtree': case 'refs': $uri = "/diffusion/{$identifier}/{$action}/{$path}{$commit}{$line}"; break; case 'branch': if (strlen($path)) { $uri = "/diffusion/{$identifier}/repository/{$path}"; } else { $uri = "/diffusion/{$identifier}/"; } break; case 'external': $commit = ltrim($commit, ';'); $uri = "/diffusion/external/{$commit}/"; break; case 'rendering-ref': // This isn't a real URI per se, it's passed as a query parameter to // the ajax changeset stuff but then we parse it back out as though // it came from a URI. $uri = rawurldecode("{$path}{$commit}"); break; } if ($action == 'rendering-ref') { return $uri; } $uri = new PhutilURI($uri); if (isset($params['lint'])) { $params['params'] = idx($params, 'params', array()) + array('lint' => $params['lint']); } if (idx($params, 'params')) { $uri->setQueryParams($params['params']); } return $uri; }
public function processRequest() { $provider = $this->provider; $auth_enabled = $provider->isProviderEnabled(); $client_id = $provider->getClientID(); $client_secret = $provider->getClientSecret(); $res_ok = '<strong style="color: #00aa00;">OK</strong>'; $res_no = '<strong style="color: #aa0000;">NO</strong>'; $res_na = '<strong style="color: #999999;">N/A</strong>'; $results = array(); if (!$auth_enabled) { $results['facebook.auth-enabled'] = array($res_no, 'false', 'Facebook authentication is disabled in the configuration. Edit the ' . 'environmental configuration to enable "facebook.auth-enabled".'); } else { $results['facebook.auth-enabled'] = array($res_ok, 'true', 'Facebook authentication is enabled.'); } if (!$client_id) { $results['facebook.application-id'] = array($res_no, null, 'No Facebook Application ID is configured. Edit the environmental ' . 'configuration to specify an application ID in ' . '"facebook.application-id". To generate an ID, sign into Facebook, ' . 'install the "Developer" application, and use it to create a new ' . 'Facebook application.'); } else { $results['facebook.application-id'] = array($res_ok, $client_id, 'Application ID is set.'); } if (!$client_secret) { $results['facebook.application-secret'] = array($res_no, null, 'No Facebook Application secret is configured. Edit the environmental ' . 'configuration to specify an Application Secret, in ' . '"facebook.application-secret". You can find the application secret ' . 'in the Facebook "Developer" application on Facebook.'); } else { $results['facebook.application-secret'] = array($res_ok, "It's a secret!", 'Application secret is set.'); } $timeout = stream_context_create(array('http' => array('ignore_errors' => true, 'timeout' => 5))); $timeout_strict = stream_context_create(array('http' => array('timeout' => 5))); $internet = @file_get_contents("http://google.com/", false, $timeout); if ($internet === false) { $results['internet'] = array($res_no, null, 'Unable to make an HTTP request to Google. Check your outbound ' . 'internet connection and firewall/filtering settings.'); } else { $results['internet'] = array($res_ok, null, 'Internet seems OK.'); } $facebook = @file_get_contents("http://facebook.com/", false, $timeout); if ($facebook === false) { $results['facebook.com'] = array($res_no, null, 'Unable to make an HTTP request to facebook.com. Facebook may be ' . 'down or inaccessible.'); } else { $results['facebook.com'] = array($res_ok, null, 'Made a request to facebook.com.'); } $graph = @file_get_contents("https://graph.facebook.com/me", false, $timeout); if ($graph === false) { $results['Facebook Graph'] = array($res_no, null, "Unable to make an HTTPS request to graph.facebook.com. " . "The Facebook graph may be down or inaccessible."); } else { $results['Facebook Graph'] = array($res_ok, null, 'Made a request to graph.facebook.com.'); } $test_uri = new PhutilURI('https://graph.facebook.com/oauth/access_token'); $test_uri->setQueryParams(array('client_id' => $client_id, 'client_secret' => $client_secret, 'grant_type' => 'client_credentials')); $token_value = @file_get_contents($test_uri, false, $timeout); $token_strict = @file_get_contents($test_uri, false, $timeout_strict); if ($token_value === false) { $results['App Login'] = array($res_no, null, "Unable to perform an application login with your Application ID and " . "Application Secret. You may have mistyped or misconfigured them; " . "Facebook may have revoked your authorization; or Facebook may be " . "having technical problems."); } else { if ($token_strict) { $results['App Login'] = array($res_ok, '(A Valid Token)', "Raw application login to Facebook works."); } else { $data = json_decode($token_value, true); if (!is_array($data)) { $results['App Login'] = array($res_no, $token_value, "Application Login failed but the graph server did not respond " . "with valid JSON error information. Facebook may be experiencing " . "technical problems."); } else { $results['App Login'] = array($res_no, null, "Application Login failed with error: " . $token_value); } } } return $this->renderResults($results); }
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')); }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $start_time = id(new AphrontFormDateControl())->setUser($user)->setName('start')->setLabel(pht('Start'))->setInitialTime(AphrontFormDateControl::TIME_START_OF_DAY); $end_time = id(new AphrontFormDateControl())->setUser($user)->setName('end')->setLabel(pht('End'))->setInitialTime(AphrontFormDateControl::TIME_END_OF_DAY); if ($this->isCreate()) { $status = new PhabricatorCalendarEvent(); $end_value = $end_time->readValueFromRequest($request); $start_value = $start_time->readValueFromRequest($request); $submit_label = pht('Create'); $filter = 'status/create/'; $page_title = pht('Create Event'); $redirect = 'created'; } else { $status = id(new PhabricatorCalendarEventQuery())->setViewer($user)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$status) { return new Aphront404Response(); } $end_time->setValue($status->getDateTo()); $start_time->setValue($status->getDateFrom()); $submit_label = pht('Update'); $filter = 'event/edit/' . $status->getID() . '/'; $page_title = pht('Update Event'); $redirect = 'updated'; } $errors = array(); if ($request->isFormPost()) { $type = $request->getInt('status'); $start_value = $start_time->readValueFromRequest($request); $end_value = $end_time->readValueFromRequest($request); $description = $request->getStr('description'); try { $status->setUserPHID($user->getPHID())->setStatus($type)->setDateFrom($start_value)->setDateTo($end_value)->setDescription($description)->save(); } catch (PhabricatorCalendarEventInvalidEpochException $e) { $errors[] = pht('Start must be before end.'); } if (!$errors) { $uri = new PhutilURI($this->getApplicationURI()); $uri->setQueryParams(array('month' => phabricator_format_local_time($status->getDateFrom(), $user, 'm'), 'year' => phabricator_format_local_time($status->getDateFrom(), $user, 'Y'), $redirect => true)); if ($request->isAjax()) { $response = id(new AphrontAjaxResponse())->setContent(array('redirect_uri' => $uri)); } else { $response = id(new AphrontRedirectResponse())->setURI($uri); } return $response; } } $error_view = null; if ($errors) { $error_view = id(new AphrontErrorView())->setTitle(pht('Status can not be set!'))->setErrors($errors); } $status_select = id(new AphrontFormSelectControl())->setLabel(pht('Status'))->setName('status')->setValue($status->getStatus())->setOptions($status->getStatusOptions()); $description = id(new AphrontFormTextAreaControl())->setLabel(pht('Description'))->setName('description')->setValue($status->getDescription()); if ($request->isAjax()) { $dialog = id(new AphrontDialogView())->setUser($user)->setTitle($page_title)->setWidth(AphrontDialogView::WIDTH_FORM); if ($this->isCreate()) { $dialog->setSubmitURI($this->getApplicationURI('event/create/')); } else { $dialog->setSubmitURI($this->getApplicationURI('event/edit/' . $status->getID() . '/')); } $form = new PHUIFormLayoutView(); if ($error_view) { $form->appendChild($error_view); } } else { $form = id(new AphrontFormView())->setUser($user); } $form->appendChild($status_select)->appendChild($start_time)->appendChild($end_time)->appendChild($description); if ($request->isAjax()) { $dialog->addSubmitButton($submit_label); $submit = $dialog; } else { $submit = id(new AphrontFormSubmitControl())->setValue($submit_label); } if ($this->isCreate()) { $submit->addCancelButton($this->getApplicationURI()); } else { $submit->addCancelButton($this->getApplicationURI('event/view/' . $status->getID() . '/')); } if ($request->isAjax()) { $dialog->appendChild($form); return id(new AphrontDialogResponse())->setDialog($dialog); } $form->appendChild($submit); $form_box = id(new PHUIObjectBoxView())->setHeaderText($page_title)->setFormErrors($errors)->setForm($form); $nav = $this->buildSideNavView($status); $nav->selectFilter($filter); $crumbs = $this->buildApplicationCrumbs()->addTextCrumb($page_title); $nav->appendChild(array($crumbs, $form_box)); return $this->buildApplicationPage($nav, array('title' => $page_title)); }
private function refreshProfileImage(PhabricatorUserOAuthInfo $oauth_info) { $user = $this->getRequest()->getUser(); $provider = $this->provider; $error = false; $userinfo_uri = new PhutilURI($provider->getUserInfoURI()); $token = $oauth_info->getToken(); try { $userinfo_uri->setQueryParams(array('access_token' => $token)); $user_data = @file_get_contents($userinfo_uri); $provider->setUserData($user_data); $provider->setAccessToken($token); $image = $provider->retrieveUserProfileImage(); if ($image) { $file = PhabricatorFile::newFromFileData($image, array('name' => $provider->getProviderKey() . '-profile.jpg', 'authorPHID' => $user->getPHID())); $user->setProfileImagePHID($file->getPHID()); $user->save(); } else { $error = 'Unable to retrieve image.'; } } catch (Exception $e) { $error = 'Unable to save image.'; } $notice = new AphrontErrorView(); if ($error) { $notice->setTitle('Error Refreshing Profile Picture')->setErrors(array($error)); } else { $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE)->setTitle('Successfully Refreshed Profile Picture'); } return $notice; }
public function processRequest() { $provider = $this->provider; $auth_enabled = $provider->isProviderEnabled(); $client_id = $provider->getClientID(); $client_secret = $provider->getClientSecret(); $key = $provider->getProviderKey(); $name = phutil_escape_html($provider->getProviderName()); $res_ok = '<strong style="color: #00aa00;">OK</strong>'; $res_no = '<strong style="color: #aa0000;">NO</strong>'; $res_na = '<strong style="color: #999999;">N/A</strong>'; $results = array(); $auth_key = $key . '.auth-enabled'; if (!$auth_enabled) { $results[$auth_key] = array($res_no, 'false', $name . ' authentication is disabled in the configuration. Edit the ' . 'Phabricator configuration to enable "' . $auth_key . '".'); } else { $results[$auth_key] = array($res_ok, 'true', $name . ' authentication is enabled.'); } $client_id_key = $key . '.application-id'; if (!$client_id) { $results[$client_id_key] = array($res_no, null, 'No ' . $name . ' Application ID is configured. Edit the Phabricator ' . 'configuration to specify an application ID in ' . '"' . $client_id_key . '". ' . $provider->renderGetClientIDHelp()); } else { $results[$client_id_key] = array($res_ok, $client_id, 'Application ID is set.'); } $client_secret_key = $key . '.application-secret'; if (!$client_secret) { $results[$client_secret_key] = array($res_no, null, 'No ' . $name . ' Application secret is configured. Edit the ' . 'Phabricator configuration to specify an Application Secret, in ' . '"' . $client_secret_key . '". ' . $provider->renderGetClientSecretHelp()); } else { $results[$client_secret_key] = array($res_ok, "It's a secret!", 'Application secret is set.'); } $timeout = stream_context_create(array('http' => array('ignore_errors' => true, 'timeout' => 5))); $timeout_strict = stream_context_create(array('http' => array('timeout' => 5))); $internet = @file_get_contents("http://google.com/", false, $timeout); if ($internet === false) { $results['internet'] = array($res_no, null, 'Unable to make an HTTP request to Google. Check your outbound ' . 'internet connection and firewall/filtering settings.'); } else { $results['internet'] = array($res_ok, null, 'Internet seems OK.'); } $test_uris = $provider->getTestURIs(); foreach ($test_uris as $uri) { $success = @file_get_contents($uri, false, $timeout); if ($success === false) { $results[$uri] = array($res_no, null, "Unable to make an HTTP request to {$uri}. {$name} may be " . 'down or inaccessible.'); } else { $results[$uri] = array($res_ok, null, 'Made a request to ' . $uri . '.'); } } $test_uri = new PhutilURI($provider->getTokenURI()); $test_uri->setQueryParams(array('client_id' => $client_id, 'client_secret' => $client_secret, 'grant_type' => 'client_credentials')); $token_value = @file_get_contents($test_uri, false, $timeout); $token_strict = @file_get_contents($test_uri, false, $timeout_strict); if ($token_value === false) { $results['App Login'] = array($res_no, null, "Unable to perform an application login with your Application ID and " . "Application Secret. You may have mistyped or misconfigured them; " . "{$name} may have revoked your authorization; or {$name} may be " . "having technical problems."); } else { if ($token_strict) { $results['App Login'] = array($res_ok, '(A Valid Token)', "Raw application login to {$name} works."); } else { $data = json_decode($token_value, true); if (!is_array($data)) { $results['App Login'] = array($res_no, $token_value, "Application Login failed but the provider did not respond " . "with valid JSON error information. {$name} may be experiencing " . "technical problems."); } else { $results['App Login'] = array($res_no, null, "Application Login failed with error: " . $token_value); } } } return $this->renderResults($results); }
private function renderViewOptionsDropdown(DifferentialChangesetDetailView $detail, $ref, DifferentialChangeset $changeset) { $meta = array(); $qparams = array('ref' => $ref, 'whitespace' => $this->whitespace); if ($this->standaloneURI) { $uri = new PhutilURI($this->standaloneURI); $uri->setQueryParams($uri->getQueryParams() + $qparams); $meta['standaloneURI'] = (string) $uri; } $repository = $this->repository; if ($repository) { $meta['diffusionURI'] = (string) $repository->getDiffusionBrowseURIForPath($changeset->getAbsoluteRepositoryPath($repository, $this->diff)); } $change = $changeset->getChangeType(); if ($this->leftRawFileURI) { if ($change != DifferentialChangeType::TYPE_ADD) { $uri = new PhutilURI($this->leftRawFileURI); $uri->setQueryParams($uri->getQueryParams() + $qparams); $meta['leftURI'] = (string) $uri; } } if ($this->rightRawFileURI) { if ($change != DifferentialChangeType::TYPE_DELETE && $change != DifferentialChangeType::TYPE_MULTICOPY) { $uri = new PhutilURI($this->rightRawFileURI); $uri->setQueryParams($uri->getQueryParams() + $qparams); $meta['rightURI'] = (string) $uri; } } $user = $this->user; if ($user && $repository) { $path = ltrim($changeset->getAbsoluteRepositoryPath($repository, $this->diff), '/'); $line = 1; // TODO: get first changed line $callsign = $repository->getCallsign(); $editor_link = $user->loadEditorLink($path, $line, $callsign); if ($editor_link) { $meta['editor'] = $editor_link; } else { $meta['editorConfigure'] = '/settings/page/preferences/'; } } $meta['containerID'] = $detail->getID(); Javelin::initBehavior('differential-dropdown-menus', array()); return javelin_render_tag('a', array('class' => 'button small grey', 'meta' => $meta, 'href' => idx($meta, 'detailURI', '#'), 'target' => '_blank', 'sigil' => 'differential-view-options'), "View Options ▼"); }
public function render() { require_celerity_resource('differential-core-view-css'); require_celerity_resource('differential-table-of-contents-css'); $rows = array(); $changesets = $this->changesets; foreach ($changesets as $changeset) { $file = $changeset->getFilename(); $display_file = $changeset->getDisplayFilename(); $type = $changeset->getChangeType(); $ftype = $changeset->getFileType(); if (DifferentialChangeType::isOldLocationChangeType($type)) { $link = phutil_escape_html($display_file); $away = $changeset->getAwayPaths(); if (count($away) > 1) { $meta = array(); if ($type == DifferentialChangeType::TYPE_MULTICOPY) { $meta[] = 'Deleted after being copied to multiple locations:'; } else { $meta[] = 'Copied to multiple locations:'; } foreach ($away as $path) { $meta[] = $path; } $meta = implode('<br />', $meta); } else { if ($type == DifferentialChangeType::TYPE_MOVE_AWAY) { $meta = 'Moved to ' . reset($away); } else { $meta = 'Copied to ' . reset($away); } } } else { if ($this->standaloneViewLink) { $id = $changeset->getID(); if ($id) { $vs_id = idx($this->vsMap, $id); } else { $vs_id = null; } $ref = $vs_id ? $id . '/' . $vs_id : $id; $detail_uri = new PhutilURI($this->renderURI); $detail_uri->setQueryParams(array('ref' => $ref, 'whitespace' => $this->whitespace, 'revision_id' => $this->revisionID)); $link = phutil_render_tag('a', array('href' => $detail_uri, 'target' => '_blank'), phutil_escape_html($display_file)); } else { $link = phutil_render_tag('a', array('href' => '#' . $changeset->getAnchorName()), phutil_escape_html($display_file)); } if ($type == DifferentialChangeType::TYPE_MOVE_HERE) { $meta = 'Moved from ' . phutil_escape_html($changeset->getOldFile()); } else { if ($type == DifferentialChangeType::TYPE_COPY_HERE) { $meta = 'Copied from ' . phutil_escape_html($changeset->getOldFile()); } else { $meta = null; } } } $line_count = $changeset->getAffectedLineCount(); if ($line_count == 0) { $lines = null; } else { if ($line_count == 1) { $lines = ' (1 line)'; } else { $lines = ' (' . $line_count . ' lines)'; } } $char = DifferentialChangeType::getSummaryCharacterForChangeType($type); $chartitle = DifferentialChangeType::getFullNameForChangeType($type); $desc = DifferentialChangeType::getShortNameForFileType($ftype); if ($desc) { $desc = '(' . $desc . ')'; } $pchar = $changeset->getOldProperties() === $changeset->getNewProperties() ? null : '<span title="Properties Changed">M</span>'; $rows[] = '<tr>' . '<td class="differential-toc-char" title=' . $chartitle . '>' . $char . '</td>' . '<td class="differential-toc-prop">' . $pchar . '</td>' . '<td class="differential-toc-ftype">' . $desc . '</td>' . '<td class="differential-toc-file">' . $link . $lines . '</td>' . '</tr>'; if ($meta) { $rows[] = '<tr>' . '<td colspan="3"></td>' . '<td class="differential-toc-meta">' . $meta . '</td>' . '</tr>'; } } return '<div class="differential-toc differential-panel">' . '<h1>Table of Contents</h1>' . '<table>' . implode("\n", $rows) . '</table>' . '</div>'; }
public function processControllerRequest(PhortuneProviderActionController $controller, AphrontRequest $request) { $viewer = $request->getUser(); $cart = $controller->loadCart($request->getInt('cartID')); if (!$cart) { return new Aphront404Response(); } $charge = $controller->loadActiveCharge($cart); switch ($controller->getAction()) { case 'checkout': if ($charge) { throw new Exception(pht('Cart is already charging!')); } break; case 'charge': case 'cancel': if (!$charge) { throw new Exception(pht('Cart is not charging yet!')); } break; } switch ($controller->getAction()) { case 'checkout': $return_uri = $this->getControllerURI('charge', array('cartID' => $cart->getID())); $cancel_uri = $this->getControllerURI('cancel', array('cartID' => $cart->getID())); $price = $cart->getTotalPriceAsCurrency(); $charge = $cart->willApplyCharge($viewer, $this); $params = array('PAYMENTREQUEST_0_AMT' => $price->formatBareValue(), 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(), 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale', 'PAYMENTREQUEST_0_CUSTOM' => $charge->getPHID(), 'PAYMENTREQUEST_0_DESC' => $cart->getName(), 'RETURNURL' => $return_uri, 'CANCELURL' => $cancel_uri, 'NOSHIPPING' => '1'); $result = $this->newPaypalAPICall()->setRawPayPalQuery('SetExpressCheckout', $params)->resolve(); $uri = new PhutilURI('https://www.sandbox.paypal.com/cgi-bin/webscr'); $uri->setQueryParams(array('cmd' => '_express-checkout', 'token' => $result['TOKEN'])); $cart->setMetadataValue('provider.checkoutURI', (string) $uri); $cart->save(); $charge->setMetadataValue('paypal.token', $result['TOKEN']); $charge->save(); return id(new AphrontRedirectResponse())->setIsExternal(true)->setURI($uri); case 'charge': if ($cart->getStatus() !== PhortuneCart::STATUS_PURCHASING) { return id(new AphrontRedirectResponse())->setURI($cart->getCheckoutURI()); } $token = $request->getStr('token'); $params = array('TOKEN' => $token); $result = $this->newPaypalAPICall()->setRawPayPalQuery('GetExpressCheckoutDetails', $params)->resolve(); if ($result['CUSTOM'] !== $charge->getPHID()) { throw new Exception(pht('Paypal checkout does not match Phortune charge!')); } if ($result['CHECKOUTSTATUS'] !== 'PaymentActionNotInitiated') { return $controller->newDialog()->setTitle(pht('Payment Already Processed'))->appendParagraph(pht('The payment response for this charge attempt has already ' . 'been processed.'))->addCancelButton($cart->getCheckoutURI(), pht('Continue')); } $price = $cart->getTotalPriceAsCurrency(); $params = array('TOKEN' => $token, 'PAYERID' => $result['PAYERID'], 'PAYMENTREQUEST_0_AMT' => $price->formatBareValue(), 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(), 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale'); $result = $this->newPaypalAPICall()->setRawPayPalQuery('DoExpressCheckoutPayment', $params)->resolve(); $transaction_id = $result['PAYMENTINFO_0_TRANSACTIONID']; $success = false; $hold = false; switch ($result['PAYMENTINFO_0_PAYMENTSTATUS']) { case 'Processed': case 'Completed': case 'Completed-Funds-Held': $success = true; break; case 'In-Progress': case 'Pending': // TODO: We can capture more information about this stuff. $hold = true; break; case 'Denied': case 'Expired': case 'Failed': case 'Partially-Refunded': case 'Canceled-Reversal': case 'None': case 'Refunded': case 'Reversed': case 'Voided': default: // These are all failure states. break; } $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $charge->setMetadataValue('paypal.transactionID', $transaction_id); $charge->save(); if ($success) { $cart->didApplyCharge($charge); $response = id(new AphrontRedirectResponse())->setURI($cart->getCheckoutURI()); } else { if ($hold) { $cart->didHoldCharge($charge); $response = $controller->newDialog()->setTitle(pht('Charge On Hold'))->appendParagraph(pht('Your charge is on hold, for reasons?'))->addCancelButton($cart->getCheckoutURI(), pht('Continue')); } else { $cart->didFailCharge($charge); $response = $controller->newDialog()->setTitle(pht('Charge Failed'))->addCancelButton($cart->getCheckoutURI(), pht('Continue')); } } unset($unguarded); return $response; case 'cancel': if ($cart->getStatus() === PhortuneCart::STATUS_PURCHASING) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); // TODO: Since the user cancelled this, we could conceivably just // throw it away or make it more clear that it's a user cancel. $cart->didFailCharge($charge); unset($unguarded); } return id(new AphrontRedirectResponse())->setURI($cart->getCheckoutURI()); } throw new Exception(pht('Unsupported action "%s".', $controller->getAction())); }
/** * 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; }
public function processRequest() { if (!$this->provider->isProviderEnabled()) { return new Aphront400Response(); } $current_user = $this->getRequest()->getUser(); $request = $this->getRequest(); $ldap_username = $request->getCookie('phusr'); if ($request->isFormPost()) { $ldap_username = $request->getStr('username'); try { $envelope = new PhutilOpaqueEnvelope($request->getStr('password')); $this->provider->auth($ldap_username, $envelope); } catch (Exception $e) { $errors[] = $e->getMessage(); } if (empty($errors)) { $ldap_info = $this->retrieveLDAPInfo($this->provider); if ($current_user->getPHID()) { if ($ldap_info->getID()) { $existing_ldap = id(new PhabricatorUserLDAPInfo())->loadOneWhere('userID = %d', $current_user->getID()); if ($ldap_info->getUserID() != $current_user->getID() || $existing_ldap) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('Already Linked to Another Account'); $dialog->appendChild('<p>The LDAP account you just authorized is already linked to ' . 'another Phabricator account. Before you can link it to a ' . 'different LDAP account, you must unlink the old account.</p>'); $dialog->addCancelButton('/settings/page/ldap/'); return id(new AphrontDialogResponse())->setDialog($dialog); } else { return id(new AphrontRedirectResponse())->setURI('/settings/page/ldap/'); } } if (!$request->isDialogFormPost()) { $dialog = new AphrontDialogView(); $dialog->setUser($current_user); $dialog->setTitle('Link LDAP Account'); $dialog->appendChild('<p>Link your LDAP account to your Phabricator account?</p>'); $dialog->addHiddenInput('username', $request->getStr('username')); $dialog->addHiddenInput('password', $request->getStr('password')); $dialog->addSubmitButton('Link Accounts'); $dialog->addCancelButton('/settings/page/ldap/'); return id(new AphrontDialogResponse())->setDialog($dialog); } $ldap_info->setUserID($current_user->getID()); $this->saveLDAPInfo($ldap_info); return id(new AphrontRedirectResponse())->setURI('/settings/page/ldap/'); } if ($ldap_info->getID()) { $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $known_user = id(new PhabricatorUser())->load($ldap_info->getUserID()); $session_key = $known_user->establishSession('web'); $this->saveLDAPInfo($ldap_info); $request->setCookie('phusr', $known_user->getUsername()); $request->setCookie('phsid', $session_key); $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams(array('phusr' => $known_user->getUsername())); return id(new AphrontRedirectResponse())->setURI((string) $uri); } $controller = newv('PhabricatorLDAPRegistrationController', array($this->getRequest())); $controller->setLDAPProvider($this->provider); $controller->setLDAPInfo($ldap_info); return $this->delegateToController($controller); } } $ldap_form = new AphrontFormView(); $ldap_form->setUser($request->getUser())->setAction('/ldap/login/')->appendChild(id(new AphrontFormTextControl())->setLabel('LDAP username')->setName('username')->setValue($ldap_username))->appendChild(id(new AphrontFormPasswordControl())->setLabel('Password')->setName('password')); $ldap_form->appendChild(id(new AphrontFormSubmitControl())->setValue('Login')); $panel = new AphrontPanelView(); $panel->setWidth(AphrontPanelView::WIDTH_FORM); $panel->appendChild('<h1>LDAP login</h1>'); $panel->appendChild($ldap_form); if (isset($errors) && count($errors) > 0) { $error_view = new AphrontErrorView(); $error_view->setTitle('Login Failed'); $error_view->setErrors($errors); } return $this->buildStandardPageResponse(array(isset($error_view) ? $error_view : null, $panel), array('title' => 'Login')); }
public final function getControllerURI($action, array $params = array(), $local = false) { $id = $this->getProviderConfig()->getID(); $app = PhabricatorApplication::getByClass('PhabricatorPhortuneApplication'); $path = $app->getBaseURI() . 'provider/' . $id . '/' . $action . '/'; $uri = new PhutilURI($path); $uri->setQueryParams($params); if ($local) { return $uri; } else { return PhabricatorEnv::getURI((string) $uri); } }
public function render() { require_celerity_resource('differential-changeset-view-css'); $changesets = $this->changesets; if ($this->standaloneViews) { Javelin::initBehavior('differential-dropdown-menus', array()); } $output = array(); $mapping = array(); $repository = $this->repository; foreach ($changesets as $key => $changeset) { $file = $changeset->getFilename(); $class = 'differential-changeset'; if (!$this->editable) { $class .= ' differential-changeset-noneditable'; } $ref = $this->references[$key]; $detail = new DifferentialChangesetDetailView(); $detail_button = null; if ($this->standaloneViews) { $detail_uri = new PhutilURI($this->renderURI); $detail_uri->setQueryParams(array('ref' => $ref, 'whitespace' => $this->whitespace)); $diffusion_uri = null; if ($repository) { $diffusion_uri = $repository->getDiffusionBrowseURIForPath($changeset->getAbsoluteRepositoryPath($this->diff, $repository)); } $detail_button = javelin_render_tag('a', array('class' => 'button small grey', 'meta' => array('detailURI' => (string) $detail_uri, 'leftURI' => (string) $detail_uri->alter('view', 'old'), 'rightURI' => (string) $detail_uri->alter('view', 'new'), 'diffusionURI' => $diffusion_uri, 'containerID' => $detail->getID()), 'href' => $detail_uri, 'target' => '_blank', 'sigil' => 'differential-view-options'), "View Options ▼"); } $detail->setChangeset($changeset); $detail->addButton($detail_button); $detail->setSymbolIndex(idx($this->symbolIndexes, $key)); $uniq_id = celerity_generate_unique_node_id(); $detail->appendChild(phutil_render_tag('div', array('id' => $uniq_id), '<div class="differential-loading">Loading...</div>')); $output[] = $detail->render(); $mapping[$uniq_id] = $ref; } Javelin::initBehavior('differential-populate', array('registry' => $mapping, 'whitespace' => $this->whitespace, 'uri' => $this->renderURI)); Javelin::initBehavior('differential-show-more', array('uri' => $this->renderURI, 'whitespace' => $this->whitespace)); Javelin::initBehavior('differential-comment-jump', array()); if ($this->editable) { $undo_templates = $this->renderUndoTemplates(); $revision = $this->revision; Javelin::initBehavior('differential-edit-inline-comments', array('uri' => '/differential/comment/inline/edit/' . $revision->getID() . '/', 'undo_templates' => $undo_templates)); } return '<div class="differential-review-stage" id="differential-review-stage">' . implode("\n", $output) . '</div>'; }