}
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");
}
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;
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;
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');
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 {
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");
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);
--- /dev/null
+/*
+ * 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);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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) {
+ }
+ }
+}