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