Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/openapi/paths/admin_v1_apps_id_api-key.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,26 @@ get:
description: Not Found
security:
- admin-api: []

delete:
tags:
- Applications
summary: Delete an application's API key
description: Deletes the API key for a specific application by its ID.
operationId: deleteApiKey
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'204':
description: No Content
'401':
description: Unauthorized
'404':
description: Not Found
security:
- admin-api: []
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@
import com.helioauth.passkeys.api.generated.models.ApplicationApiKey;
import com.helioauth.passkeys.api.generated.models.EditApplicationRequest;
import com.helioauth.passkeys.api.service.ClientApplicationService;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import jakarta.validation.Valid;
import java.net.URI;
import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -80,4 +79,9 @@ public ResponseEntity<Void> delete(@PathVariable UUID id) {

return deleted ? ResponseEntity.noContent().build() : ResponseEntity.notFound().build();
}
}

public ResponseEntity<Void> deleteApiKey(@PathVariable UUID id) {
boolean deleted = clientApplicationService.deleteApiKey(id);
return deleted ? ResponseEntity.noContent().build() : ResponseEntity.notFound().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.helioauth.passkeys.api.service;

import com.helioauth.passkeys.api.domain.ClientApplication;
import com.helioauth.passkeys.api.domain.ClientApplicationRepository;
import com.helioauth.passkeys.api.generated.models.AddApplicationRequest;
import com.helioauth.passkeys.api.generated.models.Application;
Expand Down Expand Up @@ -89,6 +88,17 @@ public boolean delete(UUID id) {
return false;
}

@Transactional
public boolean deleteApiKey(UUID id) {
return repository.findById(id)
.map(application -> {
application.setApiKey(null);
repository.save(application);
return true;
})
.orElse(false);
}

private String generateApiKey() {
byte[] buffer = new byte[16];
random.nextBytes(buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -197,4 +200,47 @@ public void getClientApplicationApiKeyTest() {
assertTrue(result.isPresent());
assertEquals(apiKey, result.get().getApiKey());
}
}

@Test
public void testDeleteApiKey_success() {
// Setup
UUID appId = UUID.randomUUID();
ClientApplication application = ClientApplication.builder()
.id(appId)
.name("Test App")
.apiKey("someapikey")
.relyingPartyHostname("localhost")
.createdAt(Instant.now())
.updatedAt(Instant.now())
.build();

when(repository.findById(appId)).thenReturn(Optional.of(application));
// Mock repository.save to return the application object after modifying it in the service
when(repository.save(any(ClientApplication.class))).thenReturn(application);

// Execute
boolean result = service.deleteApiKey(appId);

// Validate
assertTrue(result);
assertNull(application.getApiKey()); // Verify the API key was set to null
verify(repository, times(1)).findById(appId);
verify(repository, times(1)).save(application); // Verify save was called with the modified object
}

@Test
public void testDeleteApiKey_notFound() {
// Setup
UUID appId = UUID.randomUUID();

when(repository.findById(appId)).thenReturn(Optional.empty());

// Execute
boolean result = service.deleteApiKey(appId);

// Validate
assertFalse(result);
verify(repository, times(1)).findById(appId);
verify(repository, never()).save(any(ClientApplication.class)); // Verify save was not called
}
}