182 lines
6.8 KiB
Java
182 lines
6.8 KiB
Java
package im.rosetta.executors;
|
||
|
||
import java.util.Arrays;
|
||
import java.util.HashSet;
|
||
import java.util.regex.Matcher;
|
||
import java.util.regex.Pattern;
|
||
|
||
import im.rosetta.Failures;
|
||
import im.rosetta.client.tags.ECIAuthentificate;
|
||
import im.rosetta.database.entity.User;
|
||
import im.rosetta.database.repository.UserRepository;
|
||
import im.rosetta.network.enums.ResultCode;
|
||
import im.rosetta.network.packet.PacketResult;
|
||
import im.rosetta.network.packet.PacketUserInfo;
|
||
import im.rosetta.service.services.UserService;
|
||
|
||
import io.orprotocol.ProtocolException;
|
||
import io.orprotocol.client.Client;
|
||
import io.orprotocol.packet.PacketExecutor;
|
||
|
||
public class ExecutorUserInfo extends PacketExecutor<PacketUserInfo> {
|
||
|
||
private final UserRepository userRepository = new UserRepository();
|
||
private final UserService userService = new UserService(userRepository);
|
||
private final HashSet<String> blockedUsernames = new HashSet<>(Arrays.asList(
|
||
"user",
|
||
"admin",
|
||
"rosettasupport",
|
||
"rosettaupdates",
|
||
"freddie871",
|
||
"updates",
|
||
"deleted",
|
||
"safety",
|
||
"secure",
|
||
"rosettasafe",
|
||
"rosettadev1"
|
||
));
|
||
|
||
@Override
|
||
public void onPacketReceived(PacketUserInfo packet, Client client) throws Exception, ProtocolException {
|
||
ECIAuthentificate eciAuthentificate = client.getTag(ECIAuthentificate.class);
|
||
String username = packet.getUsername();
|
||
String title = packet.getTitle();
|
||
|
||
if(eciAuthentificate == null || !eciAuthentificate.hasAuthorized()){
|
||
/**
|
||
* Только для авторизованных пользователей, а этот пользователь - не авторизован
|
||
*/
|
||
client.disconnect(Failures.HANDSHAKE_NOT_COMPLETED);
|
||
return;
|
||
}
|
||
|
||
User user = userService.fromClient(client);
|
||
if(user == null){
|
||
/**
|
||
* Пользователь с таким ключем не найден в базе,
|
||
* такого не может быть, но лучше чтобы была дополнительная проверка
|
||
*/
|
||
client.disconnect(Failures.DATA_MISSMATCH);
|
||
return;
|
||
}
|
||
|
||
ResultCode usernameResult = tryChangeUsername(user, username);
|
||
if(usernameResult == ResultCode.USERNAME_TAKEN){
|
||
/**
|
||
* Это имя пользователя уже занято, отправляем клиенту ошибку
|
||
*/
|
||
PacketResult result = new PacketResult();
|
||
result.setResultCode(ResultCode.USERNAME_TAKEN);
|
||
client.send(result);
|
||
return;
|
||
}
|
||
if(usernameResult != ResultCode.SUCCESS){
|
||
/**
|
||
* Не удалось сменить username, отправляем клиенту ошибку
|
||
*/
|
||
PacketResult result = new PacketResult();
|
||
result.setResultCode(ResultCode.INVALID);
|
||
client.send(result);
|
||
return;
|
||
}
|
||
|
||
ResultCode titleResult = tryChangeTitle(user, title);
|
||
if(titleResult != ResultCode.SUCCESS){
|
||
/**
|
||
* Не удалось сменить title, отправляем клиенту ошибку
|
||
*/
|
||
PacketResult result = new PacketResult();
|
||
result.setResultCode(ResultCode.INVALID);
|
||
client.send(result);
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* Отправляем клиенту успешный результат
|
||
*/
|
||
PacketResult result = new PacketResult();
|
||
result.setResultCode(ResultCode.SUCCESS);
|
||
client.send(result);
|
||
}
|
||
|
||
/**
|
||
* Пробует сменить username
|
||
* @param user пользователь
|
||
* @param username имя пользователя для смены
|
||
* @return вернет false если смена прошла неудачно или true если username
|
||
* не нуждается в изменении или изменен
|
||
*/
|
||
public ResultCode tryChangeUsername(User user, String username){
|
||
String targetRegexp = "^[a-z][a-z0-9_]{4,15}$";
|
||
Pattern pattern = Pattern.compile(targetRegexp);
|
||
Matcher matcher = pattern.matcher(username);
|
||
|
||
if(user.getUsername().equalsIgnoreCase(username)){
|
||
/**
|
||
* Пользователь не меняет имя, значит операция прошла успешно,
|
||
* по крайней мере нам не нужно возвращать клиенту код ошибки
|
||
*/
|
||
return ResultCode.SUCCESS;
|
||
}
|
||
if(!matcher.matches()){
|
||
/**
|
||
* Не подходит по регулярному выражению
|
||
*/
|
||
return ResultCode.INVALID;
|
||
}
|
||
if(blockedUsernames.contains(username)){
|
||
/**
|
||
* Это имя пользователя не доступно для смены
|
||
*/
|
||
return ResultCode.INVALID;
|
||
}
|
||
if(userService.isUsernameTaken(username)){
|
||
/**
|
||
* Такое имя пользователя уже занято
|
||
*/
|
||
return ResultCode.USERNAME_TAKEN;
|
||
}
|
||
|
||
/**
|
||
* Меняем имя пользователя
|
||
*/
|
||
user.setUsername(username);
|
||
userRepository.update(user);
|
||
return ResultCode.SUCCESS;
|
||
}
|
||
|
||
/**
|
||
* Пробует сменить заголовок пользователя (title)
|
||
* @param user пользователь
|
||
* @param username имя пользователя для смены
|
||
* @return вернет false если смена прошла неудачно или true если title
|
||
* не нуждается в изменении или изменен
|
||
*/
|
||
public ResultCode tryChangeTitle(User user, String title) {
|
||
String targetRegexp = "^[a-zA-Z0-9а-яА-Я _-]{1,22}$";
|
||
Pattern pattern = Pattern.compile(targetRegexp);
|
||
Matcher matcher = pattern.matcher(title);
|
||
|
||
if(user.getTitle().equalsIgnoreCase(title)){
|
||
/**
|
||
* Пользователь не меняет имя, значит операция прошла успешно,
|
||
* по крайней мере нам не нужно возвращать клиенту код ошибки
|
||
*/
|
||
return ResultCode.SUCCESS;
|
||
}
|
||
if(!matcher.matches()){
|
||
/**
|
||
* Не подходит по регулярному выражению
|
||
*/
|
||
return ResultCode.INVALID;
|
||
}
|
||
/**
|
||
* Меняем имя пользователя
|
||
*/
|
||
user.setTitle(title);
|
||
userRepository.update(user);
|
||
return ResultCode.SUCCESS;
|
||
}
|
||
|
||
}
|