Finish functionality
This commit is contained in:
parent
b6af1c9792
commit
89d5282b0f
9 changed files with 583 additions and 133 deletions
|
|
@ -36,7 +36,7 @@ class SecureCompletionClientE2ETest {
|
|||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("E2E: Generate keys, save to disk, load in new client, validate")
|
||||
void e2e_fullLifecycle_generateSaveLoadValidate() {
|
||||
void e2e_fullLifecycle_generateSaveLoadValidate() throws Exception {
|
||||
// Step 1: Generate keys and save to disk
|
||||
SecureCompletionClient generateClient = new SecureCompletionClient(BASE_URL, false, true, 2);
|
||||
generateClient.generateKeys(true, keyDir.getAbsolutePath(), TEST_PASSWORD);
|
||||
|
|
@ -77,7 +77,7 @@ class SecureCompletionClientE2ETest {
|
|||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("E2E: Generate plaintext keys, load, and validate")
|
||||
void e2e_plaintextKeys_generateLoadValidate() {
|
||||
void e2e_plaintextKeys_generateLoadValidate() throws Exception {
|
||||
// Generate plaintext keys (no password)
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(true, keyDir.getAbsolutePath(), null);
|
||||
|
|
@ -296,7 +296,7 @@ class SecureCompletionClientE2ETest {
|
|||
|
||||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("E2E: Encrypted key file is unreadable without password")
|
||||
@DisplayName("E2E: Encrypted key file throws SecurityError without correct password")
|
||||
void e2e_encryptedKey_unreadableWithoutPassword() throws Exception {
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(true, keyDir.getAbsolutePath(), TEST_PASSWORD);
|
||||
|
|
@ -308,17 +308,19 @@ class SecureCompletionClientE2ETest {
|
|||
assertFalse(encryptedContent.contains("BEGIN PRIVATE KEY"),
|
||||
"Encrypted file should not contain PEM header");
|
||||
|
||||
// Try loading with wrong password - should not throw
|
||||
// Try loading with wrong password - should throw SecurityError
|
||||
SecureCompletionClient loadClient = new SecureCompletionClient();
|
||||
assertDoesNotThrow(() ->
|
||||
SecurityError error = assertThrows(SecurityError.class, () ->
|
||||
loadClient.loadKeys(privateKeyFile.getAbsolutePath(), null, "wrong-password"),
|
||||
"Wrong password should be handled gracefully"
|
||||
"Wrong password should throw SecurityError"
|
||||
);
|
||||
assertTrue(error.getMessage().contains("decrypt") || error.getMessage().contains("password"),
|
||||
"Error message should mention decryption or password");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("E2E: Generate keys without saving produces in-memory keys")
|
||||
void e2e_generateKeys_noSave_producesInMemoryKeys() {
|
||||
void e2e_generateKeys_noSave_producesInMemoryKeys() throws SecurityError {
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(false);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class SecureCompletionClientTest {
|
|||
|
||||
@Test
|
||||
@DisplayName("generateKeys should create 4096-bit RSA key pair")
|
||||
void generateKeys_shouldCreateValidKeyPair() {
|
||||
void generateKeys_shouldCreateValidKeyPair() throws SecurityError {
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(false);
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ class SecureCompletionClientTest {
|
|||
|
||||
@Test
|
||||
@DisplayName("generateKeys should create unique keys on each call")
|
||||
void generateKeys_shouldProduceUniqueKeys() {
|
||||
void generateKeys_shouldProduceUniqueKeys() throws SecurityError {
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(false);
|
||||
PrivateKey firstKey = client.getPrivateKey();
|
||||
|
|
@ -76,7 +76,7 @@ class SecureCompletionClientTest {
|
|||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("generateKeys with saveToFile=true should create key files")
|
||||
void generateKeys_withSaveToFile_shouldCreateKeyFiles(@TempDir Path tempDir) {
|
||||
void generateKeys_withSaveToFile_shouldCreateKeyFiles(@TempDir Path tempDir) throws SecurityError {
|
||||
File keyDir = tempDir.toFile();
|
||||
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
|
|
@ -112,7 +112,7 @@ class SecureCompletionClientTest {
|
|||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("generateKeys should not overwrite existing key files")
|
||||
void generateKeys_shouldNotOverwriteExistingKeys(@TempDir Path tempDir) {
|
||||
void generateKeys_shouldNotOverwriteExistingKeys(@TempDir Path tempDir) throws SecurityError {
|
||||
File keyDir = tempDir.toFile();
|
||||
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
|
|
@ -129,10 +129,10 @@ class SecureCompletionClientTest {
|
|||
|
||||
// ── Key Loading Tests ─────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("loadKeys should load plaintext private key from file")
|
||||
void loadKeys_plaintext_shouldLoadPrivateKey(@TempDir Path tempDir) {
|
||||
void loadKeys_plaintext_shouldLoadPrivateKey(@TempDir Path tempDir) throws Exception {
|
||||
File keyDir = tempDir.toFile();
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(true, keyDir.getAbsolutePath(), null);
|
||||
|
|
@ -151,10 +151,10 @@ class SecureCompletionClientTest {
|
|||
"Loaded key should have same size as original");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("loadKeys should load encrypted private key with correct password")
|
||||
void loadKeys_encrypted_correctPassword_shouldLoadPrivateKey(@TempDir Path tempDir) {
|
||||
void loadKeys_encrypted_correctPassword_shouldLoadPrivateKey(@TempDir Path tempDir) throws Exception {
|
||||
File keyDir = tempDir.toFile();
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(true, keyDir.getAbsolutePath(), TEST_PASSWORD);
|
||||
|
|
@ -176,30 +176,33 @@ class SecureCompletionClientTest {
|
|||
|
||||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("loadKeys should handle wrong password gracefully")
|
||||
void loadKeys_encrypted_wrongPassword_shouldHandleGracefully(@TempDir Path tempDir) {
|
||||
@DisplayName("loadKeys should throw SecurityError for wrong password")
|
||||
void loadKeys_encrypted_wrongPassword_shouldThrowSecurityError(@TempDir Path tempDir) throws SecurityError {
|
||||
File keyDir = tempDir.toFile();
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(true, keyDir.getAbsolutePath(), TEST_PASSWORD);
|
||||
|
||||
SecureCompletionClient loadClient = new SecureCompletionClient();
|
||||
|
||||
assertDoesNotThrow(() ->
|
||||
SecurityError error = assertThrows(SecurityError.class, () ->
|
||||
loadClient.loadKeys(
|
||||
new File(keyDir, Constants.DEFAULT_PRIVATE_KEY_FILE).getAbsolutePath(),
|
||||
null,
|
||||
"wrong-password"
|
||||
),
|
||||
"Wrong password should not throw exception"
|
||||
"Wrong password should throw SecurityError"
|
||||
);
|
||||
|
||||
assertTrue(error.getMessage().contains("decrypt") || error.getMessage().contains("password"),
|
||||
"Error message should mention decryption or password");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("loadKeys should throw exception for non-existent file")
|
||||
void loadKeys_nonExistentFile_shouldThrowException() {
|
||||
void loadKeys_nonExistentFile_shouldThrowException() {
|
||||
SecureCompletionClient loadClient = new SecureCompletionClient();
|
||||
|
||||
RuntimeException error = assertThrows(RuntimeException.class, () ->
|
||||
SecurityError error = assertThrows(SecurityError.class, () ->
|
||||
loadClient.loadKeys("/non/existent/path/private_key.pem", null, null));
|
||||
|
||||
assertTrue(error.getMessage().contains("not found"),
|
||||
|
|
@ -210,7 +213,7 @@ class SecureCompletionClientTest {
|
|||
|
||||
@Test
|
||||
@DisplayName("validateRsaKey should accept valid 4096-bit key")
|
||||
void validateRsaKey_validKey_shouldPass() {
|
||||
void validateRsaKey_validKey_shouldPass() throws SecurityError {
|
||||
SecureCompletionClient client = new SecureCompletionClient();
|
||||
client.generateKeys(false);
|
||||
PrivateKey key = client.getPrivateKey();
|
||||
|
|
@ -264,7 +267,7 @@ class SecureCompletionClientTest {
|
|||
@Test
|
||||
@Execution(ExecutionMode.SAME_THREAD)
|
||||
@DisplayName("Full roundtrip: generate, save, load should produce same key")
|
||||
void roundtrip_generateSaveLoad_shouldProduceSameKey(@TempDir Path tempDir) {
|
||||
void roundtrip_generateSaveLoad_shouldProduceSameKey(@TempDir Path tempDir) throws Exception {
|
||||
File keyDir = tempDir.toFile();
|
||||
|
||||
// Generate and save
|
||||
|
|
@ -407,10 +410,6 @@ class SecureCompletionClientTest {
|
|||
tempClient.generateKeys(false);
|
||||
PrivateKey originalKey = tempClient.getPrivateKey();
|
||||
|
||||
String pem = "-----BEGIN PRIVATE KEY-----\n " +
|
||||
originalKey.getEncoded().length + "lines\n" +
|
||||
"-----END PRIVATE KEY-----";
|
||||
|
||||
String formattedPem = ai.nomyo.util.PEMConverter.toPEM(originalKey.getEncoded(), true);
|
||||
String pemWithWhitespace = formattedPem.replace("\n", "\n ");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue