Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 165 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
WebInstallerName | |
0.00% |
0 / 165 |
|
0.00% |
0 / 2 |
650 | |
0.00% |
0 / 1 |
execute | |
0.00% |
0 / 87 |
|
0.00% |
0 / 1 |
20 | |||
submit | |
0.00% |
0 / 78 |
|
0.00% |
0 / 1 |
462 |
1 | <?php |
2 | |
3 | /** |
4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation; either version 2 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License along |
15 | * with this program; if not, write to the Free Software Foundation, Inc., |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | * http://www.gnu.org/copyleft/gpl.html |
18 | * |
19 | * @file |
20 | * @ingroup Installer |
21 | */ |
22 | |
23 | namespace MediaWiki\Installer; |
24 | |
25 | use MediaWiki\Config\HashConfig; |
26 | use MediaWiki\Json\FormatJson; |
27 | use MediaWiki\MainConfigNames; |
28 | use MediaWiki\MediaWikiServices; |
29 | use MediaWiki\Parser\Sanitizer; |
30 | use MediaWiki\Password\UserPasswordPolicy; |
31 | use MediaWiki\Title\Title; |
32 | use MediaWiki\User\User; |
33 | use MediaWiki\User\UserRigorOptions; |
34 | |
35 | class WebInstallerName extends WebInstallerPage { |
36 | |
37 | /** |
38 | * @return string |
39 | */ |
40 | public function execute() { |
41 | $r = $this->parent->request; |
42 | if ( $r->wasPosted() && $this->submit() ) { |
43 | return 'continue'; |
44 | } |
45 | |
46 | $this->startForm(); |
47 | |
48 | // Encourage people to not name their site 'MediaWiki' by blanking the |
49 | // field. I think that was the intent with the original $GLOBALS['wgSitename'] |
50 | // but these two always were the same so had the effect of making the |
51 | // installer forget $wgSitename when navigating back to this page. |
52 | if ( $this->getVar( 'wgSitename' ) == 'MediaWiki' ) { |
53 | $this->setVar( 'wgSitename', '' ); |
54 | } |
55 | |
56 | // Set wgMetaNamespace to something valid before we show the form. |
57 | // $wgMetaNamespace defaults to $wgSiteName which is 'MediaWiki' |
58 | $metaNS = $this->getVar( 'wgMetaNamespace' ); |
59 | $this->setVar( |
60 | 'wgMetaNamespace', |
61 | wfMessage( 'config-ns-other-default' )->inContentLanguage()->text() |
62 | ); |
63 | |
64 | // Database isn't available in config yet, so take it |
65 | // from the installer |
66 | $pingbackConf = new HashConfig( [ |
67 | MainConfigNames::DBtype => $this->getVar( 'wgDBtype' ), |
68 | ] ); |
69 | $pingbackInfo = Pingback::getSystemInfo( $pingbackConf ); |
70 | |
71 | $this->addHTML( |
72 | // TODO: validate wgServer on the client side |
73 | $this->parent->getTextBox( [ |
74 | 'var' => 'wgServer', |
75 | 'label' => 'config-server', |
76 | 'help' => $this->parent->getHelpBox( 'config-server-help' ) |
77 | ] ) . |
78 | $this->parent->getTextBox( [ |
79 | 'var' => 'wgSitename', |
80 | 'label' => 'config-site-name', |
81 | 'help' => $this->parent->getHelpBox( 'config-site-name-help' ) |
82 | ] ) . |
83 | // getRadioSet() builds a set of labeled radio buttons. |
84 | // For grep: The following messages are used as the item labels: |
85 | // config-ns-site-name, config-ns-generic, config-ns-other |
86 | $this->parent->getRadioSet( [ |
87 | 'var' => '_NamespaceType', |
88 | 'label' => 'config-project-namespace', |
89 | 'itemLabelPrefix' => 'config-ns-', |
90 | 'values' => [ 'site-name', 'generic', 'other' ], |
91 | 'commonAttribs' => [ 'class' => 'enableForOther', |
92 | 'rel' => 'config_wgMetaNamespace' ], |
93 | 'help' => $this->parent->getHelpBox( 'config-project-namespace-help' ) |
94 | ] ) . |
95 | $this->parent->getTextBox( [ |
96 | 'var' => 'wgMetaNamespace', |
97 | 'label' => '', // @todo Needs a label? |
98 | 'attribs' => [ 'class' => 'enabledByOther' ] |
99 | ] ) . |
100 | $this->getFieldsetStart( 'config-admin-box' ) . |
101 | $this->parent->getTextBox( [ |
102 | 'var' => '_AdminName', |
103 | 'label' => 'config-admin-name', |
104 | 'help' => $this->parent->getHelpBox( 'config-admin-help' ) |
105 | ] ) . |
106 | $this->parent->getPasswordBox( [ |
107 | 'var' => '_AdminPassword', |
108 | 'label' => 'config-admin-password', |
109 | ] ) . |
110 | $this->parent->getPasswordBox( [ |
111 | 'var' => '_AdminPasswordConfirm', |
112 | 'label' => 'config-admin-password-confirm' |
113 | ] ) . |
114 | $this->parent->getTextBox( [ |
115 | 'var' => '_AdminEmail', |
116 | 'attribs' => [ |
117 | 'dir' => 'ltr', |
118 | ], |
119 | 'label' => 'config-admin-email', |
120 | 'help' => $this->parent->getHelpBox( 'config-admin-email-help' ) |
121 | ] ) . |
122 | $this->parent->getCheckBox( [ |
123 | 'var' => '_Subscribe', |
124 | 'label' => 'config-subscribe', |
125 | 'help' => $this->parent->getHelpBox( 'config-subscribe-help' ) |
126 | ] ) . |
127 | $this->parent->getCheckBox( [ |
128 | 'var' => 'wgPingback', |
129 | 'label' => 'config-pingback', |
130 | 'help' => $this->parent->getHelpBox( |
131 | 'config-pingback-help', |
132 | FormatJson::encode( $pingbackInfo, true ) |
133 | ), |
134 | 'value' => true, |
135 | ] ) . |
136 | $this->getFieldsetEnd() . |
137 | $this->parent->getInfoBox( wfMessage( 'config-almost-done' )->plain() ) . |
138 | // getRadioSet() builds a set of labeled radio buttons. |
139 | // For grep: The following messages are used as the item labels: |
140 | // config-optional-continue, config-optional-skip |
141 | $this->parent->getRadioSet( [ |
142 | 'var' => '_SkipOptional', |
143 | 'itemLabelPrefix' => 'config-optional-', |
144 | 'values' => [ 'continue', 'skip' ] |
145 | ] ) |
146 | ); |
147 | |
148 | // Restore the default value |
149 | $this->setVar( 'wgMetaNamespace', $metaNS ); |
150 | |
151 | $this->endForm(); |
152 | |
153 | return 'output'; |
154 | } |
155 | |
156 | /** |
157 | * @return bool |
158 | */ |
159 | public function submit() { |
160 | global $wgPasswordPolicy; |
161 | |
162 | $retVal = true; |
163 | $this->parent->setVarsFromRequest( [ 'wgServer', 'wgSitename', '_NamespaceType', |
164 | '_AdminName', '_AdminPassword', '_AdminPasswordConfirm', '_AdminEmail', |
165 | '_Subscribe', '_SkipOptional', 'wgMetaNamespace', 'wgPingback' ] ); |
166 | |
167 | // Validate site name |
168 | if ( strval( $this->getVar( 'wgSitename' ) ) === '' ) { |
169 | $this->parent->showError( 'config-site-name-blank' ); |
170 | $retVal = false; |
171 | } |
172 | |
173 | // Fetch namespace |
174 | $nsType = $this->getVar( '_NamespaceType' ); |
175 | if ( $nsType == 'site-name' ) { |
176 | $name = $this->getVar( 'wgSitename' ); |
177 | // Sanitize for namespace |
178 | // This algorithm should match the JS one in WebInstallerOutput.php |
179 | $name = preg_replace( '/[\[\]\{\}|#<>%+? ]/', '_', $name ); |
180 | $name = str_replace( '&', '&', $name ); |
181 | $name = preg_replace( '/__+/', '_', $name ); |
182 | $name = ucfirst( trim( $name, '_' ) ); |
183 | } elseif ( $nsType == 'generic' ) { |
184 | $name = wfMessage( 'config-ns-generic' )->text(); |
185 | } else { // other |
186 | $name = $this->getVar( 'wgMetaNamespace' ); |
187 | } |
188 | |
189 | // Validate namespace |
190 | if ( strpos( $name, ':' ) !== false ) { |
191 | $good = false; |
192 | } else { |
193 | // Title-style validation |
194 | $title = Title::newFromText( $name ); |
195 | if ( !$title ) { |
196 | $good = $nsType == 'site-name'; |
197 | } else { |
198 | $name = $title->getDBkey(); |
199 | $good = true; |
200 | } |
201 | } |
202 | if ( !$good ) { |
203 | $this->parent->showError( 'config-ns-invalid', $name ); |
204 | $retVal = false; |
205 | } |
206 | |
207 | // Make sure it won't conflict with any existing namespaces |
208 | $nsIndex = MediaWikiServices::getInstance()->getContentLanguage()->getNsIndex( $name ); |
209 | if ( $nsIndex !== false && $nsIndex !== NS_PROJECT ) { |
210 | $this->parent->showError( 'config-ns-conflict', $name ); |
211 | $retVal = false; |
212 | } |
213 | |
214 | $this->setVar( 'wgMetaNamespace', $name ); |
215 | |
216 | // Validate username for creation |
217 | $name = $this->getVar( '_AdminName' ); |
218 | if ( strval( $name ) === '' ) { |
219 | $this->parent->showError( 'config-admin-name-blank' ); |
220 | $cname = $name; |
221 | $retVal = false; |
222 | } else { |
223 | $userNameUtils = MediaWikiServices::getInstance()->getUserNameUtils(); |
224 | $cname = $userNameUtils->getCanonical( $name, UserRigorOptions::RIGOR_CREATABLE ); |
225 | if ( $cname === false ) { |
226 | $this->parent->showError( 'config-admin-name-invalid', $name ); |
227 | $retVal = false; |
228 | } else { |
229 | $this->setVar( '_AdminName', $cname ); |
230 | } |
231 | } |
232 | |
233 | // Validate password |
234 | $msg = false; |
235 | $pwd = $this->getVar( '_AdminPassword' ); |
236 | $user = User::newFromName( $cname ); |
237 | if ( $user ) { |
238 | $upp = new UserPasswordPolicy( |
239 | $wgPasswordPolicy['policies'], |
240 | $wgPasswordPolicy['checks'] |
241 | ); |
242 | $status = $upp->checkUserPasswordForGroups( |
243 | $user, |
244 | $pwd, |
245 | [ 'bureaucrat', 'sysop', 'interface-admin' ] // per Installer::createSysop() |
246 | ); |
247 | $valid = $status->isGood() ? true : $status->getMessage(); |
248 | } else { |
249 | $valid = 'config-admin-name-invalid'; |
250 | } |
251 | if ( strval( $pwd ) === '' ) { |
252 | // Provide a more specific and helpful message if password field is left blank |
253 | $msg = 'config-admin-password-blank'; |
254 | } elseif ( $pwd !== $this->getVar( '_AdminPasswordConfirm' ) ) { |
255 | $msg = 'config-admin-password-mismatch'; |
256 | } elseif ( $valid !== true ) { |
257 | $msg = $valid; |
258 | } |
259 | if ( $msg !== false ) { |
260 | $this->parent->showError( $msg ); |
261 | $this->setVar( '_AdminPassword', '' ); |
262 | $this->setVar( '_AdminPasswordConfirm', '' ); |
263 | $retVal = false; |
264 | } |
265 | |
266 | // Validate e-mail if provided |
267 | $email = $this->getVar( '_AdminEmail' ); |
268 | if ( $email && !Sanitizer::validateEmail( $email ) ) { |
269 | $this->parent->showError( 'config-admin-error-bademail' ); |
270 | $retVal = false; |
271 | } |
272 | // If they asked to subscribe to mediawiki-announce but didn't give |
273 | // an e-mail, show an error. T31332 |
274 | if ( !$email && $this->getVar( '_Subscribe' ) ) { |
275 | $this->parent->showError( 'config-subscribe-noemail' ); |
276 | $retVal = false; |
277 | } |
278 | |
279 | return $retVal; |
280 | } |
281 | |
282 | } |