aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-11-25 09:41:19 +0100
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-11-26 14:12:36 +0100
commit93e81b2c3c3a4ebc644833cf4b364af800e808de (patch)
tree862b63f1d6c958636f4290e3fe77a9a23cd28a22 /server
parent1209d703eeae8130f87ebbe15306fd44e4675eb4 (diff)
downloadsonarqube-93e81b2c3c3a4ebc644833cf4b364af800e808de.tar.gz
sonarqube-93e81b2c3c3a4ebc644833cf4b364af800e808de.zip
SONAR-7042 WS user_tokens/revoke revoke an access token
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usertoken/UserTokenModule.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java88
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/GenerateActionTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/RevokeActionTest.java123
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/UserTokensWsTest.java14
6 files changed, 228 insertions, 3 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usertoken/UserTokenModule.java b/server/sonar-server/src/main/java/org/sonar/server/usertoken/UserTokenModule.java
index 2fd1753fe2c..5583e636ddd 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usertoken/UserTokenModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/UserTokenModule.java
@@ -22,6 +22,7 @@ package org.sonar.server.usertoken;
import org.sonar.core.platform.Module;
import org.sonar.server.usertoken.ws.GenerateAction;
+import org.sonar.server.usertoken.ws.RevokeAction;
import org.sonar.server.usertoken.ws.UserTokensWs;
public class UserTokenModule extends Module {
@@ -30,6 +31,7 @@ public class UserTokenModule extends Module {
add(
UserTokensWs.class,
GenerateAction.class,
+ RevokeAction.class,
UserTokenAuthenticator.class,
TokenGeneratorImpl.class);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java
index 7ed59918eda..300f729faa2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java
@@ -50,7 +50,7 @@ public class GenerateAction implements UserTokensWsAction {
private final System2 system;
private final TokenGenerator tokenGenerator;
- public GenerateAction(UserSession userSession, DbClient dbClient, System2 system, TokenGenerator tokenGenerator) {
+ public GenerateAction(DbClient dbClient, UserSession userSession, System2 system, TokenGenerator tokenGenerator) {
this.userSession = userSession;
this.dbClient = dbClient;
this.system = system;
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
new file mode 100644
index 00000000000..32dece255cb
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/usertoken/ws/RevokeAction.java
@@ -0,0 +1,88 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.usertoken.ws;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+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;
+
+public class RevokeAction implements UserTokensWsAction {
+ private final DbClient dbClient;
+ private final UserSession userSession;
+
+ public RevokeAction(DbClient dbClient, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction(ACTION_REVOKE)
+ .setDescription("Revoke a user access token. <br/>"+
+ "It requires administration permissions.")
+ .setSince("5.3")
+ .setPost(true)
+ .setHandler(this);
+
+ action.createParam(PARAM_LOGIN)
+ .setRequired(true)
+ .setDescription("User login")
+ .setExampleValue("g.hopper");
+
+ action.createParam(PARAM_NAME)
+ .setRequired(true)
+ .setDescription("Token name")
+ .setExampleValue("Project scan on Travis");
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ doHandle(toRevokeWsRequest(request));
+ response.noContent();
+ }
+
+ private void doHandle(RevokeWsRequest request) {
+ userSession.checkLoggedIn().checkGlobalPermission(SYSTEM_ADMIN);
+
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ dbClient.userTokenDao().deleteByLoginAndName(dbSession, request.getLogin(), request.getName());
+ dbSession.commit();
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+ }
+
+ private static RevokeWsRequest toRevokeWsRequest(Request request) {
+ return new RevokeWsRequest()
+ .setLogin(request.mandatoryParam(PARAM_LOGIN))
+ .setName(request.mandatoryParam(PARAM_NAME));
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/GenerateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/GenerateActionTest.java
index a4190e479ef..e0b0e11ca9b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/GenerateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/GenerateActionTest.java
@@ -79,7 +79,7 @@ public class GenerateActionTest {
userDb.insertUser(newUserDto().setLogin(ADA_LOVELACE));
ws = new WsActionTester(
- new GenerateAction(userSession, db.getDbClient(), System2.INSTANCE, tokenGenerator));
+ new GenerateAction(db.getDbClient(), userSession, System2.INSTANCE, tokenGenerator));
}
@Test
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
new file mode 100644
index 00000000000..e9e0995338c
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/usertoken/ws/RevokeActionTest.java
@@ -0,0 +1,123 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.usertoken.ws;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.DbClient;
+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.WsActionTester;
+import org.sonar.test.DbTests;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.user.UserTokenTesting.newUserToken;
+import static org.sonarqube.ws.client.usertoken.UserTokensWsParameters.PARAM_LOGIN;
+import static org.sonarqube.ws.client.usertoken.UserTokensWsParameters.PARAM_NAME;
+
+@Category(DbTests.class)
+public class RevokeActionTest {
+ static final String GRACE_HOPPER = "grace.hopper";
+ 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();
+ DbSession dbSession = db.getSession();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ WsActionTester ws;
+
+ @Before
+ public void setUp() {
+ userSession
+ .login()
+ .setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+
+ ws = new WsActionTester(
+ new RevokeAction(dbClient, userSession));
+ }
+
+ @Test
+ public void delete_token_in_db() {
+ insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName("token-to-delete"));
+ insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName("token-to-keep-1"));
+ insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName("token-to-keep-2"));
+ insertUserToken(newUserToken().setLogin(ADA_LOVELACE).setName("token-to-delete"));
+
+ String response = newRequest(GRACE_HOPPER, "token-to-delete");
+
+ assertThat(response).isEmpty();
+ assertThat(dbClient.userTokenDao().selectByLogin(dbSession, GRACE_HOPPER)).extracting("name").containsOnly("token-to-keep-1", "token-to-keep-2");
+ assertThat(dbClient.userTokenDao().selectByLogin(dbSession, ADA_LOVELACE)).extracting("name").containsOnly("token-to-delete");
+ }
+
+ @Test
+ public void does_not_fail_when_incorrect_login_or_name() {
+ insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName(TOKEN_NAME));
+
+ newRequest(ADA_LOVELACE, "another-token-name");
+ }
+
+ @Test
+ public void fail_if_not_logged_in() {
+ userSession.anonymous();
+ insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName(TOKEN_NAME));
+ expectedException.expect(UnauthorizedException.class);
+
+ newRequest(GRACE_HOPPER, TOKEN_NAME);
+ }
+
+ @Test
+ public void fail_if_insufficient_privileges() {
+ userSession.login().setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+ insertUserToken(newUserToken().setLogin(GRACE_HOPPER).setName(TOKEN_NAME));
+ expectedException.expect(ForbiddenException.class);
+
+ 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 void insertUserToken(UserTokenDto userToken) {
+ dbClient.userTokenDao().insert(dbSession, userToken);
+ dbSession.commit();
+ }
+}
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 4f3ad84603e..b4b3b561762 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
@@ -45,7 +45,8 @@ public class UserTokensWsTest {
TokenGenerator tokenGenerator = mock(TokenGenerator.class);
ws = new WsTester(new UserTokensWs(
- new GenerateAction(userSession, dbClient, system, tokenGenerator)));
+ new GenerateAction(dbClient, userSession, system, tokenGenerator),
+ new RevokeAction(dbClient, userSession)));
}
@Test
@@ -59,4 +60,15 @@ public class UserTokensWsTest {
assertThat(action.param("login").isRequired()).isTrue();
assertThat(action.param("name").isRequired()).isTrue();
}
+
+ @Test
+ public void revoke_action() {
+ WebService.Action action = ws.action(CONTROLLER_KEY, "revoke");
+
+ assertThat(action).isNotNull();
+ assertThat(action.since()).isEqualTo("5.3");
+ assertThat(action.isPost()).isTrue();
+ assertThat(action.param("login").isRequired()).isTrue();
+ assertThat(action.param("name").isRequired()).isTrue();
+ }
}