projects_role.user.desc=Ability to browse the measures and to create/edit issues on the project.
projects_role.codeviewer=Role: Code Viewers
projects_role.codeviewer.desc=Ability to view the source code of the project.
+projects_role.apply_template=Apply permission template
#------------------------------------------------------------------------------
--- /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.core.permission;
+
+import org.apache.ibatis.session.SqlSession;
+import org.sonar.api.ServerExtension;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.task.TaskExtension;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.user.*;
+
+import java.util.List;
+
+/**
+ * Internal use only
+ * @since 3.7
+ *
+ * This facade wraps all the db operations related to component-based permissions
+ */
+public class ComponentPermissionFacade implements TaskExtension, ServerExtension {
+
+ private final MyBatis myBatis;
+ private final RoleDao roleDao;
+ private final UserDao userDao;
+ private final PermissionDao permissionDao;
+
+ public ComponentPermissionFacade(MyBatis myBatis, RoleDao roleDao, UserDao userDao, PermissionDao permissionDao) {
+ this.myBatis = myBatis;
+ this.roleDao = roleDao;
+ this.userDao = userDao;
+ this.permissionDao = permissionDao;
+ }
+
+ public void setUserPermission(Long resourceId, String userLogin, String permission) {
+ SqlSession session = myBatis.openSession();
+ try {
+ UserDto user = session.getMapper(UserMapper.class).selectUserByLogin(userLogin);
+ if (user != null) {
+ UserRoleDto userRole = new UserRoleDto()
+ .setRole(permission)
+ .setUserId(user.getId())
+ .setResourceId(Long.valueOf(resourceId));
+ roleDao.deleteUserRole(userRole, session);
+ roleDao.insertUserRole(userRole, session);
+ session.commit();
+ }
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public void setGroupPermission(Long resourceId, String groupName, String permission) {
+ SqlSession session = myBatis.openSession();
+ try {
+ GroupRoleDto groupRole = new GroupRoleDto()
+ .setRole(permission)
+ .setResourceId(Long.valueOf(resourceId));
+ if (DefaultGroups.isAnyone(groupName)) {
+ roleDao.deleteGroupRole(groupRole, session);
+ roleDao.insertGroupRole(groupRole, session);
+ session.commit();
+ } else {
+ GroupDto group = userDao.selectGroupByName(groupName, session);
+ if (group != null) {
+ groupRole.setGroupId(group.getId());
+ roleDao.deleteGroupRole(groupRole, session);
+ roleDao.insertGroupRole(groupRole, session);
+ session.commit();
+ }
+ }
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public int countPermissions(Long resourceId) {
+ return roleDao.countGroupRoles(resourceId) + roleDao.countUserRoles(resourceId);
+ }
+
+ public void removeAllPermissions(Long resourceId, SqlSession session) {
+ roleDao.deleteGroupRolesByResourceId(resourceId, session);
+ roleDao.deleteUserRolesByResourceId(resourceId, session);
+ }
+
+ public void addUserPermission(Long resourceId, String userLogin, String permission, SqlSession session) {
+ UserDto user = userDao.selectActiveUserByLogin(userLogin, session);
+ if (user != null) {
+ UserRoleDto userRoleDto = new UserRoleDto().setRole(permission).setUserId(user.getId()).setResourceId(resourceId);
+ roleDao.insertUserRole(userRoleDto, session);
+ }
+ }
+
+ public void addGroupPermission(Long resourceId, String groupName, String permission, SqlSession session) {
+ GroupRoleDto groupRole = new GroupRoleDto().setRole(permission).setResourceId(resourceId);
+ if (DefaultGroups.isAnyone(groupName)) {
+ roleDao.insertGroupRole(groupRole, session);
+ } else {
+ GroupDto group = userDao.selectGroupByName(groupName, session);
+ if (group != null) {
+ roleDao.insertGroupRole(groupRole.setGroupId(group.getId()), session);
+ }
+ }
+ }
+
+ public PermissionTemplateDto getPermissionTemplate(Long templateId) {
+ PermissionTemplateDto permissionTemplateDto = permissionDao.selectTemplateById(templateId);
+ if(permissionTemplateDto == null) {
+ throw new IllegalArgumentException("Could not retrieve permission template with id " + templateId);
+ }
+ PermissionTemplateDto templateWithPermissions = permissionDao.selectPermissionTemplate(permissionTemplateDto.getName());
+ if(templateWithPermissions == null) {
+ throw new IllegalArgumentException("Could not retrieve permissions for template with id " + templateId);
+ }
+ return templateWithPermissions;
+ }
+
+ public void applyPermissionTemplate(Long templateId, Long resourceId) {
+ SqlSession session = myBatis.openSession();
+ try {
+ PermissionTemplateDto permissionTemplate = getPermissionTemplate(templateId);
+ List<PermissionTemplateUserDto> usersPermissions = permissionTemplate.getUsersPermissions();
+ if(usersPermissions != null) {
+ for (PermissionTemplateUserDto userPermission : usersPermissions) {
+ addUserPermission(resourceId, userPermission.getUserLogin(), userPermission.getPermission(), session);
+
+ }
+ }
+ List<PermissionTemplateGroupDto> groupsPermissions = permissionTemplate.getGroupsPermissions();
+ if(groupsPermissions != null) {
+ for (PermissionTemplateGroupDto groupPermission : groupsPermissions) {
+ addGroupPermission(resourceId, groupPermission.getGroupName(), groupPermission.getPermission(), session);
+ }
+ }
+ session.commit();
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+}
--- /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.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.core.permission;
+
+import javax.annotation.ParametersAreNonnullByDefault;
\ No newline at end of file
import org.sonar.api.security.ResourcePermissions;
import org.sonar.api.task.TaskExtension;
import org.sonar.api.web.UserRole;
+import org.sonar.core.permission.ComponentPermissionFacade;
import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.user.*;
+import org.sonar.core.user.PermissionTemplateDto;
+import org.sonar.core.user.PermissionTemplateGroupDto;
+import org.sonar.core.user.PermissionTemplateUserDto;
import java.util.ArrayList;
import java.util.List;
private final Settings settings;
private final MyBatis myBatis;
- private final RoleDao roleDao;
- private final UserDao userDao;
- private final PermissionDao permissionDao;
+ private final ComponentPermissionFacade permissionFacade;
- public DefaultResourcePermissions(Settings settings, MyBatis myBatis, RoleDao roleDao, UserDao userDao, PermissionDao permissionDao) {
+ public DefaultResourcePermissions(Settings settings, MyBatis myBatis, ComponentPermissionFacade permissionFacade) {
this.settings = settings;
this.myBatis = myBatis;
- this.roleDao = roleDao;
- this.userDao = userDao;
- this.permissionDao = permissionDao;
+ this.permissionFacade = permissionFacade;
}
public boolean hasRoles(Resource resource) {
if (resource.getId() != null) {
Long resourceId = Long.valueOf(resource.getId());
- return roleDao.countGroupRoles(resourceId) + roleDao.countUserRoles(resourceId) > 0;
+ return permissionFacade.countPermissions(resourceId) > 0;
}
return false;
}
public void grantUserRole(Resource resource, String login, String role) {
if (resource.getId() != null) {
- SqlSession session = myBatis.openSession();
- try {
- UserDto user = session.getMapper(UserMapper.class).selectUserByLogin(login);
- if (user != null) {
- UserRoleDto userRole = new UserRoleDto()
- .setRole(role)
- .setUserId(user.getId())
- .setResourceId(Long.valueOf(resource.getId()));
- roleDao.deleteUserRole(userRole, session);
- roleDao.insertUserRole(userRole, session);
- session.commit();
- }
- } finally {
- MyBatis.closeQuietly(session);
- }
+ permissionFacade.setUserPermission(Long.valueOf(resource.getId()), login, role);
}
}
public void grantGroupRole(Resource resource, String groupName, String role) {
if (resource.getId() != null) {
- SqlSession session = myBatis.openSession();
- try {
- GroupRoleDto groupRole = new GroupRoleDto()
- .setRole(role)
- .setResourceId(Long.valueOf(resource.getId()));
- if (DefaultGroups.isAnyone(groupName)) {
- roleDao.deleteGroupRole(groupRole, session);
- roleDao.insertGroupRole(groupRole, session);
- session.commit();
- } else {
- GroupDto group = userDao.selectGroupByName(groupName, session);
- if (group != null) {
- groupRole.setGroupId(group.getId());
- roleDao.deleteGroupRole(groupRole, session);
- roleDao.insertGroupRole(groupRole, session);
- session.commit();
- }
- }
- } finally {
- MyBatis.closeQuietly(session);
- }
+ permissionFacade.setGroupPermission(Long.valueOf(resource.getId()), groupName, role);
}
}
private void removeRoles(Resource resource, SqlSession session) {
Long resourceId = Long.valueOf(resource.getId());
- roleDao.deleteGroupRolesByResourceId(resourceId, session);
- roleDao.deleteUserRolesByResourceId(resourceId, session);
+ permissionFacade.removeAllPermissions(resourceId, session);
}
private void grantDefaultRoles(Resource resource, String role, SqlSession session) {
List<String> groupNames = getEligibleGroups(role, applicablePermissionTemplate);
for (String groupName : groupNames) {
- GroupRoleDto groupRole = new GroupRoleDto().setRole(role).setResourceId(Long.valueOf(resource.getId()));
- if (DefaultGroups.isAnyone(groupName)) {
- roleDao.insertGroupRole(groupRole, session);
- } else {
- GroupDto group = userDao.selectGroupByName(groupName, session);
- if (group != null) {
- roleDao.insertGroupRole(groupRole.setGroupId(group.getId()), session);
- }
- }
+ Long resourceId = Long.valueOf(resource.getId());
+ permissionFacade.addGroupPermission(resourceId, groupName, role, session);
}
List<String> logins = getEligibleUsers(role, applicablePermissionTemplate);
for (String login : logins) {
- UserDto user = userDao.selectActiveUserByLogin(login, session);
- if (user != null) {
- UserRoleDto userRoleDto = new UserRoleDto().setRole(role).setUserId(user.getId()).setResourceId(Long.valueOf(resource.getId()));
- roleDao.insertUserRole(userRoleDto, session);
- }
+ Long resourceId = Long.valueOf(resource.getId());
+ permissionFacade.addUserPermission(resourceId, login, role, session);
}
}
private PermissionTemplateDto getPermissionTemplate(String qualifier) {
String qualifierTemplateId = settings.getString("sonar.permission.template." + qualifier + ".default");
if(!StringUtils.isBlank(qualifierTemplateId)) {
- return getTemplateWithPermissions(qualifierTemplateId);
+ Long templateId = Long.parseLong(qualifierTemplateId);
+ return permissionFacade.getPermissionTemplate(templateId);
}
String defaultTemplateId = settings.getString("sonar.permission.template.default");
if(StringUtils.isBlank(defaultTemplateId)) {
throw new IllegalStateException("At least one default permission template should be defined");
}
- return getTemplateWithPermissions(defaultTemplateId);
- }
-
- private PermissionTemplateDto getTemplateWithPermissions(String templateId) {
- PermissionTemplateDto permissionTemplateDto = permissionDao.selectTemplateById(Long.parseLong(templateId));
- if(permissionTemplateDto == null) {
- throw new IllegalArgumentException("Could not retrieve permission template with id " + templateId);
- }
- PermissionTemplateDto templateWithPermissions = permissionDao.selectPermissionTemplate(permissionTemplateDto.getName());
- if(templateWithPermissions == null) {
- throw new IllegalArgumentException("Could not retrieve permissions for template with id " + templateId);
- }
- return templateWithPermissions;
+ Long templateId = Long.parseLong(defaultTemplateId);
+ return permissionFacade.getPermissionTemplate(templateId);
}
}
--- /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.core.permission;
+
+public class ComponentPermissionFacadeTest {
+}
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.security.DefaultGroups;
+import org.sonar.core.permission.ComponentPermissionFacade;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.user.PermissionDao;
import org.sonar.core.user.RoleDao;
@Before
public void initResourcePermissions() {
settings = new Settings();
- permissions = new DefaultResourcePermissions(settings, getMyBatis(),
+ ComponentPermissionFacade permissionFacade = new ComponentPermissionFacade(getMyBatis(),
new RoleDao(getMyBatis()), new UserDao(getMyBatis()), new PermissionDao(getMyBatis()));
+ permissions = new DefaultResourcePermissions(settings, getMyBatis(), permissionFacade);
}
@Test
--- /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.permission;
+
+import org.picocontainer.annotations.Nullable;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.util.RubyUtils;
+
+import java.util.List;
+import java.util.Map;
+
+public class ApplyPermissionTemplateQuery {
+
+ private static final String TEMPLATE_ID = "template_id";
+ private static final String COMPONENTS_KEY = "components";
+
+ private final Long templateId;
+ private List<String> selectedComponents;
+
+ private ApplyPermissionTemplateQuery(@Nullable Long templateId) {
+ this.templateId= templateId;
+ }
+
+ public static ApplyPermissionTemplateQuery buildFromParams(Map<String, Object> params) {
+ ApplyPermissionTemplateQuery query = new ApplyPermissionTemplateQuery(RubyUtils.toLong(params.get(TEMPLATE_ID)));
+ query.setSelectedComponents(RubyUtils.toStrings(params.get(COMPONENTS_KEY)));
+ return query;
+ }
+
+ public Long getTemplateId() {
+ return templateId;
+ }
+
+ public List<String> getSelectedComponents() {
+ return selectedComponents;
+ }
+
+ public void validate() {
+ if(templateId == null) {
+ throw new BadRequestException("Permission template is mandatory");
+ }
+ if(selectedComponents == null || selectedComponents.isEmpty()) {
+ throw new BadRequestException("Please provide at least one entry to which the permission template should be applied");
+ }
+ }
+
+ private void setSelectedComponents(List<String> selectedComponents) {
+ this.selectedComponents = selectedComponents;
+ }
+}
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerComponent;
import org.sonar.api.security.DefaultGroups;
+import org.sonar.core.permission.ComponentPermissionFacade;
import org.sonar.core.user.*;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.user.UserSession;
private final RoleDao roleDao;
private final UserDao userDao;
+ private final ComponentPermissionFacade permissionFacade;
- public InternalPermissionService(RoleDao roleDao, UserDao userDao) {
+ public InternalPermissionService(RoleDao roleDao, UserDao userDao, ComponentPermissionFacade permissionFacade) {
this.roleDao = roleDao;
this.userDao = userDao;
+ this.permissionFacade = permissionFacade;
}
public void addPermission(final Map<String, Object> params) {
changePermission(REMOVE, params);
}
+ public void applyPermissionTemplate(Map<String, Object> params) {
+ UserSession.get().checkLoggedIn();
+ UserSession.get().checkGlobalPermission(Permission.SYSTEM_ADMIN);
+ ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.buildFromParams(params);
+ query.validate();
+ for (String component : query.getSelectedComponents()) {
+ applyPermissionTemplate(query.getTemplateId(), component);
+ }
+ }
+
+ private void applyPermissionTemplate(Long templateId, String componentId) {
+ permissionFacade.applyPermissionTemplate(templateId, Long.parseLong(componentId));
+ }
+
private void changePermission(String permissionChange, Map<String, Object> params) {
UserSession.get().checkLoggedIn();
UserSession.get().checkGlobalPermission(Permission.SYSTEM_ADMIN);
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.util.List;
+import java.util.Map;
/**
* Used by ruby code <pre>Internal.permission_templates</pre>
}
};
updater.executeUpdate();
+ }
+
+ public void applyPermissionTemplate(String templateName, Map<String, Object> params) {
+
+
+
}
private void validateTemplateName(Long templateId, String templateName) {
}
throw new IllegalArgumentException("Unsupported type for boolean: " + o.getClass());
}
+
+ @CheckForNull
+ public static Long toLong(@Nullable Object o) {
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof Integer) {
+ return ((Integer)o).longValue();
+ }
+ if (o instanceof Long) {
+ return ((Long) o);
+ }
+ if (o instanceof String) {
+ if (StringUtils.isBlank((String)o)) {
+ return null;
+ }
+ return Long.parseLong((String) o);
+ }
+ throw new IllegalArgumentException("Unsupported type for long: " + o.getClass());
+ }
}
templates_names.each do |template_name|
permission_template = Internal.permission_templates.selectPermissionTemplate(template_name)
@permission_templates << permission_template
- @permission_templates_options << [permission_template.name, permission_template.id]
+ @permission_templates_options << [permission_template.name, permission_template.id.to_s]
end
@root_qualifiers = get_root_qualifiers
bad_request('Missing qualifier') if params[:qualifier].blank?
end
+ def bulk_apply_form
+ end
# POST REQUESTS
redirect
end
+ def bulk_apply_template
+ verify_post_request
+ require_parameters :name
+ Internal.permissions.applyPermissionTemplate(params)
+
+ redirect_to :action => 'projects'
+ end
+
private
+
def redirect
redirect_to(:action => params['redirect'] || 'global', :q => params[:q], :qualifier => params[:qualifier], :page => params[:page])
end
+
end
<% @root_qualifiers.each do |qualifier| %>
<%= label_tag("default_template_#{qualifier}", "Default permission template for #{message('qualifier.' + qualifier)}:") %>
<%= select_tag("default_template_#{qualifier}", options_for_select(@permission_templates_options, @default_templates[qualifier])) %>
+ <br/>
<% end %>
<br/>
<br/>
-<h1 class="marginbottom10"><%= message('roles.page') -%></h1>
+<h1><%= message('roles.page') -%></h1>
<% if @qualifiers.size>1 %>
<ul class="tabs" id="qualifier-tabs">
<div class="tabs-panel">
<% end %>
-<table class="data width100" id="default-project-roles">
- <thead>
- <tr>
- <th><%= message('projects_role.role') -%> <%= message("qualifiers.#{@qualifier}") -%></th>
- <th width="35%"><%= message('projects_role.users') -%></th>
- <th width="35%"><%= message('projects_role.groups') -%></th>
- </tr>
- </thead>
- <tbody>
-
- <tr class="even">
- <td valign="top"><b><%= message('projects_role.admin') -%></b><br/><span class="small gray"><%= message('projects_role.admin.desc') -%></span>
- </td>
- <td valign="top" style="word-break:break-all;width:35%;">
- <div style="vertical-align:top">
- <span id="u-admin"><%= default_project_users('admin', @qualifier).map{|u| h u.name}.join(', ') -%></span>
- (<%= link_to "select", {:action => 'edit_default_project_users', :role => 'admin', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action', :id => 'selectu-admin' -%>)
- </div>
- </td>
- <td valign="top" style="word-break:break-all;width:35%;">
- <span id="g-admin"><%= default_project_group_names('admin', @qualifier).join(', ') -%></span>
- (<%= link_to "select", {:action => 'edit_default_project_groups', :role => 'admin', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action', :id => 'selectg-admin' -%>)
- </td>
- </tr>
- <tr class="odd">
- <td valign="top"><b><%= message('projects_role.user') -%></b><br/><span class="small gray"><%= message('projects_role.user.desc') -%></span>
- </td>
- <td valign="top" style="word-break:break-all;width:35%;">
- <span id="u-user"><%= default_project_users('user', @qualifier).map{|u| h u.name}.join(', ') -%></span>
- (<%= link_to "select", {:action => 'edit_default_project_users', :role => 'user', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action', :id => 'selectu-user' -%>)
- </td>
- <td valign="top" style="word-break:break-all;width:35%;">
- <span id="g-user"><%= default_project_group_names('user', @qualifier).join(', ') -%></span>
- (<%= link_to "select", {:action => 'edit_default_project_groups', :role => 'user', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action', :id => 'selectg-user' -%>)
- </td>
- </tr>
- <tr class="even">
- <td valign="top">
- <b><%= message('projects_role.codeviewer') -%></b><br/><span class="small gray"><%= message('projects_role.codeviewer.desc') -%></span></td>
- <td valign="top" style="word-break:break-all;width:35%;">
- <span id="u-codeviewer"><%= default_project_users('codeviewer', @qualifier).map{|u| h u.name}.join(', ') -%></span>
- (<%= link_to "select", {:action => 'edit_default_project_users', :role => 'codeviewer', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action', :id => 'selectu-codeviewer' -%>)
- </td>
- <td valign="top" style="word-break:break-all;width:35%;">
- <span id="g-codeviewer"><%= default_project_group_names('codeviewer', @qualifier).join(', ') -%></span>
- (<%= link_to "select", {:action => 'edit_default_project_groups', :role => 'codeviewer', :redirect => 'projects', :qualifier => @qualifier}, :class => 'link-action', :id => 'selectg-codeviewer' -%>)
- </td>
- </tr>
- </tbody>
-</table>
-
-
-<br/><br/>
+<div id="project-roles-operations" style="float: right;">
+ <ul class="operations">
+ <li class="last">
+ <a id="bulk-update" href="<%= url_for params.merge({:action => 'bulk_apply_form'}) -%>"
+ class="link-action open-modal"><%= message('projects_role.apply_template') -%></a>
+ </li>
+ </ul>
+</div>
-<table class="data width100" id="projects">
- <thead>
- <tr>
- <th>
- <form action="<%= url_for :action => 'projects', :qualifier => @qualifier -%>" method="GET">
- <input type="hidden" name="qualifier" value="<%= @qualifier -%>"/>
- <input type="text" name="q" value="<%= params[:q] -%>" id="search_text"/>
- <input type="submit" value="<%= message('search_verb') -%>" id="search_submit"/>
- </form>
- </th>
- <th><%= message('projects_role.admin') -%></th>
- <th><%= message('projects_role.user') -%></th>
- <th><%= message('projects_role.codeviewer') -%></th>
- </tr>
- </thead>
+ <table class="data width100" id="projects">
+ <thead>
+ <tr>
+ <th>
+ <form action="<%= url_for :action => 'projects', :qualifier => @qualifier -%>" method="GET">
+ <input type="hidden" name="qualifier" value="<%= @qualifier -%>"/>
+ <input type="text" name="q" value="<%= params[:q] -%>" id="search_text"/>
+ <input type="submit" value="<%= message('search_verb') -%>" id="search_submit"/>
+ </form>
+ </th>
+ <th><%= message('projects_role.admin') -%></th>
+ <th><%= message('projects_role.user') -%></th>
+ <th><%= message('projects_role.codeviewer') -%></th>
+ </tr>
+ </thead>
- <%= table_pagination(@pagination, :colspan => 4) { |label, page_id| link_to(label, params.merge({:page => page_id}))} -%>
+ <%= table_pagination(@pagination, :colspan => 4) { |label, page_id| link_to(label, params.merge({:page => page_id}))} -%>
- <tbody>
- <% if @projects.empty? %>
- <tr class="even">
- <td colspan="4" align="left"><%= message('no_results') %></td>
- </tr>
- <% end
+ <tbody>
+ <% if @projects.empty? %>
+ <tr class="even">
+ <td colspan="4" align="left"><%= message('no_results') %></td>
+ </tr>
+ <% end
- @projects.each do |project|
- %>
- <tr class="<%= cycle('even', 'odd') -%>">
- <td valign="top"><b><%= h project.name %></b><br/>
- <span class="small gray"><%= h project.key -%></span>
- </td>
- <td valign="top">
- <%
- users=Api::Utils.insensitive_sort(project.user_roles.select { |ur| ur.role=='admin' }.map { |ur| ur.user.name })
- groups=Api::Utils.insensitive_sort(project.group_roles.select { |gr| gr.role=='admin' }.map { |gr| group_name(gr.group) })
- %>
- <span id="u-admin-<%= u project.kee -%>"><%= users.join(', ') %></span>
- (<a href="<%= ApplicationController.root_context -%>/roles/edit_users?redirect=projects&role=admin&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectu-admin-<%= u project.kee -%>">select users</a>)<br/>
- <span id="g-admin-<%= u project.kee -%>"><%= groups.join(', ') %></span>
- (<a href="<%= ApplicationController.root_context -%>/roles/edit_groups?redirect=projects&role=admin&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectg-admin-<%= u project.kee -%>">select groups</a>)
- </td>
- <td valign="top">
- <%
- users=Api::Utils.insensitive_sort(project.user_roles.select { |ur| ur.role=='user' }.map { |ur| ur.user.name })
- groups=Api::Utils.insensitive_sort(project.group_roles.select { |gr| gr.role=='user' }.map { |gr| group_name(gr.group) })
- %>
- <span id="u-user-<%= u project.kee -%>"><%= users.join(', ') %></span>
- (<a href="<%= ApplicationController.root_context -%>/roles/edit_users?redirect=projects&role=user&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectu-user-<%= u project.kee -%>">select users</a>)<br/>
- <span id="g-user-<%= u project.kee -%>"><%= groups.join(', ') %></span>
- (<a href="<%= ApplicationController.root_context -%>/roles/edit_groups?redirect=projects&role=user&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectg-user-<%= u project.kee -%>">select groups</a>)
- </td>
- <td valign="top">
- <%
- users=Api::Utils.insensitive_sort(project.user_roles.select { |ur| ur.role=='codeviewer' }.map { |ur| ur.user.name })
- groups=Api::Utils.insensitive_sort(project.group_roles.select { |gr| gr.role=='codeviewer' }.map { |gr| group_name(gr.group) })
- %>
- <span id="u-codeviewer-<%= u project.kee -%>"><%= users.join(', ') %></span>
- (<a href="<%= ApplicationController.root_context -%>/roles/edit_users?redirect=projects&role=codeviewer&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectu-codeviewer-<%= u project.kee -%>">select users</a>)<br/>
- <span id="g-codeviewer-<%= u project.kee -%>"><%= groups.join(', ') %></span>
- (<a href="<%= ApplicationController.root_context -%>/roles/edit_groups?redirect=projects&role=codeviewer&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectg-codeviewer-<%= u project.kee -%>">select groups</a>)
- </td>
- </tr>
- <%
- end %>
- </tbody>
-</table>
+ @projects.each do |project|
+ %>
+ <tr class="<%= cycle('even', 'odd') -%>">
+ <td valign="top"><b><%= h project.name %></b><br/>
+ <span class="small gray"><%= h project.key -%></span>
+ </td>
+ <td valign="top">
+ <%
+ users=Api::Utils.insensitive_sort(project.user_roles.select { |ur| ur.role=='admin' }.map { |ur| ur.user.name })
+ groups=Api::Utils.insensitive_sort(project.group_roles.select { |gr| gr.role=='admin' }.map { |gr| group_name(gr.group) })
+ %>
+ <span id="u-admin-<%= u project.kee -%>"><%= users.join(', ') %></span>
+ (<a href="<%= ApplicationController.root_context -%>/roles/edit_users?redirect=projects&role=admin&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectu-admin-<%= u project.kee -%>">select users</a>)<br/>
+ <span id="g-admin-<%= u project.kee -%>"><%= groups.join(', ') %></span>
+ (<a href="<%= ApplicationController.root_context -%>/roles/edit_groups?redirect=projects&role=admin&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectg-admin-<%= u project.kee -%>">select groups</a>)
+ </td>
+ <td valign="top">
+ <%
+ users=Api::Utils.insensitive_sort(project.user_roles.select { |ur| ur.role=='user' }.map { |ur| ur.user.name })
+ groups=Api::Utils.insensitive_sort(project.group_roles.select { |gr| gr.role=='user' }.map { |gr| group_name(gr.group) })
+ %>
+ <span id="u-user-<%= u project.kee -%>"><%= users.join(', ') %></span>
+ (<a href="<%= ApplicationController.root_context -%>/roles/edit_users?redirect=projects&role=user&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectu-user-<%= u project.kee -%>">select users</a>)<br/>
+ <span id="g-user-<%= u project.kee -%>"><%= groups.join(', ') %></span>
+ (<a href="<%= ApplicationController.root_context -%>/roles/edit_groups?redirect=projects&role=user&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectg-user-<%= u project.kee -%>">select groups</a>)
+ </td>
+ <td valign="top">
+ <%
+ users=Api::Utils.insensitive_sort(project.user_roles.select { |ur| ur.role=='codeviewer' }.map { |ur| ur.user.name })
+ groups=Api::Utils.insensitive_sort(project.group_roles.select { |gr| gr.role=='codeviewer' }.map { |gr| group_name(gr.group) })
+ %>
+ <span id="u-codeviewer-<%= u project.kee -%>"><%= users.join(', ') %></span>
+ (<a href="<%= ApplicationController.root_context -%>/roles/edit_users?redirect=projects&role=codeviewer&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectu-codeviewer-<%= u project.kee -%>">select users</a>)<br/>
+ <span id="g-codeviewer-<%= u project.kee -%>"><%= groups.join(', ') %></span>
+ (<a href="<%= ApplicationController.root_context -%>/roles/edit_groups?redirect=projects&role=codeviewer&resource=<%= project.id -%>&q=<%= u params[:q] -%>&qualifier=<%= @qualifier -%>&page=<%= params[:page] -%>" class="link-action" id="selectg-codeviewer-<%= u project.kee -%>">select groups</a>)
+ </td>
+ </tr>
+ <%
+ end %>
+ </tbody>
+ </table>
-<% if @qualifiers.size>1 %></div><% end %>
+<% if @qualifiers.size>1 %>
+ </div>
+<% end %>
<script>
$('search_text').focus();
default_template = PermissionTemplate.create(
:name => 'Default template',
:description => 'This permission template will be used as default when no other permission configuration is available')
- puts('default template created')
sonar_admins_group = Group.find_by_name('sonar-administrators')
sonar_users_group = Group.find_by_name('sonar-users')
# sonar-administrators default permissions
if sonar_admins_group
PermissionTemplateGroup.create(:group_id => sonar_admins_group.id, :permission_reference => 'admin', :template_id => default_template.id)
- puts('admin template group created')
end
# sonar-users default permissions
if sonar_users_group
PermissionTemplateGroup.create(:group_id => sonar_users_group.id, :permission_reference => 'user', :template_id => default_template.id)
PermissionTemplateGroup.create(:group_id => sonar_users_group.id, :permission_reference => 'codeviewer', :template_id => default_template.id)
- puts('users template group created')
end
# Anyone group default permissions
--- /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.permission;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.server.exceptions.BadRequestException;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ApplyPermissionTemplateQueryTest {
+
+ @Rule
+ public ExpectedException throwable = ExpectedException.none();
+
+ @Test
+ public void should_populate_with_params() throws Exception {
+
+ Map<String, Object> params = Maps.newHashMap();
+ params.put("template_id", "1");
+ params.put("components", Lists.newArrayList("1", "2", "3"));
+
+ ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.buildFromParams(params);
+
+ assertThat(query.getTemplateId()).isEqualTo(1L);
+ assertThat(query.getSelectedComponents()).containsOnly("1", "2", "3");
+ }
+
+ @Test
+ public void should_invalidate_query_with_empty_name() throws Exception {
+
+ throwable.expect(BadRequestException.class);
+ throwable.expectMessage("Permission template is mandatory");
+
+ Map<String, Object> params = Maps.newHashMap();
+ params.put("template_id", "");
+ params.put("components", Lists.newArrayList("1", "2", "3"));
+
+ ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.buildFromParams(params);
+ query.validate();
+ }
+
+ @Test
+ public void should_invalidate_query_with_no_components() throws Exception {
+
+ throwable.expect(BadRequestException.class);
+ throwable.expectMessage("Please provide at least one entry to which the permission template should be applied");
+
+ Map<String, Object> params = Maps.newHashMap();
+ params.put("template_id", "1");
+ params.put("components", Collections.EMPTY_LIST);
+
+ ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.buildFromParams(params);
+ query.validate();
+ }
+}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.security.DefaultGroups;
-import org.sonar.core.user.GroupDto;
-import org.sonar.core.user.GroupRoleDto;
-import org.sonar.core.user.Permission;
-import org.sonar.core.user.RoleDao;
-import org.sonar.core.user.UserDao;
-import org.sonar.core.user.UserDto;
-import org.sonar.core.user.UserRoleDto;
+import org.sonar.core.permission.ComponentPermissionFacade;
+import org.sonar.core.user.*;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
import static org.sonar.server.permission.InternalPermissionServiceTest.MatchesGroupRole.matchesRole;
import static org.sonar.server.permission.InternalPermissionServiceTest.MatchesUserRole.matchesRole;
private InternalPermissionService service;
private RoleDao roleDao;
private UserDao userDao;
+ private ComponentPermissionFacade permissionFacade;
@Before
public void setUpCommonStubbing() {
when(userDao.selectActiveUserByLogin("user")).thenReturn(targetedUser);
when(userDao.selectGroupByName("group")).thenReturn(targetedGroup);
- service = new InternalPermissionService(roleDao, userDao);
+ permissionFacade = mock(ComponentPermissionFacade.class);
+
+ service = new InternalPermissionService(roleDao, userDao, permissionFacade);
}
@Test
public void should_add_user_permission() throws Exception {
- params = buildParams("user", null, Permission.DASHBOARD_SHARING);
+ params = buildPermissionChangeParams("user", null, Permission.DASHBOARD_SHARING);
setUpUserPermissions("user", Permission.QUALITY_PROFILE_ADMIN.key());
UserRoleDto roleToInsert = new UserRoleDto().setUserId(2L).setRole(Permission.DASHBOARD_SHARING.key());
@Test
public void should_remove_user_permission() throws Exception {
- params = buildParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
setUpUserPermissions("user", Permission.QUALITY_PROFILE_ADMIN.key());
UserRoleDto roleToRemove = new UserRoleDto().setUserId(2L).setRole(Permission.QUALITY_PROFILE_ADMIN.key());
@Test
public void should_add_group_permission() throws Exception {
- params = buildParams(null, "group", Permission.DASHBOARD_SHARING);
+ params = buildPermissionChangeParams(null, "group", Permission.DASHBOARD_SHARING);
setUpGroupPermissions("group", Permission.QUALITY_PROFILE_ADMIN.key());
GroupRoleDto roleToInsert = new GroupRoleDto().setGroupId(2L).setRole(Permission.DASHBOARD_SHARING.key());
@Test
public void should_remove_group_permission() throws Exception {
- params = buildParams(null, "group", Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams(null, "group", Permission.QUALITY_PROFILE_ADMIN);
setUpGroupPermissions("group", Permission.QUALITY_PROFILE_ADMIN.key());
GroupRoleDto roleToRemove = new GroupRoleDto().setGroupId(2L).setRole(Permission.QUALITY_PROFILE_ADMIN.key());
@Test
public void should_skip_redundant_permission_change() throws Exception {
- params = buildParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
setUpUserPermissions("user", Permission.QUALITY_PROFILE_ADMIN.key());
service.addPermission(params);
@Test
public void should_fail_on_invalid_request() throws Exception {
throwable.expect(BadRequestException.class);
- params = buildParams("user", "group", Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams("user", "group", Permission.QUALITY_PROFILE_ADMIN);
service.addPermission(params);
}
@Test
public void should_fail_on_insufficient_rights() throws Exception {
throwable.expect(ForbiddenException.class);
- params = buildParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
MockUserSession.set().setLogin("unauthorized").setPermissions(Permission.QUALITY_PROFILE_ADMIN);
@Test
public void should_fail_on_anonymous_access() throws Exception {
throwable.expect(UnauthorizedException.class);
- params = buildParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams("user", null, Permission.QUALITY_PROFILE_ADMIN);
MockUserSession.set();
@Test
public void should_add_permission_to_anyone_group() throws Exception {
- params = buildParams(null, DefaultGroups.ANYONE, Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams(null, DefaultGroups.ANYONE, Permission.QUALITY_PROFILE_ADMIN);
GroupRoleDto roleToInsert = new GroupRoleDto().setRole(Permission.QUALITY_PROFILE_ADMIN.key());
service.addPermission(params);
@Test
public void should_remove_permission_from_anyone_group() throws Exception {
- params = buildParams(null, DefaultGroups.ANYONE, Permission.QUALITY_PROFILE_ADMIN);
+ params = buildPermissionChangeParams(null, DefaultGroups.ANYONE, Permission.QUALITY_PROFILE_ADMIN);
setUpGroupPermissions(DefaultGroups.ANYONE, Permission.QUALITY_PROFILE_ADMIN.key());
GroupRoleDto roleToDelete = new GroupRoleDto().setRole(Permission.QUALITY_PROFILE_ADMIN.key());
verify(roleDao).deleteGroupRole(argThat(matchesRole(roleToDelete)));
}
+ @Test
+ public void should_apply_permission_template() throws Exception {
+ params = Maps.newHashMap();
+ params.put("template_id", "1");
+ params.put("components", "1,2,3");
+
+ service.applyPermissionTemplate(params);
+
+ verify(permissionFacade).applyPermissionTemplate(1L, 1L);
+ verify(permissionFacade).applyPermissionTemplate(1L, 2L);
+ verify(permissionFacade).applyPermissionTemplate(1L, 3L);
+ }
+
protected static class MatchesUserRole extends BaseMatcher<UserRoleDto> {
private final UserRoleDto referenceDto;
}
}
- private Map<String, Object> buildParams(String login, String group, Permission perm) {
+ private Map<String, Object> buildPermissionChangeParams(String login, String group, Permission perm) {
Map<String, Object> params = Maps.newHashMap();
params.put("user", login);
params.put("group", group);
*/
package org.sonar.server.util;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.SonarException;
import static java.util.Arrays.asList;
import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
public class RubyUtilsTest {
+
+ @Rule
+ public ExpectedException throwable = ExpectedException.none();
+
@Test
public void should_parse_list_of_strings() {
assertThat(RubyUtils.toStrings(null)).isNull();
@Test
public void toInteger_unexpected_class() throws Exception {
- try {
- RubyUtils.toInteger(1.2);
- fail();
- } catch (IllegalArgumentException e) {
- // ok
- }
+ throwable.expect(IllegalArgumentException.class);
+
+ RubyUtils.toInteger(1.2);
}
@Test
@Test
public void toDouble_unexpected_class() throws Exception {
- try {
- RubyUtils.toDouble(true);
- fail();
- } catch (IllegalArgumentException e) {
- // ok
- }
+ throwable.expect(IllegalArgumentException.class);
+
+ RubyUtils.toDouble(true);
}
@Test
@Test
public void toBoolean_unexpected_class() throws Exception {
- try {
- RubyUtils.toBoolean(333);
- fail();
- } catch (IllegalArgumentException e) {
- // ok
- }
+ throwable.expect(IllegalArgumentException.class);
+
+ RubyUtils.toBoolean(333);
}
@Test
@Test
public void toDate_bad_format() throws Exception {
- try {
- RubyUtils.toDate("01/02/2013");
- fail();
- } catch (Exception e) {
- // ok
- }
+ throwable.expect(SonarException.class);
+
+ RubyUtils.toDate("01/02/2013");
}
@Test
public void toDate_unexpected_class() throws Exception {
- try {
- RubyUtils.toDate(333);
- fail();
- } catch (IllegalArgumentException e) {
- // ok
- }
+ throwable.expect(IllegalArgumentException.class);
+
+ RubyUtils.toDate(333);
+ }
+
+ @Test
+ public void toLong() throws Exception {
+ assertThat(RubyUtils.toLong(null)).isNull();
+ assertThat(RubyUtils.toLong(2)).isEqualTo(2L);
+ assertThat(RubyUtils.toLong(3L)).isEqualTo(3L);
+ assertThat(RubyUtils.toLong("4")).isEqualTo(4L);
+ }
+
+ @Test
+ public void toLong_unexpected_class() throws Exception {
+ throwable.expect(IllegalArgumentException.class);
+
+ RubyUtils.toLong(false);
}
}