diff options
8 files changed, 746 insertions, 0 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/user/PermissionDao.java b/sonar-core/src/main/java/org/sonar/core/user/PermissionDao.java index 8e9bbf5d2de..ed8967b2959 100644 --- a/sonar-core/src/main/java/org/sonar/core/user/PermissionDao.java +++ b/sonar-core/src/main/java/org/sonar/core/user/PermissionDao.java @@ -25,6 +25,7 @@ import org.sonar.api.ServerExtension; import org.sonar.api.task.TaskExtension; import org.sonar.core.persistence.MyBatis; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.util.Date; import java.util.List; @@ -37,6 +38,7 @@ public class PermissionDao implements TaskExtension, ServerExtension { this.myBatis = myBatis; } + @CheckForNull public PermissionTemplateDto selectTemplateByName(String templateName) { SqlSession session = myBatis.openSession(); try { @@ -47,6 +49,7 @@ public class PermissionDao implements TaskExtension, ServerExtension { } } + @CheckForNull public PermissionTemplateDto selectPermissionTemplate(String templateName) { PermissionTemplateDto permissionTemplate = null; SqlSession session = myBatis.openSession(); diff --git a/sonar-server/src/main/java/org/sonar/server/exceptions/ServerErrorException.java b/sonar-server/src/main/java/org/sonar/server/exceptions/ServerErrorException.java new file mode 100644 index 00000000000..c5110bf8c44 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/exceptions/ServerErrorException.java @@ -0,0 +1,30 @@ +/* + * 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.exceptions; + +public class ServerErrorException extends HttpException { + + private static final int SERVER_ERROR = 500; + + public ServerErrorException(String message) { + super(SERVER_ERROR, message); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java b/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java new file mode 100644 index 00000000000..e996b13403c --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionTemplateService.java @@ -0,0 +1,133 @@ +/* + * 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.permission; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.ServerComponent; +import org.sonar.core.user.*; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ServerErrorException; + +import javax.annotation.CheckForNull; +import java.util.List; + +/** + * Used by ruby code <pre>Internal.permission_templates</pre> + */ +public class InternalPermissionTemplateService implements ServerComponent { + + private static final Logger LOG = LoggerFactory.getLogger(InternalPermissionTemplateService.class); + + private final PermissionDao permissionDao; + private final UserDao userDao; + + public InternalPermissionTemplateService(PermissionDao permissionDao, UserDao userDao) { + this.permissionDao = permissionDao; + this.userDao = userDao; + } + + public PermissionTemplate createPermissionTemplate(String name, String description) { + PermissionTemplateUpdater.checkUserCredentials(); + PermissionTemplateDto permissionTemplateDto = permissionDao.createPermissionTemplate(name, description); + checkThatTemplateNameIsUnique(name); + if(permissionTemplateDto == null) { + String errorMsg = "Template creation failed"; + LOG.error(errorMsg); + throw new ServerErrorException(errorMsg); + } + return PermissionTemplate.create(permissionTemplateDto); + } + + @CheckForNull + public PermissionTemplate selectPermissionTemplate(String templateName) { + PermissionTemplateUpdater.checkUserCredentials(); + PermissionTemplateDto permissionTemplateDto = permissionDao.selectPermissionTemplate(templateName); + return PermissionTemplate.create(permissionTemplateDto); + } + + public void deletePermissionTemplate(String templateName) { + PermissionTemplateUpdater.checkUserCredentials(); + PermissionTemplateDto permissionTemplateDto = permissionDao.selectTemplateByName(templateName); + if(permissionTemplateDto == null) { + String errorMsg = "Unknown template:" + templateName; + LOG.error(errorMsg); + throw new BadRequestException(errorMsg); + } else { + permissionDao.deletePermissionTemplate(permissionTemplateDto.getId()); + } + } + + public void addUserPermission(String templateName, String permission, final String userLogin) { + PermissionTemplateUpdater updater = new PermissionTemplateUpdater(templateName, permission, userLogin, permissionDao, userDao) { + @Override + protected void doExecute(Long templateId, String permission) { + Long userId = getUserId(); + permissionDao.addUserPermission(templateId, userId, permission); + } + }; + updater.executeUpdate(); + } + + public void removeUserPermission(String templateName, String permission, String userLogin) { + PermissionTemplateUpdater updater = new PermissionTemplateUpdater(templateName, permission, userLogin, permissionDao, userDao) { + @Override + protected void doExecute(Long templateId, String permission) { + Long userId = getUserId(); + permissionDao.removeUserPermission(templateId, userId, permission); + } + }; + updater.executeUpdate(); + } + + public void addGroupPermission(String templateName, String permission, String groupName) { + PermissionTemplateUpdater updater = new PermissionTemplateUpdater(templateName, permission, groupName, permissionDao, userDao) { + @Override + protected void doExecute(Long templateId, String permission) { + Long groupId = getGroupId(); + permissionDao.addGroupPermission(templateId, groupId, permission); + } + }; + updater.executeUpdate(); + } + + public void removeGroupPermission(String templateName, String permission, String groupName) { + PermissionTemplateUpdater updater = new PermissionTemplateUpdater(templateName, permission, groupName, permissionDao, userDao) { + @Override + protected void doExecute(Long templateId, String permission) { + Long groupId = getGroupId(); + permissionDao.removeGroupPermission(templateId, groupId, permission); + } + }; + updater.executeUpdate(); + } + + private void checkThatTemplateNameIsUnique(String name) { + List<PermissionTemplateDto> existingTemplates = permissionDao.selectAllPermissionTemplates(); + for (PermissionTemplateDto existingTemplate : existingTemplates) { + if(existingTemplate.getName().equals(name)) { + String errorMsg = "A template with that name already exists"; + LOG.error(errorMsg); + throw new BadRequestException(errorMsg); + } + } + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplate.java b/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplate.java new file mode 100644 index 00000000000..97054b98576 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplate.java @@ -0,0 +1,91 @@ +/* + * 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.permission; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Multimap; +import org.sonar.core.user.PermissionTemplateDto; +import org.sonar.core.user.PermissionTemplateGroupDto; +import org.sonar.core.user.PermissionTemplateUserDto; + +import java.util.List; + +public class PermissionTemplate { + + private final Long id; + private final String name; + private final String description; + private Multimap<String, String> usersByPermission; + private Multimap<String, String> groupsByPermission; + + private PermissionTemplate(Long id, String name, String description) { + this.id = id; + this.name = name; + this.description = description; + usersByPermission = HashMultimap.create(); + groupsByPermission = HashMultimap.create(); + } + + public static PermissionTemplate create(PermissionTemplateDto permissionTemplateDto) { + PermissionTemplate permissionTemplate = + new PermissionTemplate(permissionTemplateDto.getId(), permissionTemplateDto.getName(), permissionTemplateDto.getDescription()); + if(permissionTemplateDto.getUsersPermissions() != null) { + for (PermissionTemplateUserDto userPermission : permissionTemplateDto.getUsersPermissions()) { + permissionTemplate.registerUserPermission(userPermission.getPermission(), userPermission.getUserName()); + } + } + if(permissionTemplateDto.getGroupsPermissions() != null) { + for (PermissionTemplateGroupDto groupPermission : permissionTemplateDto.getGroupsPermissions()) { + permissionTemplate.registerGroupPermission(groupPermission.getPermission(), groupPermission.getGroupName()); + } + } + return permissionTemplate; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public List<String> getUsersForPermission(String permission) { + return ImmutableList.copyOf(usersByPermission.get(permission)); + } + + public List<String> getGroupsForPermission(String permission) { + return ImmutableList.copyOf(groupsByPermission.get(permission)); + } + + private void registerUserPermission(String permission, String userName) { + usersByPermission.put(permission, userName); + } + + private void registerGroupPermission(String permission, String groupName) { + groupsByPermission.put(permission, groupName); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateUpdater.java b/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateUpdater.java new file mode 100644 index 00000000000..24ac25b5e56 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateUpdater.java @@ -0,0 +1,87 @@ +/* + * 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.permission; + +import org.sonar.core.user.*; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.user.UserSession; + +abstract class PermissionTemplateUpdater { + + private final String templateName; + private final String permission; + private final String updatedReference; + private final PermissionDao permissionDao; + private final UserDao userDao; + + PermissionTemplateUpdater(String templateName, String permission, String updatedReference, PermissionDao permissionDao, UserDao userDao) { + this.templateName = templateName; + this.permission = permission; + this.updatedReference = updatedReference; + this.permissionDao = permissionDao; + this.userDao = userDao; + } + + void executeUpdate() { + checkUserCredentials(); + Long templateId = getTemplateId(templateName); + validatePermission(permission); + doExecute(templateId, permission); + } + + abstract void doExecute(Long templateId, String permission); + + Long getUserId() { + UserDto userDto = userDao.selectActiveUserByLogin(updatedReference); + if(userDto == null) { + throw new BadRequestException("Unknown user: " + updatedReference); + } + return userDto.getId(); + } + + Long getGroupId() { + GroupDto groupDto = userDao.selectGroupByName(updatedReference); + if(groupDto == null) { + throw new BadRequestException("Unknown group: " + updatedReference); + } + return groupDto.getId(); + } + + static void checkUserCredentials() { + UserSession currentSession = UserSession.get(); + currentSession.checkLoggedIn(); + currentSession.checkGlobalPermission(Permission.SYSTEM_ADMIN); + } + + private void validatePermission(String permission) { + if(!Permission.isValid(permission)) { + throw new BadRequestException("Invalid permission: " + permission); + } + } + + private Long getTemplateId(String name) { + PermissionTemplateDto permissionTemplateDto = permissionDao.selectTemplateByName(name); + if(permissionTemplateDto == null) { + throw new BadRequestException("Unknown template: " + name); + } + return permissionTemplateDto.getId(); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java b/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java new file mode 100644 index 00000000000..7abe57e7496 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionTemplateServiceTest.java @@ -0,0 +1,208 @@ +/* + * 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.permission; + +import com.google.common.collect.Lists; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.core.user.*; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.user.MockUserSession; + +import java.util.List; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.*; + +public class InternalPermissionTemplateServiceTest { + + private static final String DEFAULT_NAME = "my template"; + private static final String DEFAULT_DESC = "my description"; + private static final String DEFAULT_PERMISSION = Permission.DRY_RUN_EXECUTION.key(); + private static final PermissionTemplateDto DEFAULT_TEMPLATE = + new PermissionTemplateDto().setId(1L).setName(DEFAULT_NAME).setDescription(DEFAULT_DESC); + + private PermissionDao permissionDao; + private UserDao userDao; + private InternalPermissionTemplateService permissionTemplateService; + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Before + public void setUp() { + MockUserSession.set().setLogin("admin").setPermissions(Permission.SYSTEM_ADMIN); + permissionDao = mock(PermissionDao.class); + userDao = mock(UserDao.class); + permissionTemplateService = new InternalPermissionTemplateService(permissionDao, userDao); + } + + @Test + public void should_create_permission_template() throws Exception { + when(permissionDao.createPermissionTemplate(DEFAULT_NAME, DEFAULT_DESC)).thenReturn(DEFAULT_TEMPLATE); + + PermissionTemplate permissionTemplate = permissionTemplateService.createPermissionTemplate(DEFAULT_NAME, DEFAULT_DESC); + + assertThat(permissionTemplate.getId()).isEqualTo(1L); + assertThat(permissionTemplate.getName()).isEqualTo(DEFAULT_NAME); + assertThat(permissionTemplate.getDescription()).isEqualTo(DEFAULT_DESC); + } + + @Test + public void should_enforce_unique_template_name() throws Exception { + expected.expect(BadRequestException.class); + expected.expectMessage("A template with that name already exists"); + + when(permissionDao.selectAllPermissionTemplates()).thenReturn(Lists.newArrayList(DEFAULT_TEMPLATE)); + + permissionTemplateService.createPermissionTemplate(DEFAULT_NAME, DEFAULT_DESC); + } + + @Test + public void should_delete_permission_template() throws Exception { + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + + permissionTemplateService.deletePermissionTemplate(DEFAULT_NAME); + + verify(permissionDao, times(1)).deletePermissionTemplate(1L); + } + + @Test + public void should_validate_template_name_on_deletion() throws Exception { + expected.expect(BadRequestException.class); + expected.expectMessage("Unknown template:"); + + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(null); + + permissionTemplateService.deletePermissionTemplate(DEFAULT_NAME); + } + + @Test + public void should_retrieve_permission_template() throws Exception { + + List<PermissionTemplateUserDto> usersPermissions = Lists.newArrayList( + buildUserPermission("user_scan", Permission.SCAN_EXECUTION.key()), + buildUserPermission("user_dry_run", Permission.DRY_RUN_EXECUTION.key()), + buildUserPermission("user_scan_and_dry_run", Permission.SCAN_EXECUTION.key()), + buildUserPermission("user_scan_and_dry_run", Permission.DRY_RUN_EXECUTION.key()) + ); + + List<PermissionTemplateGroupDto> groupsPermissions = Lists.newArrayList( + buildGroupPermission("admin_group", Permission.SYSTEM_ADMIN.key()), + buildGroupPermission("scan_group", Permission.SCAN_EXECUTION.key()), + buildGroupPermission(null, Permission.DRY_RUN_EXECUTION.key()) + ); + + PermissionTemplateDto permissionTemplateDto = new PermissionTemplateDto() + .setId(1L) + .setName("my template") + .setDescription("my description") + .setUsersPermissions(usersPermissions) + .setGroupsByPermission(groupsPermissions); + + when(permissionDao.selectPermissionTemplate("my template")).thenReturn(permissionTemplateDto); + + PermissionTemplate permissionTemplate = permissionTemplateService.selectPermissionTemplate("my template"); + + assertThat(permissionTemplate.getUsersForPermission(Permission.DASHBOARD_SHARING.key())).isEmpty(); + assertThat(permissionTemplate.getUsersForPermission(Permission.SCAN_EXECUTION.key())).containsOnly("user_scan", "user_scan_and_dry_run"); + assertThat(permissionTemplate.getUsersForPermission(Permission.DRY_RUN_EXECUTION.key())).containsOnly("user_dry_run", "user_scan_and_dry_run"); + assertThat(permissionTemplate.getGroupsForPermission(Permission.DASHBOARD_SHARING.key())).isEmpty(); + assertThat(permissionTemplate.getGroupsForPermission(Permission.SCAN_EXECUTION.key())).containsOnly("scan_group"); + assertThat(permissionTemplate.getGroupsForPermission(Permission.SYSTEM_ADMIN.key())).containsOnly("admin_group"); + } + + @Test + public void should_add_user_permission() throws Exception { + UserDto userDto = new UserDto().setId(1L).setLogin("user").setName("user"); + when(userDao.selectActiveUserByLogin("user")).thenReturn(userDto); + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + + permissionTemplateService.addUserPermission(DEFAULT_NAME, DEFAULT_PERMISSION, "user"); + + verify(permissionDao, times(1)).addUserPermission(1L, 1L, DEFAULT_PERMISSION); + } + + @Test + public void should_validate_provided_user_login() throws Exception { + expected.expect(BadRequestException.class); + expected.expectMessage("Unknown user:"); + + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + when(userDao.selectActiveUserByLogin("unknown")).thenReturn(null); + + permissionTemplateService.addUserPermission(DEFAULT_NAME, DEFAULT_PERMISSION, "unknown"); + } + + @Test + public void should_remove_user_permission() throws Exception { + UserDto userDto = new UserDto().setId(1L).setLogin("user").setName("user"); + when(userDao.selectActiveUserByLogin("user")).thenReturn(userDto); + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + + permissionTemplateService.removeUserPermission(DEFAULT_NAME, DEFAULT_PERMISSION, "user"); + + verify(permissionDao, times(1)).removeUserPermission(1L, 1L, DEFAULT_PERMISSION); + } + + @Test + public void should_add_group_permission() throws Exception { + GroupDto groupDto = new GroupDto().setId(1L).setName("group"); + when(userDao.selectGroupByName("group")).thenReturn(groupDto); + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + + permissionTemplateService.addGroupPermission(DEFAULT_NAME, DEFAULT_PERMISSION, "group"); + + verify(permissionDao, times(1)).addGroupPermission(1L, 1L, DEFAULT_PERMISSION); + } + + @Test + public void should_validate_provided_group_name() throws Exception { + expected.expect(BadRequestException.class); + expected.expectMessage("Unknown group:"); + + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + when(userDao.selectGroupByName("unknown")).thenReturn(null); + + permissionTemplateService.addGroupPermission(DEFAULT_NAME, DEFAULT_PERMISSION, "unknown"); + } + + @Test + public void should_remove_group_permission() throws Exception { + GroupDto groupDto = new GroupDto().setId(1L).setName("group"); + when(userDao.selectGroupByName("group")).thenReturn(groupDto); + when(permissionDao.selectTemplateByName(DEFAULT_NAME)).thenReturn(DEFAULT_TEMPLATE); + + permissionTemplateService.removeGroupPermission(DEFAULT_NAME, DEFAULT_PERMISSION, "group"); + + verify(permissionDao, times(1)).removeGroupPermission(1L, 1L, DEFAULT_PERMISSION); + } + + private PermissionTemplateUserDto buildUserPermission(String userName, String permission) { + return new PermissionTemplateUserDto().setUserName(userName).setPermission(permission); + } + + private PermissionTemplateGroupDto buildGroupPermission(String groupName, String permission) { + return new PermissionTemplateGroupDto().setGroupName(groupName).setPermission(permission); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateTest.java b/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateTest.java new file mode 100644 index 00000000000..3b23c4b7160 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateTest.java @@ -0,0 +1,60 @@ +/* + * 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.permission; + +import com.google.common.collect.Lists; +import org.junit.Test; +import org.sonar.core.user.PermissionTemplateDto; +import org.sonar.core.user.PermissionTemplateGroupDto; +import org.sonar.core.user.PermissionTemplateUserDto; + +import static org.fest.assertions.Assertions.assertThat; + +public class PermissionTemplateTest { + + @Test + public void should_populate_template_with_permissions() throws Exception { + + PermissionTemplateDto permissionTemplateDto = new PermissionTemplateDto() + .setId(1L) + .setName("name") + .setDescription("description") + .setUsersPermissions(Lists.newArrayList( + new PermissionTemplateUserDto().setId(1L).setUserName("user1").setPermission("permission1"), + new PermissionTemplateUserDto().setId(2L).setUserName("user1").setPermission("permission2"), + new PermissionTemplateUserDto().setId(3L).setUserName("user2").setPermission("permission1") + )) + .setGroupsByPermission(Lists.newArrayList( + new PermissionTemplateGroupDto().setId(1L).setGroupName("group1").setPermission("permission3"), + new PermissionTemplateGroupDto().setId(2L).setGroupName("group2").setPermission("permission3") + )); + + PermissionTemplate permissionTemplate = PermissionTemplate.create(permissionTemplateDto); + + assertThat(permissionTemplate.getId()).isEqualTo(1L); + assertThat(permissionTemplate.getName()).isEqualTo("name"); + assertThat(permissionTemplate.getDescription()).isEqualTo("description"); + assertThat(permissionTemplate.getUsersForPermission("unmatchedPermission")).isEmpty(); + assertThat(permissionTemplate.getUsersForPermission("permission1")).containsOnly("user1", "user2"); + assertThat(permissionTemplate.getUsersForPermission("permission2")).containsOnly("user1"); + assertThat(permissionTemplate.getGroupsForPermission("permission3")).containsOnly("group1", "group2"); + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateUpdaterTest.java b/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateUpdaterTest.java new file mode 100644 index 00000000000..9af7eeb66ab --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateUpdaterTest.java @@ -0,0 +1,134 @@ +/* + * 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.permission; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.core.user.*; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.user.MockUserSession; + +import static org.mockito.Mockito.*; + +public class PermissionTemplateUpdaterTest { + + private static final UserDto DEFAULT_USER = new UserDto().setId(1L).setLogin("user").setName("user"); + private static final GroupDto DEFAULT_GROUP = new GroupDto().setId(1L).setName("group"); + + private UserDao userDao; + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Before + public void setUpCommonMocks() { + MockUserSession.set().setLogin("admin").setPermissions(Permission.SYSTEM_ADMIN); + userDao = mock(UserDao.class); + stub(userDao.selectActiveUserByLogin("user")).toReturn(DEFAULT_USER); + stub(userDao.selectGroupByName("group")).toReturn(DEFAULT_GROUP); + } + + @Test + public void should_execute_on_valid_parameters() throws Exception { + + final PermissionDao permissionDao = mock(PermissionDao.class); + when(permissionDao.selectTemplateByName("my template")).thenReturn(new PermissionTemplateDto().setId(1L)); + + PermissionTemplateUpdater updater = + new PermissionTemplateUpdater("my template", Permission.SCAN_EXECUTION.key(), "user", permissionDao, userDao) { + @Override + void doExecute(Long templateId, String permission) { + permissionDao.addUserPermission(1L, 1L, Permission.SCAN_EXECUTION.key()); + } + }; + updater.executeUpdate(); + + verify(permissionDao, times(1)).addUserPermission(1L, 1L, Permission.SCAN_EXECUTION.key()); + } + + @Test + public void should_validate_template_reference() throws Exception { + expected.expect(BadRequestException.class); + expected.expectMessage("Unknown template:"); + + final PermissionDao permissionDao = mock(PermissionDao.class); + when(permissionDao.selectTemplateByName("my template")).thenReturn(null); + + PermissionTemplateUpdater updater = + new PermissionTemplateUpdater("my template", Permission.SCAN_EXECUTION.key(), "user", permissionDao, userDao) { + @Override + void doExecute(Long templateId, String permission) { + } + }; + updater.executeUpdate(); + } + + @Test + public void should_validate_permission_reference() throws Exception { + expected.expect(BadRequestException.class); + expected.expectMessage("Invalid permission:"); + + final PermissionDao permissionDao = mock(PermissionDao.class); + when(permissionDao.selectTemplateByName("my template")).thenReturn(new PermissionTemplateDto().setId(1L)); + + PermissionTemplateUpdater updater = + new PermissionTemplateUpdater("my template", "invalid", "user", permissionDao, userDao) { + @Override + void doExecute(Long templateId, String permission) { + } + }; + updater.executeUpdate(); + } + + @Test + public void should_check_that_user_is_logged_in() throws Exception { + expected.expect(UnauthorizedException.class); + expected.expectMessage("Authentication is required"); + + MockUserSession.set(); + + PermissionTemplateUpdater updater = new PermissionTemplateUpdater(null, null, null, null, null) { + @Override + void doExecute(Long templateId, String permission) { + } + }; + updater.executeUpdate(); + } + + @Test + public void should_check_that_user_is_a_system_admin() throws Exception { + expected.expect(ForbiddenException.class); + expected.expectMessage("Insufficient privileges"); + + MockUserSession.set().setLogin("user").setPermissions(Permission.SCAN_EXECUTION); + + PermissionTemplateUpdater updater = new PermissionTemplateUpdater(null, null, null, null, null) { + @Override + void doExecute(Long templateId, String permission) { + } + }; + updater.executeUpdate(); + } +} |