From 3b981515d02d5a0354ec0d7dcec52ff4d8135d06 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Mon, 18 Jan 2016 09:37:27 +0100 Subject: [PATCH] SONAR-7209 WS user_tokens/revoke a user can delete its own tokens --- .../server/usertoken/ws/RevokeAction.java | 16 +++++---- .../server/usertoken/ws/RevokeActionTest.java | 33 +++++++++++-------- .../server/usertoken/ws/UserTokensWsTest.java | 2 +- .../ws/client/usertoken/RevokeWsRequest.java | 6 +++- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java index dd36e067c6d..2fdfefc23ed 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java @@ -27,7 +27,6 @@ import org.sonar.db.DbSession; import org.sonar.server.user.UserSession; import org.sonarqube.ws.client.usertoken.RevokeWsRequest; -import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; import static org.sonarqube.ws.client.usertoken.UserTokensWsParameters.ACTION_REVOKE; import static org.sonarqube.ws.client.usertoken.UserTokensWsParameters.PARAM_LOGIN; import static org.sonarqube.ws.client.usertoken.UserTokensWsParameters.PARAM_NAME; @@ -45,13 +44,12 @@ public class RevokeAction implements UserTokensWsAction { public void define(WebService.NewController context) { WebService.NewAction action = context.createAction(ACTION_REVOKE) .setDescription("Revoke a user access token.
"+ - "It requires administration permissions.") + "If the login is set, it requires administration permissions. Otherwise, a token is generated for the authenticated user.") .setSince("5.3") .setPost(true) .setHandler(this); action.createParam(PARAM_LOGIN) - .setRequired(true) .setDescription("User login") .setExampleValue("g.hopper"); @@ -68,7 +66,7 @@ public class RevokeAction implements UserTokensWsAction { } private void doHandle(RevokeWsRequest request) { - userSession.checkLoggedIn().checkPermission(SYSTEM_ADMIN); + TokenPermissionsValidator.validate(userSession, request.getLogin()); DbSession dbSession = dbClient.openSession(false); try { @@ -79,9 +77,13 @@ public class RevokeAction implements UserTokensWsAction { } } - private static RevokeWsRequest toRevokeWsRequest(Request request) { - return new RevokeWsRequest() - .setLogin(request.mandatoryParam(PARAM_LOGIN)) + private RevokeWsRequest toRevokeWsRequest(Request request) { + RevokeWsRequest revokeWsRequest = new RevokeWsRequest() + .setLogin(request.param(PARAM_LOGIN)) .setName(request.mandatoryParam(PARAM_NAME)); + if (revokeWsRequest.getLogin() == null) { + revokeWsRequest.setLogin(userSession.getLogin()); + } + return revokeWsRequest; } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/RevokeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/RevokeActionTest.java index b93da65dc9b..05744c22d32 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/RevokeActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/RevokeActionTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.usertoken.ws; +import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -31,8 +32,8 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.user.UserTokenDto; import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import org.sonar.test.DbTests; @@ -47,7 +48,6 @@ public class RevokeActionTest { static final String ADA_LOVELACE = "ada.lovelace"; static final String TOKEN_NAME = "token-name"; - @Rule public DbTester db = DbTester.create(System2.INSTANCE); DbClient dbClient = db.getDbClient(); @@ -84,19 +84,21 @@ public class RevokeActionTest { } @Test - public void does_not_fail_when_incorrect_login_or_name() { - insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName(TOKEN_NAME)); + public void user_can_delete_its_own_tokens() { + userSession.login(GRACE_HOPPER).setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName("token-to-delete")); - newRequest(ADA_LOVELACE, "another-token-name"); + String response = newRequest(null, "token-to-delete"); + + assertThat(response).isEmpty(); + assertThat(dbClient.userTokenDao().selectByLogin(dbSession, GRACE_HOPPER)).isEmpty(); } @Test - public void fail_if_not_logged_in() { - userSession.anonymous(); + public void does_not_fail_when_incorrect_login_or_name() { insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName(TOKEN_NAME)); - expectedException.expect(UnauthorizedException.class); - newRequest(GRACE_HOPPER, TOKEN_NAME); + newRequest(ADA_LOVELACE, "another-token-name"); } @Test @@ -108,11 +110,14 @@ public class RevokeActionTest { newRequest(GRACE_HOPPER, TOKEN_NAME); } - private String newRequest(String login, String name) { - return ws.newRequest() - .setParam(PARAM_LOGIN, login) - .setParam(PARAM_NAME, name) - .execute().getInput(); + private String newRequest(@Nullable String login, String name) { + TestRequest testRequest = ws.newRequest() + .setParam(PARAM_NAME, name); + if (login != null) { + testRequest.setParam(PARAM_LOGIN, login); + } + + return testRequest.execute().getInput(); } private void insertUserToken(UserTokenDto userToken) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/UserTokensWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/UserTokensWsTest.java index 86d40f98edb..ff8e819acb4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/UserTokensWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/UserTokensWsTest.java @@ -68,7 +68,7 @@ public class UserTokensWsTest { assertThat(action).isNotNull(); assertThat(action.since()).isEqualTo("5.3"); assertThat(action.isPost()).isTrue(); - assertThat(action.param("login").isRequired()).isTrue(); + assertThat(action.param("login").isRequired()).isFalse(); assertThat(action.param("name").isRequired()).isTrue(); } diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/usertoken/RevokeWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/usertoken/RevokeWsRequest.java index 8459ab277ea..65344ce3a4e 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/usertoken/RevokeWsRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/usertoken/RevokeWsRequest.java @@ -19,15 +19,19 @@ */ package org.sonarqube.ws.client.usertoken; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + public class RevokeWsRequest { private String login; private String name; + @CheckForNull public String getLogin() { return login; } - public RevokeWsRequest setLogin(String login) { + public RevokeWsRequest setLogin(@Nullable String login) { this.login = login; return this; } -- 2.39.5