mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-22 06:26:56 +01:00
Add rest resource for api keys
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user