@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PhabricatorEnv 'infratructure' -> 'infrastructure' (rofl) Recaptcha Email Login / Forgot Password Password Reset

+1418 -104
+1
.gitignore
··· 2 2 ._* 3 3 /docs/ 4 4 /src/.phutil_module_cache 5 + /conf/custom/*
+46
conf/default.conf.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + return array( 20 + 21 + // The root URI which Phabricator is installed on. 22 + // Example: "http://phabricator.example.com/" 23 + 'phabricator.base-uri' => null, 24 + 25 + 26 + // 27 + 'phabricator.csrf-key' => '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3', 28 + 29 + 30 + // -- Facebook --------------------------------------------------------------- 31 + 32 + // Can users use Facebook credentials to login to Phabricator? 33 + 'facebook.auth-enabled' => false, 34 + 35 + // The Facebook "Application ID" to use for Facebook API access. 36 + 'facebook.application-id' => null, 37 + 38 + // The Facebook "Application Secret" to use for Facebook API access. 39 + 'facebook.application-secret' => null, 40 + 41 + 'recaptcha.public-key' => null, 42 + 'recaptcha.private-key' => null, 43 + 44 + 45 + 46 + );
+22
conf/development.conf.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + return array( 20 + 21 + 22 + ) + phabricator_read_config_file('default');
+23
conf/production.conf.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + return array( 20 + 21 + 22 + ) + phabricator_read_config_file('default'); 23 +
+22
externals/recaptcha/LICENSE
··· 1 + Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net 2 + AUTHORS: 3 + Mike Crawford 4 + Ben Maurer 5 + 6 + Permission is hereby granted, free of charge, to any person obtaining a copy 7 + of this software and associated documentation files (the "Software"), to deal 8 + in the Software without restriction, including without limitation the rights 9 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 + copies of the Software, and to permit persons to whom the Software is 11 + furnished to do so, subject to the following conditions: 12 + 13 + The above copyright notice and this permission notice shall be included in 14 + all copies or substantial portions of the Software. 15 + 16 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 + THE SOFTWARE.
+277
externals/recaptcha/recaptchalib.php
··· 1 + <?php 2 + /* 3 + * This is a PHP library that handles calling reCAPTCHA. 4 + * - Documentation and latest version 5 + * http://recaptcha.net/plugins/php/ 6 + * - Get a reCAPTCHA API Key 7 + * https://www.google.com/recaptcha/admin/create 8 + * - Discussion group 9 + * http://groups.google.com/group/recaptcha 10 + * 11 + * Copyright (c) 2007 reCAPTCHA -- http://recaptcha.net 12 + * AUTHORS: 13 + * Mike Crawford 14 + * Ben Maurer 15 + * 16 + * Permission is hereby granted, free of charge, to any person obtaining a copy 17 + * of this software and associated documentation files (the "Software"), to deal 18 + * in the Software without restriction, including without limitation the rights 19 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 20 + * copies of the Software, and to permit persons to whom the Software is 21 + * furnished to do so, subject to the following conditions: 22 + * 23 + * The above copyright notice and this permission notice shall be included in 24 + * all copies or substantial portions of the Software. 25 + * 26 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 29 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 31 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 32 + * THE SOFTWARE. 33 + */ 34 + 35 + /** 36 + * The reCAPTCHA server URL's 37 + */ 38 + define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api"); 39 + define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api"); 40 + define("RECAPTCHA_VERIFY_SERVER", "www.google.com"); 41 + 42 + /** 43 + * Encodes the given data into a query string format 44 + * @param $data - array of string elements to be encoded 45 + * @return string - encoded request 46 + */ 47 + function _recaptcha_qsencode ($data) { 48 + $req = ""; 49 + foreach ( $data as $key => $value ) 50 + $req .= $key . '=' . urlencode( stripslashes($value) ) . '&'; 51 + 52 + // Cut the last '&' 53 + $req=substr($req,0,strlen($req)-1); 54 + return $req; 55 + } 56 + 57 + 58 + 59 + /** 60 + * Submits an HTTP POST to a reCAPTCHA server 61 + * @param string $host 62 + * @param string $path 63 + * @param array $data 64 + * @param int port 65 + * @return array response 66 + */ 67 + function _recaptcha_http_post($host, $path, $data, $port = 80) { 68 + 69 + $req = _recaptcha_qsencode ($data); 70 + 71 + $http_request = "POST $path HTTP/1.0\r\n"; 72 + $http_request .= "Host: $host\r\n"; 73 + $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n"; 74 + $http_request .= "Content-Length: " . strlen($req) . "\r\n"; 75 + $http_request .= "User-Agent: reCAPTCHA/PHP\r\n"; 76 + $http_request .= "\r\n"; 77 + $http_request .= $req; 78 + 79 + $response = ''; 80 + if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) { 81 + die ('Could not open socket'); 82 + } 83 + 84 + fwrite($fs, $http_request); 85 + 86 + while ( !feof($fs) ) 87 + $response .= fgets($fs, 1160); // One TCP-IP packet 88 + fclose($fs); 89 + $response = explode("\r\n\r\n", $response, 2); 90 + 91 + return $response; 92 + } 93 + 94 + 95 + 96 + /** 97 + * Gets the challenge HTML (javascript and non-javascript version). 98 + * This is called from the browser, and the resulting reCAPTCHA HTML widget 99 + * is embedded within the HTML form it was called from. 100 + * @param string $pubkey A public key for reCAPTCHA 101 + * @param string $error The error given by reCAPTCHA (optional, default is null) 102 + * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false) 103 + 104 + * @return string - The HTML to be embedded in the user's form. 105 + */ 106 + function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) 107 + { 108 + if ($pubkey == null || $pubkey == '') { 109 + die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"); 110 + } 111 + 112 + if ($use_ssl) { 113 + $server = RECAPTCHA_API_SECURE_SERVER; 114 + } else { 115 + $server = RECAPTCHA_API_SERVER; 116 + } 117 + 118 + $errorpart = ""; 119 + if ($error) { 120 + $errorpart = "&amp;error=" . $error; 121 + } 122 + return '<script type="text/javascript" src="'. $server . '/challenge?k=' . $pubkey . $errorpart . '"></script> 123 + 124 + <noscript> 125 + <iframe src="'. $server . '/noscript?k=' . $pubkey . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/> 126 + <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea> 127 + <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/> 128 + </noscript>'; 129 + } 130 + 131 + 132 + 133 + 134 + /** 135 + * A ReCaptchaResponse is returned from recaptcha_check_answer() 136 + */ 137 + class ReCaptchaResponse { 138 + var $is_valid; 139 + var $error; 140 + } 141 + 142 + 143 + /** 144 + * Calls an HTTP POST function to verify if the user's guess was correct 145 + * @param string $privkey 146 + * @param string $remoteip 147 + * @param string $challenge 148 + * @param string $response 149 + * @param array $extra_params an array of extra variables to post to the server 150 + * @return ReCaptchaResponse 151 + */ 152 + function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $extra_params = array()) 153 + { 154 + if ($privkey == null || $privkey == '') { 155 + die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>"); 156 + } 157 + 158 + if ($remoteip == null || $remoteip == '') { 159 + die ("For security reasons, you must pass the remote ip to reCAPTCHA"); 160 + } 161 + 162 + 163 + 164 + //discard spam submissions 165 + if ($challenge == null || strlen($challenge) == 0 || $response == null || strlen($response) == 0) { 166 + $recaptcha_response = new ReCaptchaResponse(); 167 + $recaptcha_response->is_valid = false; 168 + $recaptcha_response->error = 'incorrect-captcha-sol'; 169 + return $recaptcha_response; 170 + } 171 + 172 + $response = _recaptcha_http_post (RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", 173 + array ( 174 + 'privatekey' => $privkey, 175 + 'remoteip' => $remoteip, 176 + 'challenge' => $challenge, 177 + 'response' => $response 178 + ) + $extra_params 179 + ); 180 + 181 + $answers = explode ("\n", $response [1]); 182 + $recaptcha_response = new ReCaptchaResponse(); 183 + 184 + if (trim ($answers [0]) == 'true') { 185 + $recaptcha_response->is_valid = true; 186 + } 187 + else { 188 + $recaptcha_response->is_valid = false; 189 + $recaptcha_response->error = $answers [1]; 190 + } 191 + return $recaptcha_response; 192 + 193 + } 194 + 195 + /** 196 + * gets a URL where the user can sign up for reCAPTCHA. If your application 197 + * has a configuration page where you enter a key, you should provide a link 198 + * using this function. 199 + * @param string $domain The domain where the page is hosted 200 + * @param string $appname The name of your application 201 + */ 202 + function recaptcha_get_signup_url ($domain = null, $appname = null) { 203 + return "https://www.google.com/recaptcha/admin/create?" . _recaptcha_qsencode (array ('domains' => $domain, 'app' => $appname)); 204 + } 205 + 206 + function _recaptcha_aes_pad($val) { 207 + $block_size = 16; 208 + $numpad = $block_size - (strlen ($val) % $block_size); 209 + return str_pad($val, strlen ($val) + $numpad, chr($numpad)); 210 + } 211 + 212 + /* Mailhide related code */ 213 + 214 + function _recaptcha_aes_encrypt($val,$ky) { 215 + if (! function_exists ("mcrypt_encrypt")) { 216 + die ("To use reCAPTCHA Mailhide, you need to have the mcrypt php module installed."); 217 + } 218 + $mode=MCRYPT_MODE_CBC; 219 + $enc=MCRYPT_RIJNDAEL_128; 220 + $val=_recaptcha_aes_pad($val); 221 + return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); 222 + } 223 + 224 + 225 + function _recaptcha_mailhide_urlbase64 ($x) { 226 + return strtr(base64_encode ($x), '+/', '-_'); 227 + } 228 + 229 + /* gets the reCAPTCHA Mailhide url for a given email, public key and private key */ 230 + function recaptcha_mailhide_url($pubkey, $privkey, $email) { 231 + if ($pubkey == '' || $pubkey == null || $privkey == "" || $privkey == null) { 232 + die ("To use reCAPTCHA Mailhide, you have to sign up for a public and private key, " . 233 + "you can do so at <a href='http://www.google.com/recaptcha/mailhide/apikey'>http://www.google.com/recaptcha/mailhide/apikey</a>"); 234 + } 235 + 236 + 237 + $ky = pack('H*', $privkey); 238 + $cryptmail = _recaptcha_aes_encrypt ($email, $ky); 239 + 240 + return "http://www.google.com/recaptcha/mailhide/d?k=" . $pubkey . "&c=" . _recaptcha_mailhide_urlbase64 ($cryptmail); 241 + } 242 + 243 + /** 244 + * gets the parts of the email to expose to the user. 245 + * eg, given johndoe@example,com return ["john", "example.com"]. 246 + * the email is then displayed as john...@example.com 247 + */ 248 + function _recaptcha_mailhide_email_parts ($email) { 249 + $arr = preg_split("/@/", $email ); 250 + 251 + if (strlen ($arr[0]) <= 4) { 252 + $arr[0] = substr ($arr[0], 0, 1); 253 + } else if (strlen ($arr[0]) <= 6) { 254 + $arr[0] = substr ($arr[0], 0, 3); 255 + } else { 256 + $arr[0] = substr ($arr[0], 0, 4); 257 + } 258 + return $arr; 259 + } 260 + 261 + /** 262 + * Gets html to display an email address given a public an private key. 263 + * to get a key, go to: 264 + * 265 + * http://www.google.com/recaptcha/mailhide/apikey 266 + */ 267 + function recaptcha_mailhide_html($pubkey, $privkey, $email) { 268 + $emailparts = _recaptcha_mailhide_email_parts ($email); 269 + $url = recaptcha_mailhide_url ($pubkey, $privkey, $email); 270 + 271 + return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) . 272 + "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]); 273 + 274 + } 275 + 276 + 277 + ?>
+22 -11
src/__phutil_library_map__.php
··· 25 25 'AphrontFormControl' => 'view/form/control/base', 26 26 'AphrontFormFileControl' => 'view/form/control/file', 27 27 'AphrontFormMarkupControl' => 'view/form/control/markup', 28 + 'AphrontFormPasswordControl' => 'view/form/control/password', 29 + 'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha', 28 30 'AphrontFormSelectControl' => 'view/form/control/select', 29 31 'AphrontFormStaticControl' => 'view/form/control/static', 30 32 'AphrontFormSubmitControl' => 'view/form/control/submit', ··· 54 56 'AphrontURIMapper' => 'aphront/mapper', 55 57 'AphrontView' => 'view/base', 56 58 'AphrontWebpageResponse' => 'aphront/response/webpage', 57 - 'CelerityAPI' => 'infratructure/celerity/api', 58 - 'CelerityResourceController' => 'infratructure/celerity/controller', 59 - 'CelerityResourceMap' => 'infratructure/celerity/map', 60 - 'CelerityStaticResourceResponse' => 'infratructure/celerity/response', 59 + 'CelerityAPI' => 'infrastructure/celerity/api', 60 + 'CelerityResourceController' => 'infrastructure/celerity/controller', 61 + 'CelerityResourceMap' => 'infrastructure/celerity/map', 62 + 'CelerityStaticResourceResponse' => 'infrastructure/celerity/response', 61 63 'ConduitAPIMethod' => 'applications/conduit/method/base', 62 64 'ConduitAPIRequest' => 'applications/conduit/protocol/request', 63 65 'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/conduit/connect', ··· 105 107 'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/revisionupdatehistory', 106 108 'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview', 107 109 'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus', 108 - 'Javelin' => 'infratructure/javelin/api', 110 + 'Javelin' => 'infrastructure/javelin/api', 109 111 'LiskDAO' => 'storage/lisk/dao', 110 112 'Phabricator404Controller' => 'applications/base/controller/404', 111 113 'PhabricatorAuthController' => 'applications/auth/controller/base', ··· 128 130 'PhabricatorDirectoryItemEditController' => 'applications/directory/controller/itemedit', 129 131 'PhabricatorDirectoryItemListController' => 'applications/directory/controller/itemlist', 130 132 'PhabricatorDirectoryMainController' => 'applications/directory/controller/main', 131 - 'PhabricatorFacebookConnectController' => 'applications/auth/controller/facebookconnect', 133 + 'PhabricatorEmailLoginController' => 'applications/auth/controller/email', 134 + 'PhabricatorEmailTokenController' => 'applications/auth/controller/emailtoken', 135 + 'PhabricatorEnv' => 'infrastructure/env', 136 + 'PhabricatorFacebookAuthController' => 'applications/auth/controller/facebookauth', 137 + 'PhabricatorFacebookAuthDiagnosticsController' => 'applications/auth/controller/facebookauth/diagnostics', 132 138 'PhabricatorFile' => 'applications/files/storage/file', 133 139 'PhabricatorFileController' => 'applications/files/controller/base', 134 140 'PhabricatorFileDAO' => 'applications/files/storage/base', ··· 176 182 array( 177 183 '_qsprintf_check_scalar_type' => 'storage/qsprintf', 178 184 '_qsprintf_check_type' => 'storage/qsprintf', 179 - 'celerity_generate_unique_node_id' => 'infratructure/celerity/api', 180 - 'celerity_register_resource_map' => 'infratructure/celerity/map', 181 - 'javelin_render_tag' => 'infratructure/javelin/markup', 185 + 'celerity_generate_unique_node_id' => 'infrastructure/celerity/api', 186 + 'celerity_register_resource_map' => 'infrastructure/celerity/map', 187 + 'javelin_render_tag' => 'infrastructure/javelin/markup', 182 188 'phabricator_format_relative_time' => 'view/utils', 183 189 'phabricator_format_timestamp' => 'view/utils', 184 190 'phabricator_format_units_generic' => 'view/utils', ··· 186 192 'queryfx' => 'storage/queryfx', 187 193 'queryfx_all' => 'storage/queryfx', 188 194 'queryfx_one' => 'storage/queryfx', 189 - 'require_celerity_resource' => 'infratructure/celerity/api', 195 + 'require_celerity_resource' => 'infrastructure/celerity/api', 190 196 'vqsprintf' => 'storage/qsprintf', 191 197 'vqueryfx' => 'storage/queryfx', 192 198 'vqueryfx_all' => 'storage/queryfx', ··· 207 213 'AphrontFormControl' => 'AphrontView', 208 214 'AphrontFormFileControl' => 'AphrontFormControl', 209 215 'AphrontFormMarkupControl' => 'AphrontFormControl', 216 + 'AphrontFormPasswordControl' => 'AphrontFormControl', 217 + 'AphrontFormRecaptchaControl' => 'AphrontFormControl', 210 218 'AphrontFormSelectControl' => 'AphrontFormControl', 211 219 'AphrontFormStaticControl' => 'AphrontFormControl', 212 220 'AphrontFormSubmitControl' => 'AphrontFormControl', ··· 285 293 'PhabricatorDirectoryItemEditController' => 'PhabricatorDirectoryController', 286 294 'PhabricatorDirectoryItemListController' => 'PhabricatorDirectoryController', 287 295 'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController', 288 - 'PhabricatorFacebookConnectController' => 'PhabricatorAuthController', 296 + 'PhabricatorEmailLoginController' => 'PhabricatorAuthController', 297 + 'PhabricatorEmailTokenController' => 'PhabricatorAuthController', 298 + 'PhabricatorFacebookAuthController' => 'PhabricatorAuthController', 299 + 'PhabricatorFacebookAuthDiagnosticsController' => 'PhabricatorAuthController', 289 300 'PhabricatorFile' => 'PhabricatorFileDAO', 290 301 'PhabricatorFileController' => 'PhabricatorController', 291 302 'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
+9 -2
src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php
··· 115 115 => 'PhabricatorMetaMTAMailingListEditController', 116 116 ), 117 117 118 - '/login/$' => 'PhabricatorLoginController', 118 + '/login/' => array( 119 + '$' => 'PhabricatorLoginController', 120 + 'email/$' => 'PhabricatorEmailLoginController', 121 + 'etoken/(?<token>\w+)/$' => 'PhabricatorEmailTokenController', 122 + ), 119 123 '/logout/$' => 'PhabricatorLogoutController', 120 - '/facebook-connect/$' => 'PhabricatorFacebookConnectController', 124 + '/facebook-auth/' => array( 125 + '$' => 'PhabricatorFacebookAuthController', 126 + 'diagnose/$' => 'PhabricatorFacebookAuthDiagnosticsController', 127 + ), 121 128 ); 122 129 } 123 130
+10 -2
src/aphront/request/AphrontRequest.php
··· 29 29 private $path; 30 30 private $requestData; 31 31 private $user; 32 + private $env; 33 + 34 + final public function setEnvConfig(array $conf) { 35 + $this->env = $conf; 36 + return $this; 37 + } 38 + 39 + final public function getEnvConfig($key, $default = null) { 40 + return idx($this->env, $key, $default); 41 + } 32 42 33 43 final public function __construct($host, $path) { 34 44 $this->host = $host; ··· 121 131 final public function getUser() { 122 132 return $this->user; 123 133 } 124 - 125 - 126 134 127 135 }
+1 -1
src/aphront/response/ajax/__init__.php
··· 7 7 8 8 9 9 phutil_require_module('phabricator', 'aphront/response/base'); 10 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 10 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 11 11 12 12 13 13 phutil_require_source('AphrontAjaxResponse.php');
+131
src/applications/auth/controller/email/PhabricatorEmailLoginController.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + class PhabricatorEmailLoginController extends PhabricatorAuthController { 20 + 21 + public function shouldRequireLogin() { 22 + return false; 23 + } 24 + 25 + public function processRequest() { 26 + $request = $this->getRequest(); 27 + 28 + $e_email = true; 29 + $e_captcha = true; 30 + $errors = array(); 31 + 32 + if ($request->isFormPost()) { 33 + $e_email = null; 34 + $e_captcha = 'Again'; 35 + 36 + $captcha_ok = AphrontFormRecaptchaControl::processCaptcha($request); 37 + if (!$captcha_ok) { 38 + $errors[] = "Captcha response is incorrect, try again."; 39 + $e_captcha = 'Invalid'; 40 + } 41 + 42 + $email = $request->getStr('email'); 43 + if (!strlen($email)) { 44 + $errors[] = "You must provide an email address."; 45 + $e_email = 'Required'; 46 + } 47 + 48 + if (!$errors) { 49 + // NOTE: Don't validate the email unless the captcha is good; this makes 50 + // it expensive to fish for valid email addresses while giving the user 51 + // a better error if they goof their email. 52 + 53 + $target_user = id(new PhabricatorUser())->loadOneWhere( 54 + 'email = %s', 55 + $email); 56 + 57 + if (!$target_user) { 58 + $errors[] = "There is no account associated with that email address."; 59 + $e_email = "Invalid"; 60 + } 61 + 62 + if (!$errors) { 63 + $etoken = $target_user->generateEmailToken(); 64 + 65 + $mail = new PhabricatorMetaMTAMail(); 66 + $mail->setSubject('Phabricator Email Authentication'); 67 + $mail->addTos( 68 + array( 69 + $target_user->getEmail(), 70 + )); 71 + $mail->setBody( 72 + "blah blah blah ". 73 + PhabricatorEnv::getURI('/login/etoken/'.$etoken.'/').'?email='.phutil_escape_uri($target_user->getEmail())); 74 + $mail->save(); 75 + 76 + $view = new AphrontRequestFailureView(); 77 + $view->setHeader('Check Your Email'); 78 + $view->appendChild( 79 + '<p>An email has been sent with a link you can use to login.</p>'); 80 + return $this->buildStandardPageResponse( 81 + $view, 82 + array( 83 + 'title' => 'Email Sent', 84 + )); 85 + } 86 + } 87 + 88 + } 89 + 90 + $email_auth = new AphrontFormView(); 91 + $email_auth 92 + ->setAction('/login/email/') 93 + ->setUser($request->getUser()) 94 + ->appendChild( 95 + id(new AphrontFormTextControl()) 96 + ->setLabel('Email') 97 + ->setName('email') 98 + ->setValue($request->getStr('email')) 99 + ->setError($e_email)) 100 + ->appendChild( 101 + id(new AphrontFormRecaptchaControl()) 102 + ->setLabel('Captcha') 103 + ->setError($e_captcha)) 104 + ->appendChild( 105 + id(new AphrontFormSubmitControl()) 106 + ->setValue('Send Email')); 107 + 108 + $error_view = null; 109 + if ($errors) { 110 + $error_view = new AphrontErrorView(); 111 + $error_view->setTitle('Login Error'); 112 + $error_view->setErrors($errors); 113 + } 114 + 115 + 116 + $panel = new AphrontPanelView(); 117 + $panel->setWidth(AphrontPanelView::WIDTH_FORM); 118 + $panel->appendChild('<h1>Forgot Password / Email Login</h1>'); 119 + $panel->appendChild($email_auth); 120 + 121 + return $this->buildStandardPageResponse( 122 + array( 123 + $error_view, 124 + $panel, 125 + ), 126 + array( 127 + 'title' => 'Create New Account', 128 + )); 129 + } 130 + 131 + }
+24
src/applications/auth/controller/email/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'applications/auth/controller/base'); 10 + phutil_require_module('phabricator', 'applications/metamta/storage/mail'); 11 + phutil_require_module('phabricator', 'applications/people/storage/user'); 12 + phutil_require_module('phabricator', 'infrastructure/env'); 13 + phutil_require_module('phabricator', 'view/form/base'); 14 + phutil_require_module('phabricator', 'view/form/control/recaptcha'); 15 + phutil_require_module('phabricator', 'view/form/control/submit'); 16 + phutil_require_module('phabricator', 'view/form/error'); 17 + phutil_require_module('phabricator', 'view/layout/panel'); 18 + phutil_require_module('phabricator', 'view/page/failure'); 19 + 20 + phutil_require_module('phutil', 'markup'); 21 + phutil_require_module('phutil', 'utils'); 22 + 23 + 24 + phutil_require_source('PhabricatorEmailLoginController.php');
+137
src/applications/auth/controller/emailtoken/PhabricatorEmailTokenController.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + class PhabricatorEmailTokenController extends PhabricatorAuthController { 20 + 21 + private $token; 22 + 23 + public function shouldRequireLogin() { 24 + return false; 25 + } 26 + 27 + public function willProcessRequest(array $data) { 28 + $this->token = $data['token']; 29 + } 30 + 31 + public function processRequest() { 32 + $request = $this->getRequest(); 33 + 34 + $token = $this->token; 35 + $email = $request->getStr('email'); 36 + 37 + $target_user = id(new PhabricatorUser())->loadOneWhere( 38 + 'email = %s', 39 + $email); 40 + 41 + if (!$target_user || !$target_user->validateEmailToken($token)) { 42 + $view = new AphrontRequestFailureView(); 43 + $view->setHeader('Unable to Login'); 44 + $view->appendChild( 45 + '<p>The authentication information in the link you clicked is '. 46 + 'invalid or out of date. Make sure you are copy-and-pasting the '. 47 + 'entire link into your browser. You can try again, or request '. 48 + 'a new email.</p>'); 49 + $view->appendChild( 50 + '<div class="aphront-failure-continue">'. 51 + '<a class="button" href="/login/email/">Send Another Email</a>'. 52 + '</div>'); 53 + return $this->buildStandardPageResponse( 54 + $view, 55 + array( 56 + 'title' => 'Email Sent', 57 + )); 58 + } 59 + 60 + if ($request->getUser()->getPHID() != $target_user->getPHID()) { 61 + $session_key = $target_user->establishSession('web'); 62 + $request->setCookie('phusr', $target_user->getUsername()); 63 + $request->setCookie('phsid', $session_key); 64 + } 65 + 66 + $errors = array(); 67 + 68 + $e_pass = true; 69 + $e_confirm = true; 70 + 71 + if ($request->isFormPost()) { 72 + $e_pass = 'Error'; 73 + $e_confirm = 'Error'; 74 + 75 + $pass = $request->getStr('password'); 76 + $confirm = $request->getStr('confirm'); 77 + 78 + if (strlen($pass) < 3) { 79 + $errors[] = 'That password is ridiculously short.'; 80 + } 81 + 82 + if ($pass !== $confirm) { 83 + $errors[] = "Passwords do not match."; 84 + } 85 + 86 + if (!$errors) { 87 + $target_user->setPassword($pass); 88 + $target_user->save(); 89 + return id(new AphrontRedirectResponse()) 90 + ->setURI('/'); 91 + } 92 + } 93 + 94 + if ($errors) { 95 + $error_view = new AphrontErrorView(); 96 + $error_view->setTitle('Password Reset Failed'); 97 + $error_view->setErrors($errors); 98 + } else { 99 + $error_view = null; 100 + } 101 + 102 + $form = new AphrontFormView(); 103 + $form 104 + ->setUser($target_user) 105 + ->setAction('/login/etoken/'.$token.'/') 106 + ->addHiddenInput('email', $email) 107 + ->appendChild( 108 + id(new AphrontFormPasswordControl()) 109 + ->setLabel('New Password') 110 + ->setName('password') 111 + ->setError($e_pass)) 112 + ->appendChild( 113 + id(new AphrontFormPasswordControl()) 114 + ->setLabel('Confirm Password') 115 + ->setName('confirm') 116 + ->setError($e_confirm)) 117 + ->appendChild( 118 + id(new AphrontFormSubmitControl()) 119 + ->setValue('Reset Password') 120 + ->addCancelButton('/', 'Skip')); 121 + 122 + $panel = new AphrontPanelView(); 123 + $panel->setWidth(AphrontPanelView::WIDTH_FORM); 124 + $panel->setHeader('Reset Password'); 125 + $panel->appendChild($form); 126 + 127 + return $this->buildStandardPageResponse( 128 + array( 129 + $error_view, 130 + $panel, 131 + ), 132 + array( 133 + 'title' => 'Create New Account', 134 + )); 135 + } 136 + 137 + }
+25
src/applications/auth/controller/facebookauth/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'aphront/response/400'); 10 + phutil_require_module('phabricator', 'aphront/response/redirect'); 11 + phutil_require_module('phabricator', 'applications/auth/controller/base'); 12 + phutil_require_module('phabricator', 'applications/files/storage/file'); 13 + phutil_require_module('phabricator', 'applications/people/storage/user'); 14 + phutil_require_module('phabricator', 'infrastructure/env'); 15 + phutil_require_module('phabricator', 'view/form/base'); 16 + phutil_require_module('phabricator', 'view/form/control/submit'); 17 + phutil_require_module('phabricator', 'view/form/error'); 18 + phutil_require_module('phabricator', 'view/layout/panel'); 19 + phutil_require_module('phabricator', 'view/page/failure'); 20 + 21 + phutil_require_module('phutil', 'markup'); 22 + phutil_require_module('phutil', 'parser/uri'); 23 + phutil_require_module('phutil', 'utils'); 24 + 25 + phutil_require_source('PhabricatorFacebookAuthController.php');
+230
src/applications/auth/controller/facebookauth/diagnostics/PhabricatorFacebookAuthDiagnosticsController.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + class PhabricatorFacebookAuthDiagnosticsController 20 + extends PhabricatorAuthController { 21 + 22 + public function shouldRequireLogin() { 23 + return false; 24 + } 25 + 26 + public function processRequest() { 27 + 28 + $auth_enabled = PhabricatorEnv::getEnvConfig('facebook.auth-enabled'); 29 + $app_id = PhabricatorEnv::getEnvConfig('facebook.application-id'); 30 + $app_secret = PhabricatorEnv::getEnvConfig('facebook.application-secret'); 31 + 32 + $res_ok = '<strong style="color: #00aa00;">OK</strong>'; 33 + $res_no = '<strong style="color: #aa0000;">NO</strong>'; 34 + $res_na = '<strong style="color: #999999;">N/A</strong>'; 35 + 36 + $results = array(); 37 + 38 + if (!$auth_enabled) { 39 + $results['facebook.auth-enabled'] = array( 40 + $res_no, 41 + 'false', 42 + 'Facebook authentication is disabled in the configuration. Edit the '. 43 + 'environmental configuration to enable "facebook.auth-enabled".'); 44 + } else { 45 + $results['facebook.auth-enabled'] = array( 46 + $res_ok, 47 + 'true', 48 + 'Facebook authentication is enabled.'); 49 + } 50 + 51 + if (!$app_id) { 52 + $results['facebook.application-id'] = array( 53 + $res_no, 54 + null, 55 + 'No Facebook Application ID is configured. Edit the environmental '. 56 + 'configuration to specify an application ID in '. 57 + '"facebook.application-id". To generate an ID, sign into Facebook, '. 58 + 'install the "Developer" application, and use it to create a new '. 59 + 'Facebook application.'); 60 + } else { 61 + $results['facebook.application-id'] = array( 62 + $res_ok, 63 + $app_id, 64 + 'Application ID is set.'); 65 + } 66 + 67 + if (!$app_secret) { 68 + $results['facebook.application-secret'] = array( 69 + $res_no, 70 + null, 71 + 'No Facebook Application secret is configured. Edit the environmental '. 72 + 'configuration to specify an Application Secret, in '. 73 + '"facebook.application-secret". You can find the application secret '. 74 + 'in the Facebook "Developer" application on Facebook.'); 75 + } else { 76 + $results['facebook.application-secret'] = array( 77 + $res_ok, 78 + "It's a secret!", 79 + 'Application secret is set.'); 80 + } 81 + 82 + $timeout = stream_context_create( 83 + array( 84 + 'http' => array( 85 + 'ignore_errors' => true, 86 + 'timeout' => 5, 87 + ), 88 + )); 89 + $timeout_strict = stream_context_create( 90 + array( 91 + 'http' => array( 92 + 'timeout' => 5, 93 + ), 94 + )); 95 + 96 + $internet = @file_get_contents("http://google.com/", false, $timeout); 97 + if ($internet === false) { 98 + $results['internet'] = array( 99 + $res_no, 100 + null, 101 + 'Unable to make an HTTP request to Google. Check your outbound '. 102 + 'internet connection and firewall/filtering settings.'); 103 + } else { 104 + $results['internet'] = array( 105 + $res_ok, 106 + null, 107 + 'Internet seems OK.'); 108 + } 109 + 110 + $facebook = @file_get_contents("http://facebook.com/", false, $timeout); 111 + if ($facebook === false) { 112 + $results['facebook.com'] = array( 113 + $res_no, 114 + null, 115 + 'Unable to make an HTTP request to facebook.com. Facebook may be '. 116 + 'down or inaccessible.'); 117 + } else { 118 + $results['facebook.com'] = array( 119 + $res_ok, 120 + null, 121 + 'Made a request to facebook.com.'); 122 + } 123 + 124 + $graph = @file_get_contents( 125 + "https://graph.facebook.com/me", 126 + false, 127 + $timeout); 128 + if ($graph === false) { 129 + $results['Facebook Graph'] = array( 130 + $res_no, 131 + null, 132 + "Unable to make an HTTPS request to graph.facebook.com. ". 133 + "The Facebook graph may be down or inaccessible."); 134 + } else { 135 + $results['Facebook Graph'] = array( 136 + $res_ok, 137 + null, 138 + 'Made a request to graph.facebook.com.'); 139 + } 140 + 141 + $test_uri = new PhutilURI('https://graph.facebook.com/oauth/access_token'); 142 + $test_uri->setQueryParams( 143 + array( 144 + 'client_id' => $app_id, 145 + 'client_secret' => $app_secret, 146 + 'grant_type' => 'client_credentials', 147 + )); 148 + 149 + $token_value = @file_get_contents($test_uri, false, $timeout); 150 + $token_strict = @file_get_contents($test_uri, false, $timeout_strict); 151 + if ($token_value === false) { 152 + $results['App Login'] = array( 153 + $res_no, 154 + null, 155 + "Unable to perform an application login with your Application ID and ". 156 + "Application Secret. You may have mistyped or misconfigured them; ". 157 + "Facebook may have revoked your authorization; or Facebook may be ". 158 + "having technical problems."); 159 + } else { 160 + if ($token_strict) { 161 + $results['App Login'] = array( 162 + $res_ok, 163 + $token_strict, 164 + "Raw application login to Facebook works."); 165 + } else { 166 + $data = json_decode($token_value, true); 167 + if (!is_array($data)) { 168 + $results['App Login'] = array( 169 + $res_no, 170 + $token_value, 171 + "Application Login failed but the graph server did not respond ". 172 + "with valid JSON error information. Facebook may be experiencing ". 173 + "technical problems."); 174 + } else { 175 + $results['App Login'] = array( 176 + $res_no, 177 + null, 178 + "Application Login failed with error: ".$token_value); 179 + } 180 + } 181 + } 182 + 183 + return $this->renderResults($results); 184 + } 185 + 186 + private function renderResults($results) { 187 + 188 + $rows = array(); 189 + foreach ($results as $key => $result) { 190 + $rows[] = array( 191 + phutil_escape_html($key), 192 + $result[0], 193 + phutil_escape_html($result[1]), 194 + phutil_escape_html($result[2]), 195 + ); 196 + } 197 + 198 + $table_view = new AphrontTableView($rows); 199 + $table_view->setHeaders( 200 + array( 201 + 'Test', 202 + 'Result', 203 + 'Value', 204 + 'Details', 205 + )); 206 + $table_view->setColumnClasses( 207 + array( 208 + null, 209 + null, 210 + null, 211 + 'wide', 212 + )); 213 + 214 + $panel_view = new AphrontPanelView(); 215 + $panel_view->setHeader('Facebook Auth Diagnostics'); 216 + $panel_view->appendChild( 217 + '<p class="aphront-panel-instructions">These tests may be able to '. 218 + 'help diagnose the root cause of problems you experience with '. 219 + 'Facebook Authentication. Reload the page to run the tests again.</p>'); 220 + $panel_view->appendChild($table_view); 221 + 222 + return $this->buildStandardPageResponse( 223 + $panel_view, 224 + array( 225 + 'title' => 'Facebook Auth Diagnostics', 226 + )); 227 + 228 + } 229 + 230 + }
+18
src/applications/auth/controller/facebookauth/diagnostics/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'applications/auth/controller/base'); 10 + phutil_require_module('phabricator', 'infrastructure/env'); 11 + phutil_require_module('phabricator', 'view/control/table'); 12 + phutil_require_module('phabricator', 'view/layout/panel'); 13 + 14 + phutil_require_module('phutil', 'markup'); 15 + phutil_require_module('phutil', 'parser/uri'); 16 + 17 + 18 + phutil_require_source('PhabricatorFacebookAuthDiagnosticsController.php');
+80 -12
src/applications/auth/controller/facebookconnect/PhabricatorFacebookConnectController.php src/applications/auth/controller/facebookauth/PhabricatorFacebookAuthController.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 - class PhabricatorFacebookConnectController extends PhabricatorAuthController { 19 + class PhabricatorFacebookAuthController extends PhabricatorAuthController { 20 20 21 21 public function shouldRequireLogin() { 22 22 return false; 23 23 } 24 24 25 25 public function processRequest() { 26 + $auth_enabled = PhabricatorEnv::getEnvConfig('facebook.auth-enabled'); 27 + if (!$auth_enabled) { 28 + return new Aphront400Response(); 29 + } 30 + 31 + $diagnose_auth = 32 + '<a href="/facebook-auth/diagnose/" class="button green">'. 33 + 'Diagnose Facebook Auth Problems'. 34 + '</a>'; 35 + 26 36 $request = $this->getRequest(); 27 37 28 38 if ($request->getStr('error')) { 29 - die("OMG ERROR"); 39 + $view = new AphrontRequestFailureView(); 40 + $view->setHeader('Facebook Auth Failed'); 41 + $view->appendChild( 42 + '<p>'. 43 + '<strong>Description:</strong> '. 44 + phutil_escape_html($request->getStr('error_description')). 45 + '</p>'); 46 + $view->appendChild( 47 + '<p>'. 48 + '<strong>Error:</strong> '. 49 + phutil_escape_html($request->getStr('error')). 50 + '</p>'); 51 + $view->appendChild( 52 + '<p>'. 53 + '<strong>Error Reason:</strong> '. 54 + phutil_escape_html($request->getStr('error_reason')). 55 + '</p>'); 56 + $view->appendChild( 57 + '<div class="aphront-failure-continue">'. 58 + '<a href="/login/" class="button">Continue</a>'. 59 + '</div>'); 60 + 61 + return $this->buildStandardPageResponse( 62 + $view, 63 + array( 64 + 'title' => 'Facebook Auth Failed', 65 + )); 30 66 } 31 67 32 68 $token = $request->getStr('token'); 33 69 if (!$token) { 70 + $app_id = PhabricatorEnv::getEnvConfig('facebook.application-id'); 71 + $app_secret = PhabricatorEnv::getEnvConfig('facebook.application-secret'); 72 + $redirect_uri = PhabricatorEnv::getURI('/facebook-auth/'); 73 + 34 74 $code = $request->getStr('code'); 35 - $auth_uri = 'https://graph.facebook.com/oauth/access_token'. 36 - '?client_id=184510521580034'. 37 - '&redirect_uri=http://local.aphront.com/facebook-connect/'. 38 - '&client_secret=OMGSECRETS'. 39 - '&code='.$code; 75 + $auth_uri = new PhutilURI( 76 + "https://graph.facebook.com/oauth/access_token"); 77 + $auth_uri->setQueryParams( 78 + array( 79 + 'client_id' => $app_id, 80 + 'redirect_uri' => $redirect_uri, 81 + 'client_secret' => $app_secret, 82 + 'code' => $code, 83 + )); 40 84 41 85 $response = @file_get_contents($auth_uri); 42 86 if ($response === false) { 43 - throw new Exception('failed to open oauth thing'); 87 + $view = new AphrontRequestFailureView(); 88 + $view->setHeader('Facebook Auth Failed'); 89 + $view->appendChild( 90 + '<p>Unable to authenticate with Facebook. There are several reasons '. 91 + 'this might happen:</p>'. 92 + '<ul>'. 93 + '<li>Phabricator may be configured with the wrong Application '. 94 + 'Secret; or</li>'. 95 + '<li>the Facebook OAuth access token may have expired; or</li>'. 96 + '<li>Facebook may have revoked authorization for the '. 97 + 'Application; or</li>'. 98 + '<li>Facebook may be having technical problems.</li>'. 99 + '</ul>'. 100 + '<p>You can try again, or login using another method.</p>'); 101 + $view->appendChild( 102 + '<div class="aphront-failure-continue">'. 103 + $diagnose_auth. 104 + '<a href="/login/" class="button">Continue</a>'. 105 + '</div>'); 106 + 107 + return $this->buildStandardPageResponse( 108 + $view, 109 + array( 110 + 'title' => 'Facebook Auth Failed', 111 + )); 44 112 } 45 113 46 114 $data = array(); ··· 89 157 $form 90 158 ->addHiddenInput('token', $token) 91 159 ->setUser($request->getUser()) 92 - ->setAction('/facebook-connect/') 160 + ->setAction('/facebook-auth/') 93 161 ->appendChild( 94 162 '<p class="aphront-form-view-instructions">Do you want to link your '. 95 163 "existing Phabricator account (<strong>{$ph_account}</strong>) ". 96 164 "with your Facebook account (<strong>{$fb_account}</strong>) so ". 97 - "you can login with Facebook Connect?") 165 + "you can login with Facebook?") 98 166 ->appendChild( 99 167 id(new AphrontFormSubmitControl()) 100 168 ->setValue('Link Accounts') ··· 170 238 $error_view = null; 171 239 if ($errors) { 172 240 $error_view = new AphrontErrorView(); 173 - $error_view->setTitle('Facebook Connect Failed'); 241 + $error_view->setTitle('Facebook Auth Failed'); 174 242 $error_view->setErrors($errors); 175 243 } 176 244 ··· 178 246 $form 179 247 ->addHiddenInput('token', $token) 180 248 ->setUser($request->getUser()) 181 - ->setAction('/facebook-connect/') 249 + ->setAction('/facebook-auth/') 182 250 ->appendChild( 183 251 id(new AphrontFormTextControl()) 184 252 ->setLabel('Username')
+2 -3
src/applications/auth/controller/facebookconnect/__init__.php src/applications/auth/controller/emailtoken/__init__.php
··· 8 8 9 9 phutil_require_module('phabricator', 'aphront/response/redirect'); 10 10 phutil_require_module('phabricator', 'applications/auth/controller/base'); 11 - phutil_require_module('phabricator', 'applications/files/storage/file'); 12 11 phutil_require_module('phabricator', 'applications/people/storage/user'); 13 12 phutil_require_module('phabricator', 'view/form/base'); 14 13 phutil_require_module('phabricator', 'view/form/control/submit'); 15 14 phutil_require_module('phabricator', 'view/form/error'); 16 15 phutil_require_module('phabricator', 'view/layout/panel'); 16 + phutil_require_module('phabricator', 'view/page/failure'); 17 17 18 - phutil_require_module('phutil', 'markup'); 19 18 phutil_require_module('phutil', 'utils'); 20 19 21 20 22 - phutil_require_source('PhabricatorFacebookConnectController.php'); 21 + phutil_require_source('PhabricatorEmailTokenController.php');
+34 -23
src/applications/auth/controller/login/PhabricatorLoginController.php
··· 34 34 'username = %s', 35 35 $username); 36 36 37 - $user->setPassword('asdf'); 38 - $user->save(); 39 - 40 37 $okay = false; 41 38 if ($user) { 42 39 if ($user->comparePassword($request->getStr('password'))) { ··· 71 68 ->setAction('/login/') 72 69 ->appendChild( 73 70 id(new AphrontFormTextControl()) 74 - ->setLabel('Username') 71 + ->setLabel('Username/Email') 75 72 ->setName('username') 76 73 ->setValue($username)) 77 74 ->appendChild( 78 - id(new AphrontFormTextControl()) 75 + id(new AphrontFormPasswordControl()) 79 76 ->setLabel('Password') 80 - ->setName('password')) 77 + ->setName('password') 78 + ->setCaption( 79 + '<a href="/login/email/">Forgot your password? / Email Login</a>')) 81 80 ->appendChild( 82 81 id(new AphrontFormSubmitControl()) 83 82 ->setValue('Login')); ··· 88 87 $panel->setWidth(AphrontPanelView::WIDTH_FORM); 89 88 $panel->appendChild($form); 90 89 90 + $fbauth_enabled = PhabricatorEnv::getEnvConfig('facebook.auth-enabled'); 91 + if ($fbauth_enabled) { 92 + $auth_uri = new PhutilURI("https://www.facebook.com/dialog/oauth"); 91 93 92 - // TODO: Hardcoded junk 93 - $connect_uri = "https://www.facebook.com/dialog/oauth"; 94 + $user = $request->getUser(); 94 95 95 - $user = $request->getUser(); 96 + $redirect_uri = PhabricatorEnv::getURI('/facebook-auth/'); 97 + $app_id = PhabricatorEnv::getEnvConfig('facebook.application-id'); 96 98 97 - $facebook_connect = new AphrontFormView(); 98 - $facebook_connect 99 - ->setAction($connect_uri) 100 - ->addHiddenInput('client_id', 184510521580034) 101 - ->addHiddenInput('redirect_uri', 'http://local.aphront.com/facebook-connect/') 102 - ->addHiddenInput('scope', 'email') 103 - ->addHiddenInput('state', $user->getCSRFToken()) 104 - ->setUser($request->getUser()) 105 - ->setMethod('GET') 106 - ->appendChild( 107 - id(new AphrontFormSubmitControl()) 108 - ->setValue("Login with Facebook Connect \xC2\xBB")); 99 + // TODO: In theory we should use 'state' to prevent CSRF, but the total 100 + // effect of the CSRF attack is that an attacker can cause a user to login 101 + // to Phabricator if they're already logged into Facebook. This does not 102 + // seem like the most severe threat in the world, and generating CSRF for 103 + // logged-out users is vaugely tricky. 104 + 105 + $facebook_auth = new AphrontFormView(); 106 + $facebook_auth 107 + ->setAction($auth_uri) 108 + ->addHiddenInput('client_id', $app_id) 109 + ->addHiddenInput('redirect_uri', $redirect_uri) 110 + ->addHiddenInput('scope', 'email') 111 + ->setUser($request->getUser()) 112 + ->setMethod('GET') 113 + ->appendChild( 114 + '<p class="aphront-form-instructions">Login or register for '. 115 + 'Phabricator using your Facebook account.</p>') 116 + ->appendChild( 117 + id(new AphrontFormSubmitControl()) 118 + ->setValue("Login with Facebook \xC2\xBB")); 109 119 110 - $panel->appendChild('<br /><h1>Login with Facebook</h1>'); 111 - $panel->appendChild($facebook_connect); 120 + $panel->appendChild('<br /><h1>Login with Facebook</h1>'); 121 + $panel->appendChild($facebook_auth); 122 + } 112 123 113 124 return $this->buildStandardPageResponse( 114 125 array(
+2
src/applications/auth/controller/login/__init__.php
··· 9 9 phutil_require_module('phabricator', 'aphront/response/redirect'); 10 10 phutil_require_module('phabricator', 'applications/auth/controller/base'); 11 11 phutil_require_module('phabricator', 'applications/people/storage/user'); 12 + phutil_require_module('phabricator', 'infrastructure/env'); 12 13 phutil_require_module('phabricator', 'view/form/base'); 13 14 phutil_require_module('phabricator', 'view/form/control/submit'); 14 15 phutil_require_module('phabricator', 'view/form/error'); 15 16 phutil_require_module('phabricator', 'view/layout/panel'); 16 17 18 + phutil_require_module('phutil', 'parser/uri'); 17 19 phutil_require_module('phutil', 'utils'); 18 20 19 21
+1 -1
src/applications/differential/controller/base/__init__.php
··· 8 8 9 9 phutil_require_module('phabricator', 'aphront/response/webpage'); 10 10 phutil_require_module('phabricator', 'applications/base/controller/base'); 11 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 11 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 12 12 13 13 phutil_require_module('phutil', 'utils'); 14 14
+2 -2
src/applications/differential/view/changesetdetailview/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 10 - phutil_require_module('phabricator', 'infratructure/javelin/markup'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 + phutil_require_module('phabricator', 'infrastructure/javelin/markup'); 11 11 phutil_require_module('phabricator', 'view/base'); 12 12 13 13 phutil_require_module('phutil', 'markup');
+2 -2
src/applications/differential/view/changesetlistview/__init__.php
··· 8 8 9 9 phutil_require_module('phabricator', 'applications/differential/constants/changetype'); 10 10 phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview'); 11 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 12 - phutil_require_module('phabricator', 'infratructure/javelin/api'); 11 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 12 + phutil_require_module('phabricator', 'infrastructure/javelin/api'); 13 13 phutil_require_module('phabricator', 'view/base'); 14 14 15 15 phutil_require_module('phutil', 'markup');
+1 -1
src/applications/differential/view/difftableofcontents/__init__.php
··· 7 7 8 8 9 9 phutil_require_module('phabricator', 'applications/differential/constants/changetype'); 10 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 10 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 11 11 phutil_require_module('phabricator', 'view/base'); 12 12 13 13 phutil_require_module('phutil', 'markup');
+1 -1
src/applications/differential/view/revisioncomment/__init__.php
··· 7 7 8 8 9 9 phutil_require_module('phabricator', 'applications/differential/constants/action'); 10 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 10 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 11 11 phutil_require_module('phabricator', 'view/base'); 12 12 13 13 phutil_require_module('phutil', 'markup');
+1 -1
src/applications/differential/view/revisioncommentlist/__init__.php
··· 8 8 9 9 phutil_require_module('phabricator', 'applications/differential/parser/markup'); 10 10 phutil_require_module('phabricator', 'applications/differential/view/revisioncomment'); 11 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 11 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 12 12 phutil_require_module('phabricator', 'view/base'); 13 13 14 14
+1 -1
src/applications/differential/view/revisiondetail/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+1 -1
src/applications/differential/view/revisionupdatehistory/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+1 -1
src/applications/directory/controller/main/__init__.php
··· 9 9 phutil_require_module('phabricator', 'applications/directory/controller/base'); 10 10 phutil_require_module('phabricator', 'applications/directory/storage/category'); 11 11 phutil_require_module('phabricator', 'applications/directory/storage/item'); 12 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 12 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 13 13 14 14 phutil_require_module('phutil', 'markup'); 15 15 phutil_require_module('phutil', 'utils');
+34 -10
src/applications/people/storage/user/PhabricatorUser.php
··· 64 64 return $password; 65 65 } 66 66 67 - const CSRF_CYCLE_FREQUENCY = 3600; 67 + const CSRF_CYCLE_FREQUENCY = 3600; 68 + const CSRF_TOKEN_LENGTH = 16; 69 + 70 + const EMAIL_CYCLE_FREQUENCY = 86400; 71 + const EMAIL_TOKEN_LENGTH = 24; 68 72 69 - public function getCSRFToken() { 70 - return $this->generateCSRFToken(time()); 73 + public function getCSRFToken($offset = 0) { 74 + return $this->generateToken( 75 + time() + (self::CSRF_CYCLE_FREQUENCY * $offset), 76 + self::CSRF_CYCLE_FREQUENCY, 77 + PhabricatorEnv::getEnvConfig('phabricator.csrf-key'), 78 + self::CSRF_TOKEN_LENGTH); 71 79 } 72 80 73 81 public function validateCSRFToken($token) { 74 82 for ($ii = -1; $ii <= 1; $ii++) { 75 - $time = time() + (self::CSRF_CYCLE_FREQUENCY * $ii); 76 - $valid = $this->generateCSRFToken($time); 83 + $valid = $this->getCSRFToken($ii); 77 84 if ($token == $valid) { 78 85 return true; 79 86 } ··· 81 88 return false; 82 89 } 83 90 84 - private function generateCSRFToken($epoch) { 85 - $time_block = floor($epoch / (60 * 60)); 86 - // TODO: this should be a secret lolol 87 - $key = '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3'; 91 + private function generateToken($epoch, $frequency, $key, $len) { 92 + $time_block = floor($epoch / $frequency); 88 93 $vec = $this->getPHID().$this->passwordHash.$key.$time_block; 89 - return substr(md5($vec), 0, 16); 94 + return substr(sha1($vec), 0, $len); 90 95 } 91 96 92 97 public function establishSession($session_type) { ··· 96 101 if (!$urandom) { 97 102 throw new Exception("Failed to open /dev/urandom!"); 98 103 } 104 + 99 105 $entropy = fread($urandom, 20); 100 106 if (strlen($entropy) != 20) { 101 107 throw new Exception("Failed to read /dev/urandom!"); ··· 116 122 $session_key); 117 123 118 124 return $session_key; 125 + } 126 + 127 + public function generateEmailToken($offset = 0) { 128 + return $this->generateToken( 129 + time() + ($offset * self::EMAIL_CYCLE_FREQUENCY), 130 + self::EMAIL_CYCLE_FREQUENCY, 131 + PhabricatorEnv::getEnvConfig('phabricator.csrf-key').$this->getEmail(), 132 + self::EMAIL_TOKEN_LENGTH); 133 + } 134 + 135 + public function validateEmailToken($token) { 136 + for ($ii = -1; $ii <= 1; $ii++) { 137 + $valid = $this->generateEmailToken($ii); 138 + if ($token == $valid) { 139 + return true; 140 + } 141 + } 142 + return false; 119 143 } 120 144 121 145 }
+1
src/applications/people/storage/user/__init__.php
··· 8 8 9 9 phutil_require_module('phabricator', 'applications/people/storage/base'); 10 10 phutil_require_module('phabricator', 'applications/phid/storage/phid'); 11 + phutil_require_module('phabricator', 'infrastructure/env'); 11 12 phutil_require_module('phabricator', 'storage/queryfx'); 12 13 13 14
+34
src/infrastructure/env/PhabricatorEnv.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + final class PhabricatorEnv { 20 + private static $env; 21 + 22 + public static function setEnvConfig(array $config) { 23 + self::$env = $config; 24 + } 25 + 26 + public static function getEnvConfig($key, $default = null) { 27 + return idx(self::$env, $key, $default); 28 + } 29 + 30 + public static function getURI($path) { 31 + return rtrim(self::getEnvConfig('phabricator.base-uri'), '/').$path; 32 + } 33 + 34 + }
+12
src/infrastructure/env/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phutil', 'utils'); 10 + 11 + 12 + phutil_require_source('PhabricatorEnv.php');
src/infratructure/celerity/api/CelerityAPI.php src/infrastructure/celerity/api/CelerityAPI.php
+1 -1
src/infratructure/celerity/api/__init__.php src/infrastructure/celerity/api/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/response'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/response'); 10 10 11 11 12 12 phutil_require_source('CelerityAPI.php');
+5 -5
src/infratructure/celerity/controller/CelerityResourceController.php src/infrastructure/celerity/controller/CelerityResourceController.php
··· 17 17 */ 18 18 19 19 class CelerityResourceController extends AphrontController { 20 - 20 + 21 21 private $path; 22 22 private $hash; 23 23 private $package; 24 - 24 + 25 25 public function willProcessRequest(array $data) { 26 26 $this->path = $data['path']; 27 27 $this->hash = $data['hash']; ··· 37 37 if (!preg_match('/\.(css|js)$/', $path, $matches)) { 38 38 throw new Exception("Only CSS and JS resources may be served."); 39 39 } 40 - 40 + 41 41 $type = $matches[1]; 42 42 43 43 $root = dirname(phutil_get_library_root('phabricator')); ··· 48 48 if (!$paths) { 49 49 return new Aphront404Response(); 50 50 } 51 - 51 + 52 52 try { 53 53 $data = array(); 54 54 foreach ($paths as $path) { ··· 76 76 $response->setMimeType("text/javascript; charset=utf-8"); 77 77 break; 78 78 } 79 - 79 + 80 80 $response->setCacheDurationInSeconds(60 * 60 * 24 * 30); 81 81 82 82 return $response;
+2
src/infratructure/celerity/controller/__init__.php src/infrastructure/celerity/controller/__init__.php
··· 7 7 8 8 9 9 phutil_require_module('phabricator', 'aphront/controller'); 10 + phutil_require_module('phabricator', 'aphront/response/404'); 10 11 phutil_require_module('phabricator', 'aphront/response/file'); 12 + phutil_require_module('phabricator', 'infrastructure/celerity/map'); 11 13 12 14 phutil_require_module('phutil', 'filesystem'); 13 15 phutil_require_module('phutil', 'moduleutils');
+5 -5
src/infratructure/celerity/map/CelerityResourceMap.php src/infrastructure/celerity/map/CelerityResourceMap.php
··· 67 67 68 68 $map[$symbol] = $info; 69 69 } 70 - 70 + 71 71 public function setPackageMap($package_map) { 72 72 $this->packageMap = $package_map; 73 73 } 74 - 74 + 75 75 public function packageResources(array $resolved_map) { 76 76 $packaged = array(); 77 77 $handled = array(); ··· 92 92 } 93 93 return $packaged; 94 94 } 95 - 95 + 96 96 public function resolvePackage($package_hash) { 97 97 $package = idx($this->packageMap['packages'], $package_hash); 98 98 if (!$package) { 99 99 return null; 100 100 } 101 - 101 + 102 102 $paths = array(); 103 103 foreach ($package['symbols'] as $symbol) { 104 104 $paths[] = $this->resourceMap[$symbol]['disk']; 105 105 } 106 - 106 + 107 107 return $paths; 108 108 } 109 109
+1
src/infratructure/celerity/map/__init__.php src/infrastructure/celerity/map/__init__.php
··· 7 7 8 8 9 9 phutil_require_module('phutil', 'moduleutils'); 10 + phutil_require_module('phutil', 'utils'); 10 11 11 12 12 13 phutil_require_source('CelerityResourceMap.php');
src/infratructure/celerity/response/CelerityStaticResourceResponse.php src/infrastructure/celerity/response/CelerityStaticResourceResponse.php
+1 -1
src/infratructure/celerity/response/__init__.php src/infrastructure/celerity/response/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/map'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/map'); 10 10 11 11 phutil_require_module('phutil', 'markup'); 12 12
src/infratructure/javelin/api/Javelin.php src/infrastructure/javelin/api/Javelin.php
+1 -1
src/infratructure/javelin/api/__init__.php src/infrastructure/javelin/api/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 11 11 12 12 phutil_require_source('Javelin.php');
+1 -1
src/infratructure/javelin/markup/__init__.php src/infrastructure/javelin/markup/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 11 11 phutil_require_module('phutil', 'markup'); 12 12
src/infratructure/javelin/markup/markup.php src/infrastructure/javelin/markup/markup.php
+1 -1
src/view/control/table/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'utils');
+1 -1
src/view/dialog/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+1 -1
src/view/form/base/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+9 -1
src/view/form/control/base/AphrontFormControl.php
··· 82 82 abstract protected function renderInput(); 83 83 abstract protected function getCustomControlClass(); 84 84 85 + protected function shouldRender() { 86 + return true; 87 + } 88 + 85 89 final public function render() { 90 + if (!$this->shouldRender()) { 91 + return null; 92 + } 93 + 86 94 $custom_class = $this->getCustomControlClass(); 87 95 88 96 if (strlen($this->getLabel())) { ··· 119 127 if (strlen($this->getCaption())) { 120 128 $caption = 121 129 '<div class="aphront-form-caption">'. 122 - phutil_escape_html($this->getCaption()). 130 + $this->getCaption(). 123 131 '</div>'; 124 132 } else { 125 133 $caption = null;
+1 -1
src/view/form/control/checkbox/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/form/control/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+36
src/view/form/control/password/AphrontFormPasswordControl.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + class AphrontFormPasswordControl extends AphrontFormControl { 20 + 21 + protected function getCustomControlClass() { 22 + return 'aphront-form-control-password'; 23 + } 24 + 25 + protected function renderInput() { 26 + return phutil_render_tag( 27 + 'input', 28 + array( 29 + 'type' => 'password', 30 + 'name' => $this->getName(), 31 + 'value' => $this->getValue(), 32 + 'disabled' => $this->getDisabled() ? 'disabled' : null, 33 + )); 34 + } 35 + 36 + }
+14
src/view/form/control/password/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'view/form/control/base'); 10 + 11 + phutil_require_module('phutil', 'markup'); 12 + 13 + 14 + phutil_require_source('AphrontFormPasswordControl.php');
+65
src/view/form/control/recaptcha/AphrontFormRecaptchaControl.php
··· 1 + <?php 2 + 3 + /* 4 + * Copyright 2011 Facebook, Inc. 5 + * 6 + * Licensed under the Apache License, Version 2.0 (the "License"); 7 + * you may not use this file except in compliance with the License. 8 + * You may obtain a copy of the License at 9 + * 10 + * http://www.apache.org/licenses/LICENSE-2.0 11 + * 12 + * Unless required by applicable law or agreed to in writing, software 13 + * distributed under the License is distributed on an "AS IS" BASIS, 14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + * See the License for the specific language governing permissions and 16 + * limitations under the License. 17 + */ 18 + 19 + class AphrontFormRecaptchaControl extends AphrontFormControl { 20 + 21 + protected function getCustomControlClass() { 22 + return 'aphront-form-control-recaptcha'; 23 + } 24 + 25 + protected function shouldRender() { 26 + return self::isRecaptchaEnabled(); 27 + } 28 + 29 + private static function isRecaptchaEnabled() { 30 + return PhabricatorEnv::getEnvConfig('recaptcha.enabled'); 31 + } 32 + 33 + private static function requireLib() { 34 + $root = phutil_get_library_root('phabricator'); 35 + require_once dirname($root).'/externals/recaptcha/recaptchalib.php'; 36 + } 37 + 38 + public static function processCaptcha(AphrontRequest $request) { 39 + if (!self::isRecaptchaEnabled()) { 40 + return true; 41 + } 42 + 43 + self::requireLib(); 44 + 45 + $challenge = $request->getStr('recaptcha_challenge_field'); 46 + $response = $request->getStr('recaptcha_response_field'); 47 + $resp = recaptcha_check_answer( 48 + PhabricatorEnv::getEnvConfig('recaptcha.private-key'), 49 + $_SERVER['REMOTE_ADDR'], 50 + $challenge, 51 + $response); 52 + 53 + return (bool)@$resp->is_valid; 54 + } 55 + 56 + protected function renderInput() { 57 + self::requireLib(); 58 + 59 + return recaptcha_get_html( 60 + PhabricatorEnv::getEnvConfig('recaptcha.public-key'), 61 + $error = null, 62 + $use_ssl = false); 63 + } 64 + 65 + }
+15
src/view/form/control/recaptcha/__init__.php
··· 1 + <?php 2 + /** 3 + * This file is automatically generated. Lint this module to rebuild it. 4 + * @generated 5 + */ 6 + 7 + 8 + 9 + phutil_require_module('phabricator', 'infrastructure/env'); 10 + phutil_require_module('phabricator', 'view/form/control/base'); 11 + 12 + phutil_require_module('phutil', 'moduleutils'); 13 + 14 + 15 + phutil_require_source('AphrontFormRecaptchaControl.php');
+3 -3
src/view/form/control/tokenizer/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 10 - phutil_require_module('phabricator', 'infratructure/javelin/api'); 11 - phutil_require_module('phabricator', 'infratructure/javelin/markup'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 + phutil_require_module('phabricator', 'infrastructure/javelin/api'); 11 + phutil_require_module('phabricator', 'infrastructure/javelin/markup'); 12 12 phutil_require_module('phabricator', 'view/form/control/base'); 13 13 14 14 phutil_require_module('phutil', 'markup');
+1 -1
src/view/layout/panel/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+1 -1
src/view/layout/sidenav/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 phutil_require_module('phabricator', 'view/null'); 12 12
+1 -1
src/view/page/failure/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+1 -1
src/view/page/standard/__init__.php
··· 6 6 7 7 8 8 9 - phutil_require_module('phabricator', 'infratructure/celerity/api'); 9 + phutil_require_module('phabricator', 'infrastructure/celerity/api'); 10 10 phutil_require_module('phabricator', 'view/page/base'); 11 11 12 12 phutil_require_module('phutil', 'markup');
+27
webroot/index.php
··· 16 16 * limitations under the License. 17 17 */ 18 18 19 + $env = getenv('PHABRICATOR_ENV'); 20 + if (!$env) { 21 + header('Content-Type: text/plain'); 22 + die( 23 + "CONFIG ERROR: ". 24 + "The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ". 25 + "your httpd.conf to include 'SetEnv PHABRICATOR_ENV <env>', where '<env>' ". 26 + "is one of 'development', 'production', or a custom environment."); 27 + } 28 + 29 + $conf = phabricator_read_config_file($env); 30 + $conf['phabricator.env'] = $env; 31 + 19 32 setup_aphront_basics(); 33 + 34 + phutil_require_module('phabricator', 'infrastructure/env'); 35 + PhabricatorEnv::setEnvConfig($conf); 20 36 21 37 $host = $_SERVER['HTTP_HOST']; 22 38 $path = $_REQUEST['__path__']; ··· 96 112 function __autoload($class_name) { 97 113 PhutilSymbolLoader::loadClass($class_name); 98 114 } 115 + 116 + 117 + function phabricator_read_config_file($config) { 118 + $root = dirname(dirname(__FILE__)); 119 + $conf = include $root.'/conf/'.$config.'.conf.php'; 120 + if ($conf === false) { 121 + throw new Exception("Failed to read config file '{$config}'."); 122 + } 123 + return $conf; 124 + } 125 +
-1
webroot/rsrc/css/aphront/panel-view.css
··· 37 37 margin-right: auto; 38 38 margin-left: auto; 39 39 } 40 -
+16 -2
webroot/rsrc/css/aphront/request-failure-view.css
··· 19 19 } 20 20 21 21 .aphront-request-failure-view .aphront-request-failure-body { 22 - padding: 1em 2em; 22 + padding: 1em 2em 1.5em; 23 23 } 24 24 25 25 .aphront-request-failure-view .aphront-request-failure-body p { 26 - margin: .5em 0 1.25em; 26 + margin: .5em 0; 27 + } 28 + 29 + .aphront-failure-continue { 30 + margin-top: 1.5em; 31 + text-align: right; 32 + } 33 + 34 + .aphront-failure-continue a.button { 35 + margin-left: 1em; 36 + } 37 + 38 + .aphront-request-failure-view ul { 39 + list-style: disc; 40 + margin-left: 3em; 27 41 }