Add rest resource for api keys

This commit is contained in:
René Pfeuffer
2020-09-29 11:08:36 +02:00
parent 4129f55f27
commit 905fc4158a
18 changed files with 401 additions and 38 deletions

View File

@@ -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.v2.resources;
import com.github.sdorra.shiro.ShiroRule;
@@ -41,6 +41,8 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import sonia.scm.ContextEntry;
import sonia.scm.group.GroupCollector;
import sonia.scm.security.ApiKey;
import sonia.scm.security.ApiKeyService;
import sonia.scm.user.InvalidPasswordException;
import sonia.scm.user.User;
import sonia.scm.user.UserManager;
@@ -51,7 +53,10 @@ import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import static com.google.inject.util.Providers.of;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
@@ -87,8 +92,13 @@ public class MeResourceTest {
@Mock
private UserManager userManager;
@Mock
private ApiKeyService apiKeyService;
@InjectMocks
private MeDtoFactory meDtoFactory;
@InjectMocks
private ApiKeyToApiKeyDtoMapperImpl apiKeyMapper;
private ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
@@ -96,6 +106,8 @@ public class MeResourceTest {
private PasswordService passwordService;
private User originalUser;
private MockHttpResponse response = new MockHttpResponse();
@Before
public void prepareEnvironment() {
initMocks(this);
@@ -106,7 +118,9 @@ public class MeResourceTest {
when(groupCollector.collect("trillian")).thenReturn(ImmutableSet.of("group1", "group2"));
when(userManager.isTypeDefault(userCaptor.capture())).thenCallRealMethod();
when(userManager.getDefaultType()).thenReturn("xml");
MeResource meResource = new MeResource(meDtoFactory, userManager, passwordService);
ApiKeyCollectionToDtoMapper apiKeyCollectionMapper = new ApiKeyCollectionToDtoMapper(apiKeyMapper, resourceLinks);
ApiKeyResource apiKeyResource = new ApiKeyResource(apiKeyService, apiKeyCollectionMapper, apiKeyMapper);
MeResource meResource = new MeResource(meDtoFactory, userManager, passwordService, of(apiKeyResource));
when(uriInfo.getApiRestUri()).thenReturn(URI.create("/"));
when(scmPathInfoStore.get()).thenReturn(uriInfo);
dispatcher.addSingletonResource(meResource);
@@ -118,14 +132,14 @@ public class MeResourceTest {
MockHttpRequest request = MockHttpRequest.get("/" + MeResource.ME_PATH_V2);
request.accept(VndMediaType.ME);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(HttpServletResponse.SC_OK, response.getStatus());
assertTrue(response.getContentAsString().contains("\"name\":\"trillian\""));
assertTrue(response.getContentAsString().contains("\"self\":{\"href\":\"/v2/me/\"}"));
assertTrue(response.getContentAsString().contains("\"delete\":{\"href\":\"/v2/users/trillian\"}"));
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\"}");
}
private void applyUserToSubject(User user) {
@@ -149,7 +163,6 @@ public class MeResourceTest {
.put("/" + MeResource.ME_PATH_V2 + "password")
.contentType(VndMediaType.PASSWORD_CHANGE)
.content(content.getBytes());
MockHttpResponse response = new MockHttpResponse();
when(passwordService.encryptPassword(newPassword)).thenReturn(encryptedNewPassword);
when(passwordService.encryptPassword(oldPassword)).thenReturn(encryptedOldPassword);
@@ -174,7 +187,6 @@ public class MeResourceTest {
.put("/" + MeResource.ME_PATH_V2 + "password")
.contentType(VndMediaType.PASSWORD_CHANGE)
.content(content.getBytes());
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
@@ -190,7 +202,6 @@ public class MeResourceTest {
.put("/" + MeResource.ME_PATH_V2 + "password")
.contentType(VndMediaType.PASSWORD_CHANGE)
.content(content.getBytes());
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
@@ -206,7 +217,6 @@ public class MeResourceTest {
.put("/" + MeResource.ME_PATH_V2 + "password")
.contentType(VndMediaType.PASSWORD_CHANGE)
.content(content.getBytes());
MockHttpResponse response = new MockHttpResponse();
doThrow(new InvalidPasswordException(ContextEntry.ContextBuilder.entity("passwortChange", "-")))
.when(userManager).changePasswordForLoggedInUser(any(), any());
@@ -216,6 +226,33 @@ public class MeResourceTest {
assertEquals(HttpServletResponse.SC_BAD_REQUEST, response.getStatus());
}
@Test
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");
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\"}");
}
@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");
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\"}");
}
private User createDummyUser(String name) {
User user = new User();

View File

@@ -80,6 +80,8 @@ public class ResourceLinksMock {
lenient().when(resourceLinks.namespaceCollection()).thenReturn(new ResourceLinks.NamespaceCollectionLinks(pathInfo));
lenient().when(resourceLinks.namespacePermission()).thenReturn(new ResourceLinks.NamespacePermissionLinks(pathInfo));
lenient().when(resourceLinks.adminInfo()).thenReturn(new ResourceLinks.AdminInfoLinks(pathInfo));
lenient().when(resourceLinks.apiKeyCollection()).thenReturn(new ResourceLinks.ApiKeyCollectionLinks(pathInfo));
lenient().when(resourceLinks.apiKey()).thenReturn(new ResourceLinks.ApiKeyLinks(pathInfo));
return resourceLinks;
}

View File

@@ -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.v2.resources;
import com.github.sdorra.shiro.ShiroRule;

View File

@@ -49,12 +49,14 @@ import static org.mockito.Mockito.when;
class ApiKeyServiceTest {
int nextKey = 1;
int nextId = 1;
PasswordService passwordService = mock(PasswordService.class);
Supplier<String> keyGenerator = () -> Integer.toString(nextKey++);
Supplier<String> passphraseGenerator = () -> Integer.toString(nextKey++);
KeyGenerator keyGenerator = () -> Integer.toString(nextId++);
ConfigurationEntryStoreFactory storeFactory = new InMemoryConfigurationEntryStoreFactory();
ConfigurationEntryStore<ApiKeyCollection> store = storeFactory.withType(ApiKeyCollection.class).withName("apiKeys").build();
ApiKeyService service = new ApiKeyService(storeFactory, passwordService, keyGenerator);
ApiKeyService service = new ApiKeyService(storeFactory, passwordService, keyGenerator, passphraseGenerator);
@BeforeEach
@@ -128,7 +130,7 @@ class ApiKeyServiceTest {
assertThat(service.check("dent", "1", firstKey)).contains("READ");
assertThat(service.check("dent", "2", secondKey)).contains("WRITE");
assertThat(service.getKeys()).extracting("name").contains("1", "2");
assertThat(service.getKeys()).extracting("id").contains("1", "2");
}
@Test