Add more validation rules for player name

This commit is contained in:
printempw 2018-06-19 11:51:34 +08:00
parent 6926ae21ff
commit abde385776
16 changed files with 165 additions and 76 deletions

View File

@ -179,7 +179,19 @@ class AdminController extends Controller
->text('max_upload_file_size')->addon('KB')
->hint(trans('options.general.max_upload_file_size.hint', ['size' => ini_get('upload_max_filesize')]));
$form->checkbox('allow_chinese_playername')->label();
$form->select('player_name_rule')
->option('official', trans('options.general.player_name_rule.official'))
->option('cjk', trans('options.general.player_name_rule.cjk'))
->option('custom', trans('options.general.player_name_rule.custom'));
$form->text('custom_player_name_regexp')->hint()->placeholder();
$form->group('player_name_length')
->addon(trans('options.general.player_name_length.addon1'))
->text('player_name_length_min')
->addon(trans('options.general.player_name_length.addon2'))
->text('player_name_length_max')
->addon(trans('options.general.player_name_length.addon3'));
$form->select('api_type')
->option('0', 'CustomSkinLoader API')
@ -305,7 +317,7 @@ class AdminController extends Controller
} elseif ($action == "nickname") {
$this->validate($request, [
'nickname' => 'required|nickname'
'nickname' => 'required|no_special_chars'
]);
$user->setNickName($request->input('nickname'));

View File

@ -109,7 +109,7 @@ class AuthController extends Controller
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8|max:32',
'nickname' => 'required|nickname|max:255'
'nickname' => 'required|no_special_chars|max:255'
]);
if (! option('user_can_register')) {

View File

@ -59,7 +59,7 @@ class PlayerController extends Controller
public function add(Request $request)
{
$this->validate($request, [
'player_name' => 'required|'.(option('allow_chinese_playername') ? 'pname_chinese' : 'playername')
'player_name' => 'required|player_name|min:'.option('player_name_length_min').'|max:'.option('player_name_length_max')
]);
event(new CheckPlayerExists($request->input('player_name')));
@ -114,7 +114,7 @@ class PlayerController extends Controller
public function rename(Request $request)
{
$this->validate($request, [
'new_player_name' => 'required|'.(option('allow_chinese_playername') ? 'pname_chinese' : 'playername')
'new_player_name' => 'required|player_name|min:'.option('player_name_length_min').'|max:'.option('player_name_length_max')
]);
$newName = $request->input('new_player_name');

View File

@ -20,40 +20,63 @@ class ValidatorExtendServiceProvider extends ServiceProvider
* @param $p parameters
* @param $v validator
*/
Validator::extend('username', function($a, $value, $p, $v) {
return preg_match("/^([A-Za-z0-9\x{4e00}-\x{9fa5}_]+)$/u", $value);
Validator::extend('no_special_chars', function ($a, $value, $p, $v) {
return $value === addslashes(trim($value));
});
Validator::extend('nickname', function($a, $value, $p, $v) {
return $value == addslashes(trim($value));
Validator::extend('player_name', function ($a, $value, $p, $v) {
$regexp = '/^(.*)$/';
switch (option('player_name_rule')) {
case 'official':
// Mojang's official username rule
$regexp = '/^([A-Za-z0-9_]+)$/';
break;
case 'cjk':
// CJK Unified Ideographs
$regexp = '/^([A-Za-z0-9_\x{4e00}-\x{9fff}]+)$/u';
break;
case 'custom':
$regexp = option('custom_player_name_regexp') ?: $regexp;
break;
}
return preg_match($regexp, $value);
});
Validator::extend('no_special_chars', function($a, $value, $p, $v) {
return $value == addslashes(trim($value));
Validator::extend('preference', function ($a, $value, $p, $v) {
return preg_match('/^(default|slim)$/', $value);
});
Validator::extend('playername', function($a, $value, $p, $v) {
return preg_match("/^([A-Za-z0-9_]+)$/", $value);
Validator::extend('model', function ($a, $value, $p, $v) {
return preg_match('/^(steve|alex|cape)$/', $value);
});
Validator::extend('pname_chinese', function($a, $value, $p, $v) {
return preg_match("/^([A-Za-z0-9\x{4e00}-\x{9fa5}_]+)$/u", $value);
});
Validator::extend('preference', function($a, $value, $p, $v) {
return preg_match("/^(default|slim)$/", $value);
});
Validator::extend('model', function($a, $value, $p, $v) {
return preg_match("/^(steve|alex|cape)$/", $value);
});
$this->registerExpiredRules();
}
/**
* Register any application services.
* Register these for the compatibility with plugins using old rules.
*
* @return void
*/
protected function registerExpiredRules()
{
Validator::extend('nickname', function ($a, $value, $p, $v) {
return $value === addslashes(trim($value));
});
Validator::extend('playername', function($a, $value, $p, $v) {
return preg_match('/^([A-Za-z0-9_]+)$/', $value);
});
Validator::extend('pname_chinese', function ($a, $value, $p, $v) {
return preg_match('/^([A-Za-z0-9_\x{4e00}-\x{9fff}]+)$/u', $value);
});
}
public function register()
{
//

View File

@ -13,7 +13,10 @@ return [
'home_pic_url' => './resources/assets/dist/images/bg.jpg',
'custom_css' => '',
'custom_js' => '',
'allow_chinese_playername' => 'true',
'player_name_rule' => 'official',
'custom_player_name_regexp' => '',
'player_name_length_min' => '3',
'player_name_length_max' => '16',
'comment_script' => '',
'allow_sending_statistics' => 'true',
'user_initial_score' => '1000',

View File

@ -82,9 +82,20 @@ general:
max_upload_file_size:
title: Max Upload Size
hint: "Limit of PHP in php.ini: :size"
allow_chinese_playername:
title: Player Name
label: Allow chinese player names.
player_name_rule:
title: Player Name Rule
official: Letters, numbers and underscores (Mojang's official rule)
cjk: Allow CJK Unified Ideographs
custom: Use custom rules (regular expression)
custom_player_name_regexp:
title: Custom Player Name Rules
hint: Only takes effect when the above option is set to 'custom'. Leave empty to allow any character.
placeholder: Regular Expressions
player_name_length:
title: Player Name Length
addon1: Minimum
addon2: characters, maximum
addon3: characters
api_type: Prefered JSON API
auto_del_invalid_texture:
title: Invalid Textures

View File

@ -80,6 +80,13 @@ player:
pname-rule: Could only contain letters, numbers and dashes.
pname-rule-chinese: Could only contain chinese characters, letters, numbers and dashes.
player-name-rule:
official: Player name may only contains letters, numbers and underscores.
cjk: Player name may contains letters, numbers, underscores and CJK Unified Ideographs.
custom: Custom player name rules are applied on this site. Please contact admins for further information.
player-name-length: The player name should be at least :min characters and not greater than :max characters.
add:
repeated: The player name is already registered.
lack-score: You don't have enough score to add a player.

View File

@ -1,8 +1,6 @@
# Blessing Skin
username: ':attribute format is invalid.'
nickname: ':attribute format is invalid.'
playername: 'The :attribute may only contain letters, numbers and dashes.'
pname_chinese: 'The :attribute may only contain letters, numbers, dashes and chinese characters.'
player_name: 'The :attribute contains invalid character.'
no_special_chars: 'The :attribute must not contain special characters.'
preference: 'The :attribute must be default or slim.'
model: 'The :attribute must be steve, alex or cape.'

View File

@ -82,9 +82,20 @@ general:
max_upload_file_size:
title: 最大允许上传大小
hint: PHP 限制::size定义在 php.ini 中。
allow_chinese_playername:
title: 角色名
label: 允许中文角色名
player_name_rule:
title: 角色名规则
official: 大小写字母数字下划线Mojang 官方的用户名规则)
cjk: 允许中文字符(中日韩统一表意文字)
custom: 自定义(使用下方设置的正则表达式)
custom_player_name_regexp:
title: 自定义角色名规则
hint: 正则表达式,仅当上一选项为「自定义」时生效。留空表示允许使用任意字符。
placeholder: 正则表达式,不懂别乱填
player_name_length:
title: 角色名长度
addon1: 最少
addon2: 个字符,最多
addon3: 个字符
api_type: 首选 JSON API
auto_del_invalid_texture:
title: 失效材质

View File

@ -84,8 +84,12 @@ player:
cape: 披风:
empty: 未上传
pname-rule: 只能包含数字、字母以及下划线
pname-rule-chinese: 可使用汉字,字母数字以及下划线
player-name-rule:
official: 角色名只能包含拉丁字母、数字以及下划线。
cjk: 角色名可使用拉丁字母、数字、下划线以及汉字(中日韩统一表意文字)。
custom: 本站使用了自定义的角色名规则,详情请咨询站点管理员。
player-name-length: 角色名最少要求 :min 个字符,最多不超过 :max 个字符。
add:
repeated: 该角色名已经被其他人注册掉啦

View File

@ -1,8 +1,6 @@
# Blessing Skin
username: ':attribute 格式错误。'
nickname: ':attribute 格式错误。'
playername: ':attribute 只能包含数字、字母以及下划线。'
pname_chinese: ':attribute 只能包含数字、字母、汉字以及下划线。'
player_name: ':attribute 不符合规则。'
no_special_chars: ':attribute 不能包含特殊字母。'
preference: ':attribute 的值必须为 default 或 slim。'
model: ':attribute 的值必须为 steve、alex 或 cape。'

View File

@ -113,15 +113,20 @@
<table class="table">
<tbody>
<tr>
<style> td { border-top: 0 !important; } </style>
<td>{{ trans('user.player.player-name') }}</td>
<td>
<input type="text" class="form-control" id="player_name"
placeholder="{{ option('allow_chinese_playername') ? trans('user.player.pname-rule-chinese') : trans('user.player.pname-rule') }}" value="">
<td class="key">{{ trans('user.player.player-name') }}</td>
<td class="value">
<input type="text" class="form-control" id="player_name" value="">
</td>
</tr>
</tbody>
</table>
<div class="callout callout-info">
<ul style="padding: 0 0 0 20px; margin: 0;">
<li>{{ trans('user.player.player-name-rule.'.option('player_name_rule')) }}</li>
<li>{{ trans('user.player.player-name-length', ['min' => option('player_name_length_min'), 'max' => option('player_name_length_max')]) }}</li>
</ul>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('general.close') }}</button>

View File

@ -106,7 +106,8 @@ class AdminControllerTest extends TestCase
'options.general.max_upload_file_size.hint',
['size' => ini_get('upload_max_filesize')]
))
->uncheck('allow_chinese_playername')
->select('cjk', 'player_name_rule')
->type('/^([0-9]+)$/', 'custom_player_name_regexp')
->select('1', 'api_type')
->check('auto_del_invalid_texture')
->type('code', 'comment_script')
@ -119,7 +120,8 @@ class AdminControllerTest extends TestCase
$this->assertEquals('8', option('regs_per_ip'));
$this->assertEquals('1', option('ip_get_method'));
$this->assertEquals('2048', option('max_upload_file_size'));
$this->assertFalse(option('allow_chinese_playername'));
$this->assertEquals('cjk', option('player_name_rule'));
$this->assertEquals('/^([0-9]+)$/', option('custom_player_name_regexp'));
$this->assertEquals('1', option('api_type'));
$this->assertTrue(option('auto_del_invalid_texture'));
$this->assertEquals('code', option('comment_script'));
@ -298,14 +300,14 @@ class AdminControllerTest extends TestCase
'msg' => trans('validation.required', ['attribute' => 'nickname'])
]);
// Action is `email` but with an invalid nickname
// Action is `nickname` but with an invalid nickname
$this->post(
'/admin/users',
['uid' => $user->uid, 'action' => 'nickname', 'nickname' => '\\'],
['X-Requested-With' => 'XMLHttpRequest']
)->seeJson([
'errno' => 1,
'msg' => trans('validation.nickname', ['attribute' => 'nickname'])
'msg' => trans('validation.no_special_chars', ['attribute' => 'nickname'])
]);
// Set nickname successfully

View File

@ -295,7 +295,7 @@ class AuthControllerTest extends TestCase
['X-Requested-With' => 'XMLHttpRequest']
)->seeJson([
'errno' => 1,
'msg' => trans('validation.nickname', ['attribute' => 'nickname'])
'msg' => trans('validation.no_special_chars', ['attribute' => 'nickname'])
]);
// Should return a warning if `nickname` is too long

View File

@ -34,32 +34,47 @@ class PlayerControllerTest extends TestCase
'msg' => trans('validation.required', ['attribute' => 'Player Name'])
]);
// Not allowed to use Chinese characters
option(['allow_chinese_playername' => false]);
$this->post('/user/player/add', [
'player_name' => '角色名'
], ['X-Requested-With' => 'XMLHttpRequest'])
->seeJson([
'errno' => 1,
'msg' => trans('validation.playername', ['attribute' => 'Player Name'])
]);
// Only A-Za-z0-9_ are allowed
option(['player_name_rule' => 'official']);
$this->post(
'/user/player/add',
['player_name' => '角色名'],
['X-Requested-With' => 'XMLHttpRequest']
)->seeJson([
'errno' => 1,
'msg' => trans('validation.player_name', ['attribute' => 'Player Name'])
]);
// Custom player name rule (regexp)
option(['player_name_rule' => 'custom']);
option(['custom_player_name_regexp' => '/^([0-9]+)$/']);
$this->post(
'/user/player/add',
['player_name' => 'yjsnpi'],
['X-Requested-With' => 'XMLHttpRequest']
)->seeJson([
'errno' => 1,
'msg' => trans('validation.player_name', ['attribute' => 'Player Name'])
]);
// Lack of score
option(['player_name_rule' => 'official']);
$user = factory(User::class)->create(['score' => 0]);
$this->actAs($user)
->post('/user/player/add', ['player_name' => 'no_score'])
->seeJson([
'errno' => 7,
'msg' => trans('user.player.add.lack-score')
]);
$this->actAs($user)->post(
'/user/player/add',
['player_name' => 'no_score'],
['X-Requested-With' => 'XMLHttpRequest']
)->seeJson([
'errno' => 7,
'msg' => trans('user.player.add.lack-score')
]);
$this->expectsEvents(Events\CheckPlayerExists::class);
// Allowed to use Chinese characters
option(['allow_chinese_playername' => true]);
// Allowed to use CJK characters
option(['player_name_rule' => 'cjk']);
$user = factory(User::class)->create();
$score = $user->score;
$this->actAs($user)
->post('/user/player/add', [
$this->actAs($user)->post('/user/player/add', [
'player_name' => '角色名'
])->seeJson([
'errno' => 0,
@ -142,20 +157,20 @@ class PlayerControllerTest extends TestCase
'msg' => trans('validation.required', ['attribute' => 'Player Name'])
]);
// Chinese characters are not allowed
option(['allow_chinese_playername' => false]);
$this->post('/user/player/rename', [
// Only A-Za-z0-9_ are allowed
option(['player_name_rule' => 'official']);
$this->post('/user/player/rename',[
'pid' => $player->pid,
'new_player_name' => '角色名'
], [
'X-Requested-With' => 'XMLHttpRequest'
])->seeJson([
'errno' => 1,
'msg' => trans('validation.playername', ['attribute' => 'Player Name'])
'msg' => trans('validation.player_name', ['attribute' => 'Player Name'])
]);
// Other invalid characters
option(['allow_chinese_playername' => true]);
option(['player_name_rule' => 'cjk']);
$this->post('/user/player/rename', [
'pid' => $player->pid,
'new_player_name' => '\\'
@ -163,7 +178,7 @@ class PlayerControllerTest extends TestCase
'X-Requested-With' => 'XMLHttpRequest'
])->seeJson([
'errno' => 1,
'msg' => trans('validation.pname_chinese', ['attribute' => 'Player Name'])
'msg' => trans('validation.player_name', ['attribute' => 'Player Name'])
]);
// Use a duplicated player name

View File

@ -133,7 +133,7 @@ class UserControllerTest extends TestCase
'X-Requested-With' => 'XMLHttpRequest'
])->seeJson([
'errno' => 1,
'msg' => trans('validation.nickname', ['attribute' => 'new nickname'])
'msg' => trans('validation.no_special_chars', ['attribute' => 'new nickname'])
]);
// Too long nickname