Files
rosetta-wss/src/main/java/im/rosetta/executors/ExecutorUserInfo.java

182 lines
6.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}