]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16263 Handle analysis token lifecycle
authorMatteo Mara <matteo.mara@sonarsource.com>
Mon, 25 Apr 2022 14:18:48 +0000 (16:18 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 29 Apr 2022 20:03:19 +0000 (20:03 +0000)
21 files changed:
server/sonar-db-dao/src/main/java/org/sonar/db/audit/model/UserTokenNewValue.java
server/sonar-db-dao/src/main/java/org/sonar/db/user/TokenType.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/user/UserTokenDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/user/UserTokenMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserTokenMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/user/UserTokenDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/user/UserTokenDaoWithPersisterTest.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/TokenGenerator.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/TokenGeneratorImpl.java
server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/TokenType.java [deleted file]
server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/UserTokenAuthentication.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/usertoken/TokenGeneratorImplTest.java
server/sonar-webserver-auth/src/test/java/org/sonar/server/usertoken/UserTokenAuthenticationTest.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/badge/ws/TokenRenewAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentCleanerService.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/usertoken/ws/GenerateAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/badge/ws/TokenActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/badge/ws/TokenRenewActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentCleanerServiceTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/usertoken/ws/GenerateActionTest.java

index 48d060b23bdc69fbc97233aa71cfda59566c4e37..96f2956a51889bf35e9895bb6150be40e13dddc0 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.db.audit.model;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.utils.DateUtils;
+import org.sonar.db.user.TokenType;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserTokenDto;
 
@@ -29,6 +30,7 @@ public class UserTokenNewValue extends NewValue {
   @Nullable
   private String tokenUuid;
 
+  @Nullable
   private String userUuid;
 
   @Nullable
@@ -66,6 +68,11 @@ public class UserTokenNewValue extends NewValue {
     this.tokenName = tokenName;
   }
 
+  public UserTokenNewValue(String projectKey) {
+    this.projectKey = projectKey;
+    this.type = TokenType.PROJECT_ANALYSIS_TOKEN.name();
+  }
+
   @CheckForNull
   public String getTokenUuid() {
     return this.tokenUuid;
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/TokenType.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/TokenType.java
new file mode 100644 (file)
index 0000000..3499f4c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.db.user;
+
+public enum TokenType {
+
+  USER_TOKEN("u"),
+  GLOBAL_ANALYSIS_TOKEN("a"),
+  PROJECT_ANALYSIS_TOKEN("p");
+
+  private final String identifier;
+
+  TokenType(String identifier) {
+    this.identifier = identifier;
+  }
+
+  public String getIdentifier() {
+    return identifier;
+  }
+}
index a3627d1ce63960b1199cec851ab01dd2bbaa638f..e1191ee266ca18ae429820fece9d9e4d9aa0c96b 100644 (file)
@@ -103,6 +103,14 @@ public class UserTokenDao implements Dao {
     }
   }
 
+  public void deleteByProjectKey(DbSession dbSession, String projectKey) {
+    int deletedRows = mapper(dbSession).deleteByProjectKey(projectKey);
+
+    if (deletedRows > 0) {
+      auditPersister.deleteUserToken(dbSession, new UserTokenNewValue(projectKey));
+    }
+  }
+
   private static UserTokenMapper mapper(DbSession dbSession) {
     return dbSession.getMapper(UserTokenMapper.class);
   }
index 2094fabd08c43b8b922f396ec82fd90ded5f0e8b..435d445c35de92d0ea731b1e6f293ff36759dca0 100644 (file)
@@ -38,5 +38,7 @@ public interface UserTokenMapper {
 
   int deleteByUserUuidAndName(@Param("userUuid") String userUuid, @Param("name") String name);
 
+  int deleteByProjectKey(@Param("projectKey") String projectKey);
+
   List<UserTokenCount> countTokensByUserUuids(@Param("userUuids") List<String> userUuids);
 }
index 3977a79404586b2540dab2cf08dbc783de25d876..ba43d789d86290c1ff76a022b9f0bb7bafc7188f 100644 (file)
@@ -85,4 +85,8 @@
     DELETE FROM user_tokens WHERE user_uuid=#{userUuid, jdbcType=VARCHAR} and name=#{name, jdbcType=VARCHAR}
   </delete>
 
+  <delete id="deleteByProjectKey">
+    DELETE FROM user_tokens WHERE project_key=#{projectKey, jdbcType=VARCHAR}
+  </delete>
+
 </mapper>
index 2568efd1b226b5eb60e8f4628e07fc37f59ba0ec..2f5dc9c7d892d7618130d70ca186b67214fcf91e 100644 (file)
@@ -144,6 +144,21 @@ public class UserTokenDaoTest {
     assertThat(underTest.selectByUserAndName(dbSession, user2, "name")).isNotNull();
   }
 
+  @Test
+  public void delete_tokens_by_projectKey() {
+    UserDto user1 = db.users().insertUser();
+    UserDto user2 = db.users().insertUser();
+    db.users().insertToken(user1, t -> t.setProjectKey("projectKey1"));
+    db.users().insertToken(user1, t -> t.setProjectKey("projectKey2"));
+    db.users().insertToken(user2, t -> t.setProjectKey("projectKey1"));
+
+    underTest.deleteByProjectKey(dbSession, "projectKey1");
+    db.commit();
+
+    assertThat(underTest.selectByUser(dbSession, user1)).hasSize(1);
+    assertThat(underTest.selectByUser(dbSession, user2)).isEmpty();
+  }
+
   @Test
   public void count_tokens_by_user() {
     UserDto user = db.users().insertUser();
index 67da1273d81507f0498b0ae79f507f0cb91b13c6..f189d2397571fdf3478c042e909ac045f6415d2c 100644 (file)
@@ -138,7 +138,7 @@ public class UserTokenDaoWithPersisterTest {
   }
 
   @Test
-  public void delete_token_by_user_and_name_without_affected_rows_is_persisted() {
+  public void delete_token_by_user_and_name_without_affected_rows_is_not_persisted() {
     UserDto user1 = db.users().insertUser();
 
     underTest.deleteByUserAndName(dbSession, user1, "name");
@@ -146,4 +146,38 @@ public class UserTokenDaoWithPersisterTest {
     verify(auditPersister).addUser(any(), any());
     verifyNoMoreInteractions(auditPersister);
   }
+
+
+  @Test
+  public void delete_token_by_projectKey_is_persisted() {
+    UserDto user1 = db.users().insertUser();
+    UserDto user2 = db.users().insertUser();
+    db.users().insertToken(user1, t -> t.setProjectKey("projectToDelete"));
+    db.users().insertToken(user1, t -> t.setProjectKey("projectToKeep"));
+    db.users().insertToken(user2, t -> t.setProjectKey("projectToDelete"));
+
+    underTest.deleteByProjectKey(dbSession, "projectToDelete");
+
+    assertThat(underTest.selectByUser(dbSession, user1)).hasSize(1);
+    assertThat(underTest.selectByUser(dbSession, user2)).isEmpty();
+    verify(auditPersister).deleteUserToken(eq(db.getSession()), newValueCaptor.capture());
+    assertThat(newValueCaptor.getValue())
+      .extracting(UserTokenNewValue::getProjectKey, UserTokenNewValue::getType)
+      .containsExactly("projectToDelete", "PROJECT_ANALYSIS_TOKEN");
+  }
+
+  @Test
+  public void delete_token_by_projectKey_without_affected_rows_is_not_persisted() {
+    UserDto user1 = db.users().insertUser();
+
+    db.users().insertToken(user1, t -> t.setProjectKey("projectToKeep"));
+
+    underTest.deleteByProjectKey(dbSession, "projectToDelete");
+
+    assertThat(underTest.selectByUser(dbSession, user1)).hasSize(1);
+
+    verify(auditPersister).addUser(any(), any());
+    verify(auditPersister).addUserToken(any(), any());
+    verifyNoMoreInteractions(auditPersister);
+  }
 }
index b41644530bf4f1a21929a511674dc11bc6f4319e..1df9e1f8dadeae8629b34cb50d92bbd61c1b9976 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.server.usertoken;
 
+import org.sonar.db.user.TokenType;
+
 public interface TokenGenerator {
   /**
    * Generate a token. It must be unique and non deterministic.<br />
index 235a2fb0285b061e2dab0b2abdb9a69f09f4ce1b..fee313bd1f04472b549c432dbd1a3bdb12868587 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.usertoken;
 import java.security.SecureRandom;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.sonar.db.user.TokenType;
 
 public class TokenGeneratorImpl implements TokenGenerator {
 
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/TokenType.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/usertoken/TokenType.java
deleted file mode 100644 (file)
index 0fcfbd7..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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;
-
-public enum TokenType {
-
-  USER_TOKEN("u"),
-  GLOBAL_ANALYSIS_TOKEN("a"),
-  PROJECT_ANALYSIS_TOKEN("p");
-
-  private final String identifier;
-
-  TokenType(String identifier) {
-    this.identifier = identifier;
-  }
-
-  public String getIdentifier() {
-    return identifier;
-  }
-}
index 1bed33677d62b2005626675b0d1d0adcccf87f8f..03af54aa1c45fe699ed26e6022d8a7d8a48140e6 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Set;
 import javax.annotation.Nullable;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.user.TokenType;
 import org.sonar.db.user.UserTokenDto;
 import org.sonar.server.authentication.UserLastConnectionDatesUpdater;
 
index d0816bca086f395d1ecbd32d1bfbf6cec7294754..08a20be69b2d411be811dd7b350b06e10d76335e 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.server.usertoken;
 
 import org.junit.Test;
+import org.sonar.db.user.TokenType;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
index 7957812dab1539fbae4e6750b3dd84ca38123ee1..32b2c3948ba3706f48cc553d4d82550172d8c1bf 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
+import org.sonar.db.user.TokenType;
 import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserTokenDto;
 import org.sonar.server.authentication.UserLastConnectionDatesUpdater;
index 6298e21679a9224d9ad1019ab7a44c118fdb5fe4..22111431fd713f4c82e71d0f16267132ec8cd7de 100644 (file)
@@ -31,7 +31,7 @@ import org.sonar.db.project.ProjectDto;
 import org.sonar.db.project.ProjectBadgeTokenDto;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.usertoken.TokenGenerator;
-import org.sonar.server.usertoken.TokenType;
+import org.sonar.db.user.TokenType;
 import org.sonarqube.ws.ProjectBadgeToken.TokenWsResponse;
 
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
index 23905c9d668867ae4535d3f211e8663b6a9103f3..f89f55f41786391dfaf7e3ae376e8f0b0fd955c2 100644 (file)
@@ -29,7 +29,7 @@ import org.sonar.db.DbSession;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.usertoken.TokenGenerator;
-import org.sonar.server.usertoken.TokenType;
+import org.sonar.db.user.TokenType;
 
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
 
index 630c3f55c60e87c28c0140f453b10fde2a76a037..2ca216902c063f168c9870e5dc8fc22566f6f023 100644 (file)
@@ -68,6 +68,7 @@ public class ComponentCleanerService {
   public void delete(DbSession dbSession, ProjectDto project) {
     dbClient.purgeDao().deleteProject(dbSession, project.getUuid(), project.getQualifier(), project.getName(), project.getKey());
     dbClient.userDao().cleanHomepage(dbSession, project);
+    dbClient.userTokenDao().deleteByProjectKey(dbSession, project.getKey());
     projectIndexers.commitAndIndexProjects(dbSession, singletonList(project), PROJECT_DELETION);
   }
 
@@ -78,19 +79,20 @@ public class ComponentCleanerService {
   }
 
   public void delete(DbSession dbSession, ComponentDto project) {
-    checkArgument(!hasNotProjectScope(project) && !isNotDeletable(project) && project.getMainBranchProjectUuid() == null, "Only projects can be deleted");
+    checkArgument(hasProjectScope(project) && isDeletable(project) && project.getMainBranchProjectUuid() == null, "Only projects can be deleted");
     dbClient.purgeDao().deleteProject(dbSession, project.uuid(), project.qualifier(), project.name(), project.getKey());
     dbClient.userDao().cleanHomepage(dbSession, project);
+    dbClient.userTokenDao().deleteByProjectKey(dbSession, project.getKey());
     projectIndexers.commitAndIndexComponents(dbSession, singletonList(project), PROJECT_DELETION);
   }
 
-  private static boolean hasNotProjectScope(ComponentDto project) {
-    return !Scopes.PROJECT.equals(project.scope());
+  private static boolean hasProjectScope(ComponentDto project) {
+    return Scopes.PROJECT.equals(project.scope());
   }
 
-  private boolean isNotDeletable(ComponentDto project) {
+  private boolean isDeletable(ComponentDto project) {
     ResourceType resourceType = resourceTypes.get(project.qualifier());
     // this essentially means PROJECTS, VIEWS and APPS (not SUBVIEWS)
-    return resourceType == null || !resourceType.getBooleanProperty("deletable");
+    return resourceType != null && resourceType.getBooleanProperty("deletable");
   }
 }
index 79992ae442fe689f3d24481cabcf61f0847ff513..ccecb44f1539a3828d024b197e74f5dbeaee1f61 100644 (file)
@@ -31,7 +31,7 @@ import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserTokenDto;
 import org.sonar.server.exceptions.ServerException;
 import org.sonar.server.usertoken.TokenGenerator;
-import org.sonar.server.usertoken.TokenType;
+import org.sonar.db.user.TokenType;
 import org.sonarqube.ws.UserTokens;
 import org.sonarqube.ws.UserTokens.GenerateWsResponse;
 
@@ -39,9 +39,9 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
 import static org.sonar.api.utils.DateUtils.formatDateTime;
 import static org.sonar.server.exceptions.BadRequestException.checkRequest;
-import static org.sonar.server.usertoken.TokenType.GLOBAL_ANALYSIS_TOKEN;
-import static org.sonar.server.usertoken.TokenType.PROJECT_ANALYSIS_TOKEN;
-import static org.sonar.server.usertoken.TokenType.USER_TOKEN;
+import static org.sonar.db.user.TokenType.GLOBAL_ANALYSIS_TOKEN;
+import static org.sonar.db.user.TokenType.PROJECT_ANALYSIS_TOKEN;
+import static org.sonar.db.user.TokenType.USER_TOKEN;
 import static org.sonar.server.usertoken.ws.UserTokenSupport.ACTION_GENERATE;
 import static org.sonar.server.usertoken.ws.UserTokenSupport.PARAM_LOGIN;
 import static org.sonar.server.usertoken.ws.UserTokenSupport.PARAM_NAME;
index 46fe9733d4b56175923a7679b8a3f43e1099719b..b078773fc774ab4f50c3e56bb257a210d28580fa 100644 (file)
@@ -29,7 +29,7 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usertoken.TokenGenerator;
-import org.sonar.server.usertoken.TokenType;
+import org.sonar.db.user.TokenType;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
index 65b2ad863253897d55d9c50cb761d3404cb5b674..37a02948c42d2b0e871f694a545f3ee56b742b2a 100644 (file)
@@ -33,7 +33,7 @@ import org.sonar.db.project.ProjectDto;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usertoken.TokenGenerator;
-import org.sonar.server.usertoken.TokenType;
+import org.sonar.db.user.TokenType;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
index 6e207d2e7de9ee3c78418c68fe20ead1d9a8cf51..21612c447341965790e2c9322d69376af11c8c81 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.component;
 
+import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.resources.ResourceType;
@@ -84,6 +85,38 @@ public class ComponentCleanerServiceTest {
     assertExists(data3);
   }
 
+  @Test
+  public void delete_list_of_components_from_db() {
+    ComponentDto componentDto1 = db.components().insertPublicProject();
+    ComponentDto componentDto2 = db.components().insertPublicProject();
+    ComponentDto componentDto3 = db.components().insertPublicProject();
+
+    mockResourceTypeAsValidProject();
+
+    underTest.deleteComponents(dbSession, asList(componentDto1, componentDto2));
+    dbSession.commit();
+
+    assertNotExists(componentDto1);
+    assertNotExists(componentDto2);
+    assertExists(componentDto3);
+  }
+
+  @Test
+  public void fail_with_IAE_if_project_non_deletable() {
+    ComponentDto componentDto1 = db.components().insertPublicProject();
+    ComponentDto componentDto2 = db.components().insertPublicProject();
+
+    mockResourceTypeAsNonDeletable();
+
+    dbSession.commit();
+
+    List<ComponentDto> componentDtos = asList(componentDto1, componentDto2);
+
+    assertThatThrownBy(() -> underTest.deleteComponents(dbSession, componentDtos))
+      .withFailMessage("Only projects can be deleted")
+      .isInstanceOf(IllegalArgumentException.class);
+  }
+
   @Test
   public void delete_application_from_db_and_index() {
     DbData data1 = insertProjectData();
@@ -176,6 +209,12 @@ public class ComponentCleanerServiceTest {
     when(mockResourceTypes.get(anyString())).thenReturn(resourceType);
   }
 
+  private void mockResourceTypeAsNonDeletable() {
+    ResourceType resourceType = mock(ResourceType.class);
+    when(resourceType.getBooleanProperty("deletable")).thenReturn(false);
+    when(mockResourceTypes.get(anyString())).thenReturn(resourceType);
+  }
+
   private void assertNotExists(DbData data) {
     assertDataInDb(data, false);
     assertThat(projectIndexers.hasBeenCalled(data.branch.getUuid(), PROJECT_DELETION)).isTrue();
@@ -198,6 +237,18 @@ public class ComponentCleanerServiceTest {
     assertThat(dbClient.branchDao().selectByUuid(dbSession, appOrProject.getUuid()).isPresent()).isEqualTo(exists);
   }
 
+  private void assertNotExists(ComponentDto componentDto) {
+    assertComponentExists(componentDto, false);
+  }
+
+  private void assertExists(ComponentDto componentDto) {
+    assertComponentExists(componentDto, true);
+  }
+
+  private void assertComponentExists(ComponentDto componentDto, boolean exists) {
+    assertThat(dbClient.componentDao().selectByUuid(dbSession, componentDto.uuid()).isPresent()).isEqualTo(exists);
+  }
+  
   private static class DbData {
     final ProjectDto project;
     final BranchDto branch;
index 3928d32c23de7d3cb8dfb5cde238ffc5b76790ef..a56be8b720c68962df4d2e15ac49b1fc4d3dc7d8 100644 (file)
@@ -35,7 +35,7 @@ import org.sonar.server.exceptions.ServerException;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usertoken.TokenGenerator;
-import org.sonar.server.usertoken.TokenType;
+import org.sonar.db.user.TokenType;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.MediaTypes;
@@ -47,9 +47,9 @@ import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.sonar.db.permission.GlobalPermission.SCAN;
-import static org.sonar.server.usertoken.TokenType.GLOBAL_ANALYSIS_TOKEN;
-import static org.sonar.server.usertoken.TokenType.PROJECT_ANALYSIS_TOKEN;
-import static org.sonar.server.usertoken.TokenType.USER_TOKEN;
+import static org.sonar.db.user.TokenType.GLOBAL_ANALYSIS_TOKEN;
+import static org.sonar.db.user.TokenType.PROJECT_ANALYSIS_TOKEN;
+import static org.sonar.db.user.TokenType.USER_TOKEN;
 import static org.sonar.server.usertoken.ws.UserTokenSupport.PARAM_LOGIN;
 import static org.sonar.server.usertoken.ws.UserTokenSupport.PARAM_NAME;
 import static org.sonar.server.usertoken.ws.UserTokenSupport.PARAM_PROJECT_KEY;