[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/auth/controller/ -> PhabricatorAuthStartController.php (source)

   1  <?php
   2  
   3  final class PhabricatorAuthStartController
   4    extends PhabricatorAuthController {
   5  
   6    public function shouldRequireLogin() {
   7      return false;
   8    }
   9  
  10    public function processRequest() {
  11      $request = $this->getRequest();
  12      $viewer = $request->getUser();
  13  
  14      if ($viewer->isLoggedIn()) {
  15        // Kick the user home if they are already logged in.
  16        return id(new AphrontRedirectResponse())->setURI('/');
  17      }
  18  
  19      if ($request->isAjax()) {
  20        return $this->processAjaxRequest();
  21      }
  22  
  23      if ($request->isConduit()) {
  24        return $this->processConduitRequest();
  25      }
  26  
  27      // If the user gets this far, they aren't logged in, so if they have a
  28      // user session token we can conclude that it's invalid: if it was valid,
  29      // they'd have been logged in above and never made it here. Try to clear
  30      // it and warn the user they may need to nuke their cookies.
  31  
  32      $session_token = $request->getCookie(PhabricatorCookies::COOKIE_SESSION);
  33  
  34      if (strlen($session_token)) {
  35        $kind = PhabricatorAuthSessionEngine::getSessionKindFromToken(
  36          $session_token);
  37        switch ($kind) {
  38          case PhabricatorAuthSessionEngine::KIND_ANONYMOUS:
  39            // If this is an anonymous session. It's expected that they won't
  40            // be logged in, so we can just continue.
  41            break;
  42          default:
  43            // The session cookie is invalid, so clear it.
  44            $request->clearCookie(PhabricatorCookies::COOKIE_USERNAME);
  45            $request->clearCookie(PhabricatorCookies::COOKIE_SESSION);
  46  
  47            return $this->renderError(
  48              pht(
  49                'Your login session is invalid. Try reloading the page and '.
  50                'logging in again. If that does not work, clear your browser '.
  51                'cookies.'));
  52        }
  53      }
  54  
  55      $providers = PhabricatorAuthProvider::getAllEnabledProviders();
  56      foreach ($providers as $key => $provider) {
  57        if (!$provider->shouldAllowLogin()) {
  58          unset($providers[$key]);
  59        }
  60      }
  61  
  62      if (!$providers) {
  63        if ($this->isFirstTimeSetup()) {
  64          // If this is a fresh install, let the user register their admin
  65          // account.
  66          return id(new AphrontRedirectResponse())
  67            ->setURI($this->getApplicationURI('/register/'));
  68        }
  69  
  70        return $this->renderError(
  71          pht(
  72            'This Phabricator install is not configured with any enabled '.
  73            'authentication providers which can be used to log in. If you '.
  74            'have accidentally locked yourself out by disabling all providers, '.
  75            'you can use `phabricator/bin/auth recover <username>` to '.
  76            'recover access to an administrative account.'));
  77      }
  78  
  79      $next_uri = $request->getStr('next');
  80      if (!$next_uri) {
  81        $next_uri_path = $this->getRequest()->getPath();
  82        if ($next_uri_path == '/auth/start/') {
  83          $next_uri = '/';
  84        } else {
  85          $next_uri = $this->getRequest()->getRequestURI();
  86        }
  87      }
  88  
  89      if (!$request->isFormPost()) {
  90        PhabricatorCookies::setNextURICookie($request, $next_uri);
  91        PhabricatorCookies::setClientIDCookie($request);
  92      }
  93  
  94      $not_buttons = array();
  95      $are_buttons = array();
  96      $providers = msort($providers, 'getLoginOrder');
  97      foreach ($providers as $provider) {
  98        if ($provider->isLoginFormAButton()) {
  99          $are_buttons[] = $provider->buildLoginForm($this);
 100        } else {
 101          $not_buttons[] = $provider->buildLoginForm($this);
 102        }
 103      }
 104  
 105      $out = array();
 106      $out[] = $not_buttons;
 107      if ($are_buttons) {
 108        require_celerity_resource('auth-css');
 109  
 110        foreach ($are_buttons as $key => $button) {
 111          $are_buttons[$key] = phutil_tag(
 112            'div',
 113            array(
 114              'class' => 'phabricator-login-button mmb',
 115            ),
 116            $button);
 117        }
 118  
 119        // If we only have one button, add a second pretend button so that we
 120        // always have two columns. This makes it easier to get the alignments
 121        // looking reasonable.
 122        if (count($are_buttons) == 1) {
 123          $are_buttons[] = null;
 124        }
 125  
 126        $button_columns = id(new AphrontMultiColumnView())
 127          ->setFluidLayout(true);
 128        $are_buttons = array_chunk($are_buttons, ceil(count($are_buttons) / 2));
 129        foreach ($are_buttons as $column) {
 130          $button_columns->addColumn($column);
 131        }
 132  
 133        $out[] = phutil_tag(
 134          'div',
 135          array(
 136            'class' => 'phabricator-login-buttons',
 137          ),
 138          $button_columns);
 139      }
 140  
 141      $login_message = PhabricatorEnv::getEnvConfig('auth.login-message');
 142      $login_message = phutil_safe_html($login_message);
 143  
 144      $crumbs = $this->buildApplicationCrumbs();
 145      $crumbs->addTextCrumb(pht('Login'));
 146  
 147      return $this->buildApplicationPage(
 148        array(
 149          $crumbs,
 150          $login_message,
 151          $out,
 152        ),
 153        array(
 154          'title' => pht('Login to Phabricator'),
 155        ));
 156    }
 157  
 158  
 159    private function processAjaxRequest() {
 160      $request = $this->getRequest();
 161      $viewer = $request->getUser();
 162  
 163      // We end up here if the user clicks a workflow link that they need to
 164      // login to use. We give them a dialog saying "You need to login...".
 165  
 166      if ($request->isDialogFormPost()) {
 167        return id(new AphrontRedirectResponse())->setURI(
 168          $request->getRequestURI());
 169      }
 170  
 171      $dialog = new AphrontDialogView();
 172      $dialog->setUser($viewer);
 173      $dialog->setTitle(pht('Login Required'));
 174      $dialog->appendChild(pht('You must login to continue.'));
 175      $dialog->addSubmitButton(pht('Login'));
 176      $dialog->addCancelButton('/');
 177  
 178      return id(new AphrontDialogResponse())->setDialog($dialog);
 179    }
 180  
 181  
 182    private function processConduitRequest() {
 183      $request = $this->getRequest();
 184      $viewer = $request->getUser();
 185  
 186      // A common source of errors in Conduit client configuration is getting
 187      // the request path wrong. The client will end up here, so make some
 188      // effort to give them a comprehensible error message.
 189  
 190      $request_path = $this->getRequest()->getPath();
 191      $conduit_path = '/api/<method>';
 192      $example_path = '/api/conduit.ping';
 193  
 194      $message = pht(
 195        'ERROR: You are making a Conduit API request to "%s", but the correct '.
 196        'HTTP request path to use in order to access a COnduit method is "%s" '.
 197        '(for example, "%s"). Check your configuration.',
 198        $request_path,
 199        $conduit_path,
 200        $example_path);
 201  
 202      return id(new AphrontPlainTextResponse())->setContent($message);
 203    }
 204  
 205    protected function renderError($message) {
 206      return $this->renderErrorPage(
 207        pht('Authentication Failure'),
 208        array($message));
 209    }
 210  
 211  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1