]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4463 Added LoadedTemplate entry to cover default permission template initialization
authorJean-Baptiste Vilain <jean-baptiste.vilain@sonarsource.com>
Mon, 15 Jul 2013 11:52:11 +0000 (13:52 +0200)
committerJean-Baptiste Vilain <jean-baptiste.vilain@sonarsource.com>
Mon, 15 Jul 2013 11:52:11 +0000 (13:52 +0200)
sonar-core/src/main/java/org/sonar/core/permission/PermissionDao.java
sonar-core/src/main/java/org/sonar/core/permission/PermissionTemplateDto.java
sonar-core/src/main/java/org/sonar/core/template/LoadedTemplateDto.java
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
sonar-core/src/test/java/org/sonar/core/permission/PermissionDaoTest.java
sonar-server/src/main/java/org/sonar/server/platform/Platform.java
sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java [new file with mode: 0644]
sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java [new file with mode: 0644]

index 5c60d63fbd603b89758d6c92a1f57ec8a7fc534c..486f3d552a09cb508e71d5f3a5294365401f6577 100644 (file)
@@ -214,6 +214,9 @@ public class PermissionDao implements TaskComponent, ServerComponent {
   }
 
   private String generateTemplateKee(String name, Date timeStamp) {
+    if(PermissionTemplateDto.DEFAULT.getName().equals(name)) {
+      return PermissionTemplateDto.DEFAULT.getKee();
+    }
     String normalizedName = Normalizer.normalize(name, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "").replace(" ", "_");
     return normalizedName.toLowerCase() + "_" + DateFormatUtils.format(timeStamp, "yyyyMMdd_HHmmss");
   }
index 6eead5a1cc8bda3f419fa48370cce579b29ef707..a68a60557aa7f2af0696ef5b735ba78a6a96e234 100644 (file)
@@ -27,6 +27,11 @@ import java.util.List;
 
 public class PermissionTemplateDto {
 
+  public static final PermissionTemplateDto DEFAULT = new PermissionTemplateDto()
+    .setName("Default template")
+    .setKee("default_template")
+    .setDescription("This permission template will be used as default when no other permission configuration is available");
+
   private Long id;
   private String name;
   private String kee;
index 60e033ef734e9e25275a5edb36d10c87d858367a..5ebcf50d0e50f561d7a64780a2a03c5a063ddb15 100644 (file)
@@ -26,6 +26,7 @@ public final class LoadedTemplateDto {
   public static final String DASHBOARD_TYPE = "DASHBOARD";
   public static final String FILTER_TYPE = "FILTER";
   public static final String QUALITY_PROFILE_TYPE = "QUALITY_PROFILE";
+  public static final String PERMISSION_TEMPLATE_TYPE = "PERM_TEMPLATE";
 
   private Long id;
   private String key;
index 750a0ba31aabf8f57eca46703e81cf44f8905f34..98231f3ff1d50742690daf881e8974c177a644e7 100644 (file)
@@ -14,21 +14,6 @@ ALTER TABLE GROUP_ROLES ALTER COLUMN ID RESTART WITH 6;
 INSERT INTO GROUPS_USERS(USER_ID, GROUP_ID) VALUES (1, 1);
 INSERT INTO GROUPS_USERS(USER_ID, GROUP_ID) VALUES (1, 2);
 
--- Default permissions - Replaces the previous role-based properties such as 'sonar.role.admin.TRK.defaultGroups' (see migration 418)
-INSERT INTO PERMISSION_TEMPLATES(ID, name, kee, description) VALUES (1, 'Default template', 'default_template', 'This permission template will be used as default when no other permission configuration is available');
-ALTER TABLE PERMISSION_TEMPLATES ALTER COLUMN ID RESTART WITH 2;
-
-INSERT INTO PERM_TEMPLATES_GROUPS(ID, template_id, group_id, permission_reference) VALUES (1, 1, 1, 'admin');
-INSERT INTO PERM_TEMPLATES_GROUPS(ID, template_id, group_id, permission_reference) VALUES (2, 1, 2, 'user');
-INSERT INTO PERM_TEMPLATES_GROUPS(ID, template_id, group_id, permission_reference) VALUES (3, 1, NULL, 'user');
-INSERT INTO PERM_TEMPLATES_GROUPS(ID, template_id, group_id, permission_reference) VALUES (4, 1, 2, 'codeviewer');
-INSERT INTO PERM_TEMPLATES_GROUPS(ID, template_id, group_id, permission_reference) VALUES (5, 1, NULL, 'codeviewer');
-ALTER TABLE PERM_TEMPLATES_GROUPS ALTER COLUMN ID RESTART WITH 6;
-
-INSERT INTO PROPERTIES(ID, prop_key, resource_id, text_value, user_id) VALUES (1, 'sonar.permission.template.default', NULL, 'default_template', NULL);
-ALTER TABLE PROPERTIES ALTER COLUMN ID RESTART WITH 2;
--- Default permissions end
-
 
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('1');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('2');
index b607e086584c9ac7c60199fe4fb431500220d642..57d312aceb9c2777fa29405a9a16ec7e0802f9af 100644 (file)
 
 package org.sonar.core.permission;
 
+import org.apache.ibatis.session.SqlSession;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.core.date.DateProvider;
 import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.MyBatis;
 
 import java.util.Date;
 import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.stub;
+import static org.mockito.Mockito.*;
 
 public class PermissionDaoTest extends AbstractDaoTestCase {
 
@@ -65,6 +66,26 @@ public class PermissionDaoTest extends AbstractDaoTestCase {
     checkTable("createNonAsciiPermissionTemplate", "permission_templates", "id", "name", "kee", "description");
   }
 
+  @Test
+  public void should_skip_key_normalization_on_default_template() throws Exception {
+
+    PermissionTemplateMapper mapper = mock(PermissionTemplateMapper.class);
+
+    SqlSession session = mock(SqlSession.class);
+    when(session.getMapper(PermissionTemplateMapper.class)).thenReturn(mapper);
+
+    MyBatis myBatis = mock(MyBatis.class);
+    when(myBatis.openSession()).thenReturn(session);
+
+    permissionDao = new PermissionDao(myBatis, dateProvider);
+    PermissionTemplateDto permissionTemplate = permissionDao.createPermissionTemplate(PermissionTemplateDto.DEFAULT.getName(), null);
+
+    verify(mapper).insert(permissionTemplate);
+    verify(session).commit();
+
+    assertThat(permissionTemplate.getKee()).isEqualTo(PermissionTemplateDto.DEFAULT.getKee());
+  }
+
   @Test
   public void should_select_permission_template() throws Exception {
     setupData("selectPermissionTemplate");
index e06af738a31d63f404f27f5d92b586db2889c4c8..00218059afb0859d4e5a664945c050f2d9d6feaf 100644 (file)
@@ -329,6 +329,7 @@ public final class Platform {
     startupContainer.addSingleton(GenerateBootstrapIndex.class);
     startupContainer.addSingleton(RegisterNewMeasureFilters.class);
     startupContainer.addSingleton(RegisterNewDashboards.class);
+    startupContainer.addSingleton(RegisterPermissionTemplates.class);
     startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class);
     startupContainer.addSingleton(LogServerId.class);
     startupContainer.addSingleton(RegisterServletFilters.class);
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java
new file mode 100644 (file)
index 0000000..51fc1cc
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.startup;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.utils.TimeProfiler;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.permission.PermissionDao;
+import org.sonar.core.permission.PermissionTemplateDto;
+import org.sonar.core.template.LoadedTemplateDao;
+import org.sonar.core.template.LoadedTemplateDto;
+import org.sonar.core.user.UserDao;
+import org.sonar.server.platform.PersistentSettings;
+
+public class RegisterPermissionTemplates {
+
+  public static final String DEFAULT_TEMPLATE_PROPERTY = "sonar.permission.template.default";
+
+  private static final Logger LOG = LoggerFactory.getLogger(RegisterPermissionTemplates.class);
+
+  private final LoadedTemplateDao loadedTemplateDao;
+  private final PermissionDao permissionDao;
+  private final UserDao userDao;
+  private final PersistentSettings settings;
+
+  public RegisterPermissionTemplates(LoadedTemplateDao loadedTemplateDao, PermissionDao permissionDao,
+                                     UserDao userDao, PersistentSettings settings) {
+    this.loadedTemplateDao = loadedTemplateDao;
+    this.permissionDao = permissionDao;
+    this.userDao = userDao;
+    this.settings = settings;
+  }
+
+  public void start() {
+    TimeProfiler profiler = new TimeProfiler(LOG).start("Register permission templates");
+
+    if(shouldRegister()) {
+      insertDefaultTemplate(PermissionTemplateDto.DEFAULT.getName());
+      registerInitialization();
+      setDefaultProperty(PermissionTemplateDto.DEFAULT.getKee());
+    }
+    profiler.stop();
+  }
+
+  private boolean shouldRegister() {
+    return loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE, PermissionTemplateDto.DEFAULT.getKee()) == 0;
+  }
+
+  private void insertDefaultTemplate(String templateName) {
+    PermissionTemplateDto defaultPermissionTemplate = permissionDao
+      .createPermissionTemplate(templateName, PermissionTemplateDto.DEFAULT.getDescription());
+    addGroupPermission(defaultPermissionTemplate, UserRole.ADMIN, DefaultGroups.ADMINISTRATORS);
+    addGroupPermission(defaultPermissionTemplate, UserRole.USER, DefaultGroups.USERS);
+    addGroupPermission(defaultPermissionTemplate, UserRole.USER, DefaultGroups.ANYONE);
+    addGroupPermission(defaultPermissionTemplate, UserRole.CODEVIEWER, DefaultGroups.USERS);
+    addGroupPermission(defaultPermissionTemplate, UserRole.CODEVIEWER, DefaultGroups.ANYONE);
+  }
+
+  private void addGroupPermission(PermissionTemplateDto template, String permission, String groupName) {
+    Long groupId;
+    if(DefaultGroups.isAnyone(groupName)) {
+      groupId = null;
+    } else {
+      groupId = userDao.selectGroupByName(groupName).getId();
+    }
+    permissionDao.addGroupPermission(template.getId(), groupId, permission);
+  }
+
+  private void registerInitialization() {
+    LoadedTemplateDto loadedTemplate = new LoadedTemplateDto(PermissionTemplateDto.DEFAULT.getKee(),
+      LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE);
+    loadedTemplateDao.insert(loadedTemplate);
+  }
+
+  private void setDefaultProperty(String defaultTemplate) {
+    if (settings.getString(DEFAULT_TEMPLATE_PROPERTY) == null) {
+      LOG.info("Set default permission template: " + defaultTemplate);
+      settings.saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate);
+    }
+  }
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java b/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java
new file mode 100644 (file)
index 0000000..c192075
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.startup;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.permission.PermissionDao;
+import org.sonar.core.permission.PermissionTemplateDto;
+import org.sonar.core.template.LoadedTemplateDao;
+import org.sonar.core.template.LoadedTemplateDto;
+import org.sonar.core.user.GroupDto;
+import org.sonar.core.user.UserDao;
+import org.sonar.server.platform.PersistentSettings;
+
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
+public class RegisterPermissionTemplatesTest {
+
+  private PersistentSettings settings;
+  private LoadedTemplateDao loadedTemplateDao;
+  private PermissionDao permissionDao;
+  private UserDao userDao;
+
+  @Before
+  public void setUp() {
+    settings = mock(PersistentSettings.class);
+    loadedTemplateDao = mock(LoadedTemplateDao.class);
+    permissionDao = mock(PermissionDao.class);
+    userDao = mock(UserDao.class);
+  }
+
+  @Test
+  public void should_insert_and_register_default_permission_template() throws Exception {
+    LoadedTemplateDto expectedTemplate = new LoadedTemplateDto().setKey(PermissionTemplateDto.DEFAULT.getKee())
+      .setType(LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE);
+    PermissionTemplateDto permissionTemplate = PermissionTemplateDto.DEFAULT.setId(1L);
+
+    when(loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE, PermissionTemplateDto.DEFAULT.getKee()))
+      .thenReturn(0);
+    when(permissionDao.createPermissionTemplate(PermissionTemplateDto.DEFAULT.getName(), PermissionTemplateDto.DEFAULT.getDescription()))
+      .thenReturn(permissionTemplate);
+    when(userDao.selectGroupByName(DefaultGroups.ADMINISTRATORS)).thenReturn(new GroupDto().setId(1L));
+    when(userDao.selectGroupByName(DefaultGroups.USERS)).thenReturn(new GroupDto().setId(2L));
+
+    RegisterPermissionTemplates initializer = new RegisterPermissionTemplates(loadedTemplateDao, permissionDao, userDao, settings);
+    initializer.start();
+
+    verify(loadedTemplateDao).insert(argThat(Matches.template(expectedTemplate)));
+    verify(permissionDao).createPermissionTemplate(PermissionTemplateDto.DEFAULT.getName(), PermissionTemplateDto.DEFAULT.getDescription());
+    verify(permissionDao).addGroupPermission(1L, 1L, UserRole.ADMIN);
+    verify(permissionDao).addGroupPermission(1L, 2L, UserRole.USER);
+    verify(permissionDao).addGroupPermission(1L, null, UserRole.USER);
+    verify(permissionDao).addGroupPermission(1L, 2L, UserRole.CODEVIEWER);
+    verify(permissionDao).addGroupPermission(1L, null, UserRole.CODEVIEWER);
+    verify(settings).saveProperty(RegisterPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY, PermissionTemplateDto.DEFAULT.getKee());
+  }
+
+  @Test
+  public void should_skip_insertion_and_registration() throws Exception {
+    when(loadedTemplateDao.countByTypeAndKey(LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE, PermissionTemplateDto.DEFAULT.getKee()))
+      .thenReturn(1);
+
+    RegisterPermissionTemplates initializer = new RegisterPermissionTemplates(loadedTemplateDao, permissionDao, userDao, settings);
+    initializer.start();
+
+    verifyZeroInteractions(permissionDao, settings);
+    verify(loadedTemplateDao, never()).insert(any(LoadedTemplateDto.class));
+  }
+
+  private static class Matches extends BaseMatcher<LoadedTemplateDto> {
+
+    private final LoadedTemplateDto referenceTemplate;
+
+    private Matches(LoadedTemplateDto referenceTemplate) {
+      this.referenceTemplate = referenceTemplate;
+    }
+
+    static Matches template(LoadedTemplateDto referenceTemplate) {
+      return new Matches(referenceTemplate);
+    }
+
+    @Override
+    public boolean matches(Object o) {
+      if(o != null && o instanceof LoadedTemplateDto) {
+        LoadedTemplateDto otherTemplate = (LoadedTemplateDto) o;
+        return referenceTemplate.getKey().equals(otherTemplate.getKey())
+          && referenceTemplate.getType().equals(otherTemplate.getType());
+      }
+      return false;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+    }
+  }
+}