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
|
<?php
namespace MediaWiki\HTMLForm\Field;
use MediaWiki\MediaWikiServices;
use MediaWiki\User\ExternalUserNames;
use MediaWiki\Widget\UserInputWidget;
use Wikimedia\IPUtils;
/**
* Implements a text input field for user names.
* Automatically auto-completes if using the OOUI display format.
*
* Optional parameters:
* 'exists' - Whether to validate that the user already exists
* 'external' - Whether an external user (imported actor) is interpreted as "valid"
* 'ipallowed' - Whether an IP address is interpreted as "valid"
* 'iprange' - Whether an IP address range is interpreted as "valid"
* 'iprangelimits' - Specifies the valid IP ranges for IPv4 and IPv6 in an array.
*
* @stable to extend
* @since 1.26
*/
class HTMLUserTextField extends HTMLTextField {
/**
* @stable to call
* @inheritDoc
*/
public function __construct( $params ) {
$params = wfArrayPlus2d( $params, [
'exists' => false,
'external' => false,
'ipallowed' => false,
'iprange' => false,
'iprangelimits' => [
'IPv4' => 0,
'IPv6' => 0,
],
]
);
parent::__construct( $params );
}
public function validate( $value, $alldata ) {
// If the value is null, reset it to an empty string which is what is expected by the parent.
if ( $value === null ) {
$value = '';
}
// If the value is empty, there are no additional checks that can be performed.
if ( $value === '' ) {
return parent::validate( $value, $alldata );
}
// check if the input is a valid username
$user = MediaWikiServices::getInstance()->getUserFactory()->newFromName( $value );
if ( $user ) {
// check if the user exists, if requested
if ( $this->mParams['exists'] && !(
$user->isRegistered() &&
// Treat hidden users as unregistered if current user can't view them (T309894)
!( $user->isHidden() && !( $this->mParent && $this->mParent->getUser()->isAllowed( 'hideuser' ) ) )
) ) {
return $this->msg( 'htmlform-user-not-exists', $user->getName() );
}
} else {
// not a valid username
$valid = false;
// check if the input is a valid external user
if ( $this->mParams['external'] && ExternalUserNames::isExternal( $value ) ) {
$valid = true;
}
// check if the input is a valid IP address
if ( $this->mParams['ipallowed'] && IPUtils::isValid( $value ) ) {
$valid = true;
}
// check if the input is a valid IP range
if ( $this->mParams['iprange'] ) {
$rangeError = $this->isValidIPRange( $value );
if ( $rangeError === true ) {
$valid = true;
} elseif ( $rangeError !== false ) {
return $rangeError;
}
}
if ( !$valid ) {
return $this->msg( 'htmlform-user-not-valid', $value );
}
}
return parent::validate( $value, $alldata );
}
protected function isValidIPRange( $value ) {
$cidrIPRanges = $this->mParams['iprangelimits'];
if ( !IPUtils::isValidRange( $value ) ) {
return false;
}
[ $ip, $range ] = explode( '/', $value, 2 );
if (
( IPUtils::isIPv4( $ip ) && $cidrIPRanges['IPv4'] == 32 ) ||
( IPUtils::isIPv6( $ip ) && $cidrIPRanges['IPv6'] == 128 )
) {
// Range block effectively disabled
return $this->msg( 'ip_range_toolow' );
}
if (
( IPUtils::isIPv4( $ip ) && $range > 32 ) ||
( IPUtils::isIPv6( $ip ) && $range > 128 )
) {
// Dodgy range
return $this->msg( 'ip_range_invalid' );
}
if ( IPUtils::isIPv4( $ip ) && $range < $cidrIPRanges['IPv4'] ) {
return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv4'] );
}
if ( IPUtils::isIPv6( $ip ) && $range < $cidrIPRanges['IPv6'] ) {
return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv6'] );
}
return true;
}
protected function getInputWidget( $params ) {
return new UserInputWidget( $params );
}
protected function shouldInfuseOOUI() {
return true;
}
protected function getOOUIModules() {
return [ 'mediawiki.widgets.UserInputWidget' ];
}
public function getInputHtml( $value ) {
// add the required module and css class for user suggestions in non-OOUI mode
$this->mParent->getOutput()->addModules( 'mediawiki.userSuggest' );
$this->mClass .= ' mw-autocomplete-user';
// return parent html
return parent::getInputHTML( $value );
}
}
/** @deprecated class alias since 1.42 */
class_alias( HTMLUserTextField::class, 'HTMLUserTextField' );
|