package com.sshmanager.service; import com.sshmanager.dto.ConnectionCreateRequest; import com.sshmanager.dto.ConnectionDto; import com.sshmanager.entity.Connection; import com.sshmanager.repository.ConnectionRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.Instant; import java.util.List; import java.util.stream.Collectors; @Service public class ConnectionService { private final ConnectionRepository connectionRepository; private final EncryptionService encryptionService; private final SshService sshService; public ConnectionService(ConnectionRepository connectionRepository, EncryptionService encryptionService, SshService sshService) { this.connectionRepository = connectionRepository; this.encryptionService = encryptionService; this.sshService = sshService; } public List listByUserId(Long userId) { return connectionRepository.findByUserIdOrderByUpdatedAtDesc(userId).stream() .map(ConnectionDto::fromEntity) .collect(Collectors.toList()); } public ConnectionDto getById(Long id, Long userId) { Connection conn = connectionRepository.findById(id).orElseThrow( () -> new RuntimeException("Connection not found: " + id)); if (!conn.getUserId().equals(userId)) { throw new RuntimeException("Access denied"); } return ConnectionDto.fromEntity(conn); } @Transactional public ConnectionDto create(ConnectionCreateRequest request, Long userId) { Connection conn = new Connection(); conn.setUserId(userId); conn.setName(request.getName()); conn.setHost(request.getHost()); conn.setPort(request.getPort() != null ? request.getPort() : 22); conn.setUsername(request.getUsername()); conn.setAuthType(request.getAuthType() != null ? request.getAuthType() : Connection.AuthType.PASSWORD); if (conn.getAuthType() == Connection.AuthType.PASSWORD) { conn.setEncryptedPassword(encryptionService.encrypt(request.getPassword())); conn.setEncryptedPrivateKey(null); conn.setPassphrase(null); } else { conn.setEncryptedPassword(null); conn.setEncryptedPrivateKey(encryptionService.encrypt(request.getPrivateKey())); conn.setPassphrase(encryptionService.encrypt(request.getPassphrase())); } conn = connectionRepository.save(conn); return ConnectionDto.fromEntity(conn); } @Transactional public ConnectionDto update(Long id, ConnectionCreateRequest request, Long userId) { Connection conn = connectionRepository.findById(id).orElseThrow( () -> new RuntimeException("Connection not found: " + id)); if (!conn.getUserId().equals(userId)) { throw new RuntimeException("Access denied"); } if (request.getName() != null) conn.setName(request.getName()); if (request.getHost() != null) conn.setHost(request.getHost()); if (request.getPort() != null) conn.setPort(request.getPort()); if (request.getUsername() != null) conn.setUsername(request.getUsername()); if (request.getAuthType() != null) conn.setAuthType(request.getAuthType()); if (conn.getAuthType() == Connection.AuthType.PASSWORD) { if (request.getPassword() != null) { conn.setEncryptedPassword(encryptionService.encrypt(request.getPassword())); } conn.setEncryptedPrivateKey(null); conn.setPassphrase(null); } else { if (request.getPrivateKey() != null) { conn.setEncryptedPrivateKey(encryptionService.encrypt(request.getPrivateKey())); } if (request.getPassphrase() != null) { conn.setPassphrase(encryptionService.encrypt(request.getPassphrase())); } conn.setEncryptedPassword(null); } conn.setUpdatedAt(Instant.now()); conn = connectionRepository.save(conn); return ConnectionDto.fromEntity(conn); } @Transactional public void delete(Long id, Long userId) { Connection conn = connectionRepository.findById(id).orElse(null); if (conn == null) { return; } if (!conn.getUserId().equals(userId)) { throw new RuntimeException("Access denied"); } connectionRepository.delete(conn); } public Connection getConnectionForSsh(Long id, Long userId) { Connection conn = connectionRepository.findById(id).orElseThrow( () -> new RuntimeException("Connection not found: " + id)); if (!conn.getUserId().equals(userId)) { throw new RuntimeException("Access denied"); } return conn; } public String getDecryptedPassword(Connection conn) { return conn.getEncryptedPassword() != null ? encryptionService.decrypt(conn.getEncryptedPassword()) : null; } public String getDecryptedPrivateKey(Connection conn) { return conn.getEncryptedPrivateKey() != null ? encryptionService.decrypt(conn.getEncryptedPrivateKey()) : null; } public String getDecryptedPassphrase(Connection conn) { return conn.getPassphrase() != null ? encryptionService.decrypt(conn.getPassphrase()) : null; } public Connection testConnection(Connection conn, String password, String privateKey, String passphrase) { SshService.SshSession session = null; try { session = sshService.createShellSession(conn, password, privateKey, passphrase); return conn; } catch (Exception e) { throw new RuntimeException("Connection test failed: " + e.getMessage(), e); } finally { if (session != null) { session.disconnect(); } } } }