]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7210 WS user_tokens/search a user can search its own token 720/head 5.4-M8
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 18 Jan 2016 08:43:40 +0000 (09:43 +0100)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 18 Jan 2016 17:35:44 +0000 (18:35 +0100)
server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/TokenPermissionsValidator.java
server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/UserTokensWsTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/usertoken/SearchWsRequest.java

index d43705f3421b6d4da3880926cfdfc9405ef423d6..c44f5cc9604a0d081b7866e69114259b63e7b5d7 100644 (file)
@@ -24,7 +24,6 @@ import java.util.List;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.user.UserTokenDto;
@@ -50,15 +49,14 @@ public class SearchAction implements UserTokensWsAction {
   @Override
   public void define(WebService.NewController context) {
     WebService.NewAction action = context.createAction(ACTION_SEARCH)
-      .setDescription("List the access tokens of a user. <br />" +
-        "The login must exist and active.<br />" +
-        "It requires administration permissions.")
+      .setDescription("List the access tokens of a user.<br>" +
+        "The login must exist and active.<br>" +
+        "If the login is set, it requires administration permissions. Otherwise, a token is generated for the authenticated user.")
       .setResponseExample(getClass().getResource("search-example.json"))
       .setSince("5.3")
       .setHandler(this);
 
     action.createParam(PARAM_LOGIN)
-      .setRequired(true)
       .setDescription("User login")
       .setExampleValue("g.hopper");
   }
@@ -70,7 +68,7 @@ public class SearchAction implements UserTokensWsAction {
   }
 
   private SearchWsResponse doHandle(SearchWsRequest request) {
-    userSession.checkLoggedIn().checkPermission(GlobalPermissions.SYSTEM_ADMIN);
+    TokenPermissionsValidator.validate(userSession, request.getLogin());
 
     DbSession dbSession = dbClient.openSession(false);
     try {
@@ -83,9 +81,12 @@ public class SearchAction implements UserTokensWsAction {
     }
   }
 
-  private static SearchWsRequest toSearchWsRequest(Request request) {
-    return new SearchWsRequest()
-      .setLogin(request.mandatoryParam(PARAM_LOGIN));
+  private SearchWsRequest toSearchWsRequest(Request request) {
+    SearchWsRequest searchWsRequest = new SearchWsRequest().setLogin(request.param(PARAM_LOGIN));
+    if (searchWsRequest.getLogin() == null) {
+      searchWsRequest.setLogin(userSession.getLogin());
+    }
+    return searchWsRequest;
   }
 
   private static SearchWsResponse buildResponse(String login, List<UserTokenDto> userTokensDto) {
index 8be1c2a32e33fb70da767cc92db2575770446a88..ff28731c2c708810c79bc5a89e707bf84d7c53b4 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.usertoken.ws;
 
+import javax.annotation.Nullable;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.server.user.UserSession;
 
@@ -29,9 +30,9 @@ class TokenPermissionsValidator {
     // prevent instantiation
   }
 
-  static void validate(UserSession userSession, String requestLogin) {
+  static void validate(UserSession userSession, @Nullable String requestLogin) {
     if (userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN)
-      || requestLogin.equals(userSession.getLogin())) {
+      || (requestLogin != null && requestLogin.equals(userSession.getLogin()))) {
       return;
     }
 
index 3a532274fd17dd4b054a60a4a8b0485d73830297..82a9918e60b9c2a7ed57be52efbfff9d9f4cebfd 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.usertoken.ws;
 
 import com.google.common.base.Throwables;
 import java.io.IOException;
+import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -34,14 +35,15 @@ import org.sonar.db.DbTester;
 import org.sonar.db.user.UserDbTester;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
 import org.sonar.test.DbTests;
 import org.sonarqube.ws.MediaTypes;
 import org.sonarqube.ws.WsUserTokens.SearchWsResponse;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.db.user.UserTesting.newUserDto;
 import static org.sonar.db.user.UserTokenTesting.newUserToken;
 import static org.sonar.test.JsonAssert.assertJson;
@@ -51,7 +53,6 @@ import static org.sonarqube.ws.client.usertoken.UserTokensWsParameters.PARAM_LOG
 public class SearchActionTest {
   static final String GRACE_HOPPER = "grace.hopper";
   static final String ADA_LOVELACE = "ada.lovelace";
-  static final String TOKEN_NAME = "token-name";
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
@@ -91,6 +92,7 @@ public class SearchActionTest {
       .setName("Project scan on Travis")
       .setLogin(ADA_LOVELACE));
     dbSession.commit();
+
     String response = ws.newRequest()
       .setParam(PARAM_LOGIN, GRACE_HOPPER)
       .execute().getInput();
@@ -99,19 +101,25 @@ public class SearchActionTest {
   }
 
   @Test
-  public void fail_when_login_does_not_exist() {
-    expectedException.expect(NotFoundException.class);
-    expectedException.expectMessage("User with login 'unknown-login' not found");
+  public void a_user_can_search_its_own_token() {
+    userSession.login(GRACE_HOPPER).setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    dbClient.userTokenDao().insert(dbSession, newUserToken()
+      .setCreatedAt(1448523067221L)
+      .setName("Project scan on Travis")
+      .setLogin(GRACE_HOPPER));
+    db.commit();
 
-    newRequest("unknown-login");
+    SearchWsResponse response = newRequest(null);
+
+    assertThat(response.getUserTokensCount()).isEqualTo(1);
   }
 
   @Test
-  public void fail_when_not_logged_in() {
-    userSession.anonymous();
-    expectedException.expect(UnauthorizedException.class);
+  public void fail_when_login_does_not_exist() {
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage("User with login 'unknown-login' not found");
 
-    newRequest(GRACE_HOPPER);
+    newRequest("unknown-login");
   }
 
   @Test
@@ -122,11 +130,15 @@ public class SearchActionTest {
     newRequest(GRACE_HOPPER);
   }
 
-  private SearchWsResponse newRequest(String login) {
-    TestResponse response = ws.newRequest()
-      .setMediaType(MediaTypes.PROTOBUF)
-      .setParam(PARAM_LOGIN, login)
-      .execute();
+  private SearchWsResponse newRequest(@Nullable String login) {
+    TestRequest testRequest = ws.newRequest()
+      .setMediaType(MediaTypes.PROTOBUF);
+    if (login != null) {
+      testRequest.setParam(PARAM_LOGIN, login);
+    }
+
+    TestResponse response = testRequest.execute();
+
     try {
       return SearchWsResponse.parseFrom(response.getInputStream());
     } catch (IOException e) {
index ff8e819acb48c6f585db72d9305244498bb71f76..2ab34825658235938f6eb9dc5292fb7a488f523b 100644 (file)
@@ -79,6 +79,6 @@ public class UserTokensWsTest {
     assertThat(action).isNotNull();
     assertThat(action.since()).isEqualTo("5.3");
     assertThat(action.isPost()).isFalse();
-    assertThat(action.param("login").isRequired()).isTrue();
+    assertThat(action.param("login").isRequired()).isFalse();
   }
 }
index 4c69e9487de1694b3919c5570b4f4977de9d2d4e..3fd52b200ff509f730c37fe292f4e1279fc10cfe 100644 (file)
  */
 package org.sonarqube.ws.client.usertoken;
 
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
 public class SearchWsRequest {
   private String login;
 
+  @CheckForNull
   public String getLogin() {
     return login;
   }
 
-  public SearchWsRequest setLogin(String login) {
+  public SearchWsRequest setLogin(@Nullable String login) {
     this.login = login;
     return this;
   }