Improve SFTP reliability and credential hygiene with regression tests
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
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.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ConnectionServiceTest {
|
||||
|
||||
@Mock
|
||||
private ConnectionRepository connectionRepository;
|
||||
|
||||
@Mock
|
||||
private EncryptionService encryptionService;
|
||||
|
||||
@InjectMocks
|
||||
private ConnectionService connectionService;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(connectionRepository.save(any(Connection.class))).thenAnswer(invocation -> invocation.getArgument(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createPasswordConnectionClearsPrivateKeyCredentials() {
|
||||
ConnectionCreateRequest request = new ConnectionCreateRequest();
|
||||
request.setName("prod");
|
||||
request.setHost("127.0.0.1");
|
||||
request.setUsername("root");
|
||||
request.setAuthType(Connection.AuthType.PASSWORD);
|
||||
request.setPassword("secret");
|
||||
request.setPrivateKey("unused-key");
|
||||
request.setPassphrase("unused-passphrase");
|
||||
|
||||
when(encryptionService.encrypt("secret")).thenReturn("enc-secret");
|
||||
|
||||
ConnectionDto result = connectionService.create(request, 1L);
|
||||
|
||||
assertNotNull(result);
|
||||
ArgumentCaptor<Connection> captor = ArgumentCaptor.forClass(Connection.class);
|
||||
verify(connectionRepository).save(captor.capture());
|
||||
Connection saved = captor.getValue();
|
||||
|
||||
assertEquals(Connection.AuthType.PASSWORD, saved.getAuthType());
|
||||
assertEquals("enc-secret", saved.getEncryptedPassword());
|
||||
assertNull(saved.getEncryptedPrivateKey());
|
||||
assertNull(saved.getPassphrase());
|
||||
}
|
||||
|
||||
@Test
|
||||
void createPrivateKeyConnectionClearsPasswordCredential() {
|
||||
ConnectionCreateRequest request = new ConnectionCreateRequest();
|
||||
request.setName("prod");
|
||||
request.setHost("127.0.0.1");
|
||||
request.setUsername("root");
|
||||
request.setAuthType(Connection.AuthType.PRIVATE_KEY);
|
||||
request.setPassword("unused-password");
|
||||
request.setPrivateKey("private-key");
|
||||
request.setPassphrase("passphrase");
|
||||
|
||||
when(encryptionService.encrypt("private-key")).thenReturn("enc-key");
|
||||
when(encryptionService.encrypt("passphrase")).thenReturn("enc-passphrase");
|
||||
|
||||
ConnectionDto result = connectionService.create(request, 1L);
|
||||
|
||||
assertNotNull(result);
|
||||
ArgumentCaptor<Connection> captor = ArgumentCaptor.forClass(Connection.class);
|
||||
verify(connectionRepository).save(captor.capture());
|
||||
Connection saved = captor.getValue();
|
||||
|
||||
assertEquals(Connection.AuthType.PRIVATE_KEY, saved.getAuthType());
|
||||
assertEquals("enc-key", saved.getEncryptedPrivateKey());
|
||||
assertEquals("enc-passphrase", saved.getPassphrase());
|
||||
assertNull(saved.getEncryptedPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateSwitchToPrivateKeyClearsPasswordCredential() {
|
||||
Connection existing = new Connection();
|
||||
existing.setId(10L);
|
||||
existing.setUserId(1L);
|
||||
existing.setAuthType(Connection.AuthType.PASSWORD);
|
||||
existing.setEncryptedPassword("old-password");
|
||||
|
||||
ConnectionCreateRequest request = new ConnectionCreateRequest();
|
||||
request.setAuthType(Connection.AuthType.PRIVATE_KEY);
|
||||
request.setPrivateKey("new-key");
|
||||
request.setPassphrase("new-passphrase");
|
||||
|
||||
when(connectionRepository.findById(10L)).thenReturn(Optional.of(existing));
|
||||
when(encryptionService.encrypt("new-key")).thenReturn("enc-new-key");
|
||||
when(encryptionService.encrypt("new-passphrase")).thenReturn("enc-new-passphrase");
|
||||
|
||||
ConnectionDto result = connectionService.update(10L, request, 1L);
|
||||
|
||||
assertNotNull(result);
|
||||
ArgumentCaptor<Connection> captor = ArgumentCaptor.forClass(Connection.class);
|
||||
verify(connectionRepository).save(captor.capture());
|
||||
Connection saved = captor.getValue();
|
||||
|
||||
assertEquals(Connection.AuthType.PRIVATE_KEY, saved.getAuthType());
|
||||
assertEquals("enc-new-key", saved.getEncryptedPrivateKey());
|
||||
assertEquals("enc-new-passphrase", saved.getPassphrase());
|
||||
assertNull(saved.getEncryptedPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateSwitchToPasswordClearsPrivateKeyCredentials() {
|
||||
Connection existing = new Connection();
|
||||
existing.setId(20L);
|
||||
existing.setUserId(1L);
|
||||
existing.setAuthType(Connection.AuthType.PRIVATE_KEY);
|
||||
existing.setEncryptedPrivateKey("old-key");
|
||||
existing.setPassphrase("old-passphrase");
|
||||
|
||||
ConnectionCreateRequest request = new ConnectionCreateRequest();
|
||||
request.setAuthType(Connection.AuthType.PASSWORD);
|
||||
request.setPassword("new-password");
|
||||
|
||||
when(connectionRepository.findById(20L)).thenReturn(Optional.of(existing));
|
||||
when(encryptionService.encrypt("new-password")).thenReturn("enc-new-password");
|
||||
|
||||
ConnectionDto result = connectionService.update(20L, request, 1L);
|
||||
|
||||
assertNotNull(result);
|
||||
ArgumentCaptor<Connection> captor = ArgumentCaptor.forClass(Connection.class);
|
||||
verify(connectionRepository).save(captor.capture());
|
||||
Connection saved = captor.getValue();
|
||||
|
||||
assertEquals(Connection.AuthType.PASSWORD, saved.getAuthType());
|
||||
assertEquals("enc-new-password", saved.getEncryptedPassword());
|
||||
assertNull(saved.getEncryptedPrivateKey());
|
||||
assertNull(saved.getPassphrase());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user