Изменение домена с rosetta-im.com на rosetta.im
This commit is contained in:
231
src/main/java/im/rosetta/executors/Executor0Handshake.java
Normal file
231
src/main/java/im/rosetta/executors/Executor0Handshake.java
Normal file
@@ -0,0 +1,231 @@
|
||||
package im.rosetta.executors;
|
||||
|
||||
import im.rosetta.Failures;
|
||||
import im.rosetta.client.ClientManager;
|
||||
import im.rosetta.client.tags.ECIAuthentificate;
|
||||
import im.rosetta.client.tags.ECIDevice;
|
||||
import im.rosetta.database.entity.Device;
|
||||
import im.rosetta.database.entity.User;
|
||||
import im.rosetta.database.repository.BufferRepository;
|
||||
import im.rosetta.database.repository.DeviceRepository;
|
||||
import im.rosetta.database.repository.UserRepository;
|
||||
import im.rosetta.event.EventManager;
|
||||
import im.rosetta.event.events.handshake.HandshakeCompletedEvent;
|
||||
import im.rosetta.event.events.handshake.HandshakeDeviceConfirmEvent;
|
||||
import im.rosetta.event.events.handshake.HandshakeFailedEvent;
|
||||
import im.rosetta.packet.Packet0Handshake;
|
||||
import im.rosetta.packet.Packet9DeviceNew;
|
||||
import im.rosetta.packet.runtime.HandshakeStage;
|
||||
import im.rosetta.service.services.BufferService;
|
||||
import im.rosetta.service.services.DeviceService;
|
||||
|
||||
import io.orprotocol.ProtocolException;
|
||||
import io.orprotocol.client.Client;
|
||||
import io.orprotocol.lock.Lock;
|
||||
import io.orprotocol.packet.PacketExecutor;
|
||||
import io.orprotocol.packet.PacketManager;
|
||||
|
||||
public class Executor0Handshake extends PacketExecutor<Packet0Handshake> {
|
||||
|
||||
private final UserRepository userRepository = new UserRepository();
|
||||
private final DeviceRepository deviceRepository = new DeviceRepository();
|
||||
private final DeviceService deviceService = new DeviceService(deviceRepository);
|
||||
private final EventManager eventManager;
|
||||
private final ClientManager clientManager;
|
||||
private final BufferRepository bufferRepository = new BufferRepository();
|
||||
private final BufferService bufferService;
|
||||
|
||||
public Executor0Handshake(EventManager eventManager, ClientManager clientManager, PacketManager packetManager) {
|
||||
this.eventManager = eventManager;
|
||||
this.clientManager = clientManager;
|
||||
this.bufferService = new BufferService(bufferRepository, packetManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Lock(lockFor = "publicKey")
|
||||
public void onPacketReceived(Packet0Handshake handshake, Client client) throws ProtocolException {
|
||||
String publicKey = handshake.getPublicKey();
|
||||
String privateKey = handshake.getPrivateKey();
|
||||
String deviceId = handshake.getDeviceId();
|
||||
String deviceName = handshake.getDeviceName();
|
||||
String deviceOs = handshake.getDeviceOs();
|
||||
int protocolVersion = handshake.getProtocolVersion();
|
||||
/**
|
||||
* Получаем информацию об аутентификации клиента
|
||||
* используя возможности ECI тэгов.
|
||||
*/
|
||||
ECIAuthentificate authentificate = client.getTag(ECIAuthentificate.class);
|
||||
if(authentificate != null && authentificate.hasAuthorized()) {
|
||||
/**
|
||||
* Клиент уже авторизован, повторный хэндшейк не допускается
|
||||
*/
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Проверяем корректность версии протокола
|
||||
*/
|
||||
if(protocolVersion != 1) {
|
||||
client.disconnect(Failures.UNSUPPORTED_PROTOCOL);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создаем минимальную информацию об устройстве клиента
|
||||
*/
|
||||
ECIDevice device = new ECIDevice(deviceId, deviceName, deviceOs);
|
||||
client.addTag(ECIDevice.class, device);
|
||||
|
||||
/**
|
||||
* Проверяем есть ли такой пользователь
|
||||
*/
|
||||
User user = userRepository.findByField("publicKey", publicKey);
|
||||
|
||||
if(user == null) {
|
||||
/**
|
||||
* Пользователь не найден, создаем нового
|
||||
*/
|
||||
user = new User();
|
||||
user.setPrivateKey(privateKey);
|
||||
user.setPublicKey(publicKey);
|
||||
user.setUsername("");
|
||||
user.setTitle(publicKey.substring(0, 7));
|
||||
/**
|
||||
* Новый пользователь не верифицирован
|
||||
*/
|
||||
user.setVerified(0);
|
||||
|
||||
userRepository.save(user);
|
||||
|
||||
/**
|
||||
* Ставим метку аутентификации на клиента
|
||||
*/
|
||||
ECIAuthentificate eciTag = new ECIAuthentificate
|
||||
(publicKey, privateKey, HandshakeStage.COMPLETED);
|
||||
client.addTag(ECIAuthentificate.class, eciTag);
|
||||
/**
|
||||
* Вызываем событие завершения хэндшейка
|
||||
*/
|
||||
boolean cancelled = this.eventManager.callEvent(
|
||||
new HandshakeCompletedEvent(publicKey, privateKey, device, eciTag, client)
|
||||
);
|
||||
if(cancelled) {
|
||||
/**
|
||||
* Событие было отменено, не даем завершить хэндшейк
|
||||
*/
|
||||
client.disconnect(Failures.DATA_MISSMATCH);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Отправляем клиенту подтверждение успешного хэндшейка
|
||||
*/
|
||||
handshake.setHandshakeStage(HandshakeStage.COMPLETED);
|
||||
handshake.setHeartbeatInterval(this.settings.heartbeatInterval);
|
||||
client.send(handshake);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Пользователь найден, проверяем приватный ключ
|
||||
*/
|
||||
if(!user.getPrivateKey().equals(privateKey)){
|
||||
/**
|
||||
* Приватный ключ не совпадает, отключаем клиента
|
||||
*/
|
||||
eventManager.callEvent(new HandshakeFailedEvent(publicKey, privateKey, device, authentificate, client));
|
||||
client.disconnect(Failures.AUTHENTIFICATION_ERROR);
|
||||
return;
|
||||
}
|
||||
long userDevicesCount = deviceRepository.countUserDevices(user);
|
||||
|
||||
/**
|
||||
* Проверяем верифицировано ли устройство
|
||||
*/
|
||||
if(userDevicesCount > 0 && !deviceService.isDeviceVerifiedByUser(deviceId, user)) {
|
||||
/**
|
||||
* Устройство не верифицировано, нужно отправить клиента
|
||||
* на подтверждение устройства
|
||||
*/
|
||||
handshake.setHandshakeStage(HandshakeStage.NEED_DEVICE_VERIFICATION);
|
||||
handshake.setHeartbeatInterval(this.settings.heartbeatInterval);
|
||||
/**
|
||||
* Ставим метку аутентификации на клиента
|
||||
*/
|
||||
ECIAuthentificate eciTag = new ECIAuthentificate
|
||||
(publicKey, privateKey, HandshakeStage.NEED_DEVICE_VERIFICATION);
|
||||
client.addTag(ECIAuthentificate.class, eciTag);
|
||||
/**
|
||||
* Вызываем событие подтверждения устройства
|
||||
*/
|
||||
this.eventManager.callEvent(
|
||||
new HandshakeDeviceConfirmEvent(publicKey, privateKey, device, authentificate, client)
|
||||
);
|
||||
/**
|
||||
* Отправляем клиенту информацию о необходимости
|
||||
* подтверждения устройства
|
||||
*/
|
||||
client.send(handshake);
|
||||
|
||||
/**
|
||||
* Уведомляем все авторизованные устройства пользователя о том, что нужно подтвердить новое устройство
|
||||
*/
|
||||
Packet9DeviceNew newDevicePacket = new Packet9DeviceNew();
|
||||
newDevicePacket.setDeviceId(deviceId);
|
||||
newDevicePacket.setDeviceName(deviceName);
|
||||
newDevicePacket.setDeviceOs(deviceOs);
|
||||
newDevicePacket.setIpAddress(client.getSocket().getRemoteSocketAddress().getAddress().getHostAddress());
|
||||
clientManager.sendPacketToAuthorizedPK(publicKey, newDevicePacket);
|
||||
/**
|
||||
* Сбрасываем клиенту все старые подтверждения устройств, чтобы исключить спам запросами
|
||||
*/
|
||||
this.bufferService.deletePacketsFromBuffer(publicKey, newDevicePacket, 0);
|
||||
/**
|
||||
* Кладем пакет в очередь на все устройства пользователя,
|
||||
* чтобы если в момент отправки этого пакета какое-то устройство было не онлайн,
|
||||
* то когда оно зайдет в сеть, то получит этот пакет и сможет отреагировать на него,
|
||||
* показав пользователю уведомление о том, что нужно подтвердить новое устройство
|
||||
*/
|
||||
this.bufferService.pushPacketToBuffer("server", publicKey, newDevicePacket);
|
||||
return;
|
||||
}
|
||||
|
||||
if(userDevicesCount == 0) {
|
||||
/**
|
||||
* Это первое устройство пользователя, сохраняем его
|
||||
* как верифицированное
|
||||
*/
|
||||
Device newDevice = new Device();
|
||||
newDevice.setDeviceId(deviceId);
|
||||
newDevice.setDeviceName(deviceName);
|
||||
newDevice.setDeviceOs(deviceOs);
|
||||
newDevice.setPublicKey(publicKey);
|
||||
newDevice.setLeaveTime(System.currentTimeMillis());
|
||||
deviceRepository.save(newDevice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ставим метку аутентификации на клиента
|
||||
*/
|
||||
ECIAuthentificate eciTag = new ECIAuthentificate
|
||||
(publicKey, privateKey, HandshakeStage.COMPLETED);
|
||||
client.addTag(ECIAuthentificate.class, eciTag);
|
||||
/**
|
||||
* Вызываем событие завершения хэндшейка
|
||||
*/
|
||||
boolean cancelled = this.eventManager.callEvent(
|
||||
new HandshakeCompletedEvent(publicKey, privateKey, device, eciTag, client)
|
||||
);
|
||||
if(cancelled) {
|
||||
/**
|
||||
* Событие было отменено, не даем завершить хэндшейк
|
||||
*/
|
||||
client.disconnect(Failures.DATA_MISSMATCH);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Отправляем клиенту подтверждение успешного хэндшейка
|
||||
*/
|
||||
handshake.setHandshakeStage(HandshakeStage.COMPLETED);
|
||||
handshake.setHeartbeatInterval(this.settings.heartbeatInterval);
|
||||
client.send(handshake);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user