diff --git a/scm-webapp/src/main/java/sonia/scm/api/NotSupportedExceptionMapper.java b/scm-webapp/src/main/java/sonia/scm/api/NotSupportedExceptionMapper.java index 0fa8113c6b..9e10b89669 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/NotSupportedExceptionMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/NotSupportedExceptionMapper.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.api; import org.slf4j.Logger; @@ -42,7 +42,7 @@ public class NotSupportedExceptionMapper implements ExceptionMapper getKeys() { - return store.get(currentUser()).getKeys().stream().map(ApiKey::new).collect(toList()); + return store.getOptional(currentUser()) + .map(ApiKeyCollection::getKeys) + .map(Collection::stream) + .orElse(Stream.empty()) + .map(ApiKey::new) + .collect(toList()); } private String currentUser() { diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java index 63b6092d35..607bba6712 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MeResourceTest.java @@ -64,6 +64,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @@ -139,7 +140,7 @@ public class MeResourceTest { assertThat(response.getContentAsString()).contains("\"name\":\"trillian\""); assertThat(response.getContentAsString()).contains("\"self\":{\"href\":\"/v2/me/\"}"); assertThat(response.getContentAsString()).contains("\"delete\":{\"href\":\"/v2/users/trillian\"}"); - assertThat(response.getContentAsString()).contains("\"apiKeys\":{\"href\":\"/v2/me/apiKeys\"}"); + assertThat(response.getContentAsString()).contains("\"apiKeys\":{\"href\":\"/v2/me/api-keys\"}"); } private void applyUserToSubject(User user) { @@ -230,29 +231,30 @@ public class MeResourceTest { public void shouldGetAllApiKeys() throws URISyntaxException, UnsupportedEncodingException { when(apiKeyService.getKeys()).thenReturn(Arrays.asList(new ApiKey("1", "key 1", "READ"), new ApiKey("2", "key 2", "WRITE"))); - MockHttpRequest request = MockHttpRequest.get("/" + MeResource.ME_PATH_V2 + "apiKeys"); + MockHttpRequest request = MockHttpRequest.get("/" + MeResource.ME_PATH_V2 + "api-keys"); dispatcher.invoke(request, response); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); assertThat(response.getContentAsString()).contains("\"displayName\":\"key 1\",\"role\":\"READ\""); assertThat(response.getContentAsString()).contains("\"displayName\":\"key 2\",\"role\":\"WRITE\""); - assertThat(response.getContentAsString()).contains("\"self\":{\"href\":\"/v2/me/apiKeys\"}"); - assertThat(response.getContentAsString()).contains("\"create\":{\"href\":\"/v2/me/apiKeys\"}"); + assertThat(response.getContentAsString()).contains("\"self\":{\"href\":\"/v2/me/api-keys\"}"); + assertThat(response.getContentAsString()).contains("\"create\":{\"href\":\"/v2/me/api-keys\"}"); } @Test public void shouldGetSingleApiKey() throws URISyntaxException, UnsupportedEncodingException { when(apiKeyService.getKeys()).thenReturn(Arrays.asList(new ApiKey("1", "key 1", "READ"), new ApiKey("2", "key 2", "WRITE"))); - MockHttpRequest request = MockHttpRequest.get("/" + MeResource.ME_PATH_V2 + "apiKeys/1"); + MockHttpRequest request = MockHttpRequest.get("/" + MeResource.ME_PATH_V2 + "api-keys/1"); dispatcher.invoke(request, response); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); assertThat(response.getContentAsString()).contains("\"displayName\":\"key 1\""); assertThat(response.getContentAsString()).contains("\"role\":\"READ\""); - assertThat(response.getContentAsString()).contains("\"self\":{\"href\":\"/v2/me/apiKeys/1\"}"); + assertThat(response.getContentAsString()).contains("\"self\":{\"href\":\"/v2/me/api-keys/1\"}"); + assertThat(response.getContentAsString()).contains("\"delete\":{\"href\":\"/v2/me/api-keys/1\"}"); } @Test @@ -260,7 +262,7 @@ public class MeResourceTest { when(apiKeyService.createNewKey("guide", "READ")).thenReturn(new ApiKeyService.CreationResult("abc", "1")); final MockHttpRequest request = MockHttpRequest - .post("/" + MeResource.ME_PATH_V2 + "apiKeys/") + .post("/" + MeResource.ME_PATH_V2 + "api-keys/") .contentType(VndMediaType.API_KEY) .content("{\"displayName\":\"guide\",\"role\":\"READ\"}".getBytes()); @@ -268,7 +270,16 @@ public class MeResourceTest { assertThat(response.getStatus()).isEqualTo(201); assertThat(response.getContentAsString()).isEqualTo("abc"); - assertThat(response.getOutputHeaders().get("Location")).containsExactly(URI.create("/v2/me/apiKeys/1")); + assertThat(response.getOutputHeaders().get("Location")).containsExactly(URI.create("/v2/me/api-keys/1")); + } + + @Test + public void shouldDeleteExistingApiKey() throws URISyntaxException { + MockHttpRequest request = MockHttpRequest.delete("/" + MeResource.ME_PATH_V2 + "api-keys/1"); + dispatcher.invoke(request, response); + + assertThat(response.getStatus()).isEqualTo(204); + verify(apiKeyService).remove("1"); } private User createDummyUser(String name) { diff --git a/scm-webapp/src/test/java/sonia/scm/security/ApiKeyServiceTest.java b/scm-webapp/src/test/java/sonia/scm/security/ApiKeyServiceTest.java index 4f5a122a8c..ebd29788d9 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/ApiKeyServiceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/ApiKeyServiceTest.java @@ -108,6 +108,11 @@ class ApiKeyServiceTest { assertThat(role).contains("READ"); } + @Test + void shouldHandleNewUser() { + assertThat(service.getKeys()).isEmpty(); + } + @Test void shouldNotReturnAnythingWithWrongKey() { service.createNewKey("1", "READ"); @@ -135,8 +140,8 @@ class ApiKeyServiceTest { @Test void shouldRemoveKey() { - String firstKey = service.createNewKey("1", "READ").getToken(); - String secondKey = service.createNewKey("2", "WRITE").getToken(); + String firstKey = service.createNewKey("first", "READ").getToken(); + String secondKey = service.createNewKey("second", "WRITE").getToken(); service.remove("1");