global_permissions.admin.desc=Ability to perform all administration functions for the instance: global configuration and personalization of default dashboards.
global_permissions.profileadmin=Quality Profile Administration
global_permissions.profileadmin.desc=Ability to perform any action on the quality profiles.
-global_permissions.shareDashboard=Dashboard Sharing
-global_permissions.shareDashboard.desc=Ability to share dashboards that any user will be able to follow.
+global_permissions.shareDashboard=Dashboard And Filter Sharing
+global_permissions.shareDashboard.desc=Ability to share dashboards, issue filters and measure filters.
global_permissions.scan=Analysis Execution
global_permissions.scan.desc=Ability to execute analyses, and to get all settings required to perform the analysis, even the secured ones like the scm account password, the jira account password, and so on.
global_permissions.dryRunScan=Local (dry run) Analysis Execution
}
}
+ public boolean canUserShareIssueFilter(){
+ return issueFilterService.canShareFilter(UserSession.get());
+ }
+
public String serializeFilterQuery(Map<String, Object> filterQuery) {
return issueFilterService.serializeFilterQuery(filterQuery);
}
public DefaultIssueFilter save(DefaultIssueFilter issueFilter, UserSession userSession) {
String user = getLoggedLogin(userSession);
issueFilter.setUser(user);
- validateFilter(issueFilter);
+ validateFilter(issueFilter, userSession);
return insertIssueFilter(issueFilter, user);
}
public DefaultIssueFilter update(DefaultIssueFilter issueFilter, UserSession userSession) {
String login = getLoggedLogin(userSession);
IssueFilterDto existingFilterDto = findIssueFilterDto(issueFilter.id(), login);
- verifyCurrentUserCanModifyFilter(existingFilterDto.toIssueFilter(), login);
+ verifyCurrentUserCanModifyFilter(existingFilterDto.toIssueFilter(), userSession);
verifyCurrentUserCanChangeFilterSharingFilter(issueFilter, existingFilterDto, login);
if (!existingFilterDto.getUserLogin().equals(issueFilter.user())) {
- verifyCurrentUserCanChangeFilterOwnership(login);
+ verifyCurrentUserCanChangeFilterOwnership(userSession);
}
- validateFilter(issueFilter);
+ validateFilter(issueFilter, userSession);
deleteOtherFavoriteFiltersIfFilterBecomeUnshared(existingFilterDto, issueFilter);
filterDao.update(IssueFilterDto.toIssueFilter(issueFilter));
return issueFilter;
public DefaultIssueFilter updateFilterQuery(Long issueFilterId, Map<String, Object> filterQuery, UserSession userSession) {
String login = getLoggedLogin(userSession);
IssueFilterDto issueFilterDto = findIssueFilterDto(issueFilterId, login);
- verifyCurrentUserCanModifyFilter(issueFilterDto.toIssueFilter(), login);
+ verifyCurrentUserCanModifyFilter(issueFilterDto.toIssueFilter(), userSession);
DefaultIssueFilter issueFilter = issueFilterDto.toIssueFilter();
issueFilter.setData(serializeFilterQuery(filterQuery));
public void delete(Long issueFilterId, UserSession userSession) {
String login = getLoggedLogin(userSession);
IssueFilterDto issueFilterDto = findIssueFilterDto(issueFilterId, login);
- verifyCurrentUserCanModifyFilter(issueFilterDto.toIssueFilter(), login);
+ verifyCurrentUserCanModifyFilter(issueFilterDto.toIssueFilter(), userSession);
deleteFavouriteIssueFilters(issueFilterDto);
filterDao.delete(issueFilterId);
public DefaultIssueFilter copy(Long issueFilterIdToCopy, DefaultIssueFilter issueFilter, UserSession userSession) {
String login = getLoggedLogin(userSession);
IssueFilterDto issueFilterDtoToCopy = findIssueFilterDto(issueFilterIdToCopy, login);
+ // Copy of filter should not be shared
+ issueFilterDtoToCopy.setShared(false);
issueFilter.setUser(login);
issueFilter.setData(issueFilterDtoToCopy.getData());
- validateFilter(issueFilter);
+ validateFilter(issueFilter, userSession);
return insertIssueFilter(issueFilter, login);
}
return issueFilterDto;
}
+ public boolean canShareFilter(UserSession userSession){
+ return userSession.hasGlobalPermission(Permission.DASHBOARD_SHARING);
+ }
+
String getLoggedLogin(UserSession userSession) {
String user = userSession.login();
- if (!userSession.isLoggedIn() && user != null) {
+ if (!userSession.isLoggedIn()) {
throw new UnauthorizedException("User is not logged in");
}
return user;
}
}
- private void verifyCurrentUserCanModifyFilter(DefaultIssueFilter issueFilter, String user) {
- if (!issueFilter.user().equals(user) && !isAdmin(user)) {
+ private void verifyCurrentUserCanModifyFilter(DefaultIssueFilter issueFilter, UserSession userSession) {
+ if (!issueFilter.user().equals(userSession.login()) && !isAdmin(userSession)) {
throw new ForbiddenException("User is not authorized to modify this filter");
}
}
}
}
- private void verifyCurrentUserCanChangeFilterOwnership(String user) {
- if (!isAdmin(user)) {
+ private void verifyCurrentUserCanChangeFilterOwnership(UserSession userSession) {
+ if (!isAdmin(userSession)) {
throw new ForbiddenException("User is not authorized to change the owner of this filter");
}
}
- private void validateFilter(final DefaultIssueFilter issueFilter) {
+ private void verifyCurrentUserCanShareFilter(DefaultIssueFilter issueFilter, UserSession userSession) {
+ if (issueFilter.shared() && !canShareFilter(userSession)) {
+ throw new ForbiddenException("User is not authorized to share this filter");
+ }
+ }
+
+ private void validateFilter(final DefaultIssueFilter issueFilter, UserSession userSession) {
List<IssueFilterDto> userFilters = selectUserIssueFilters(issueFilter.user());
IssueFilterDto userFilterSameName = findFilterWithSameName(userFilters, issueFilter.name());
if (userFilterSameName != null && !userFilterSameName.getId().equals(issueFilter.id())) {
if (sharedFilterWithSameName != null && !sharedFilterWithSameName.getId().equals(issueFilter.id())) {
throw new BadRequestException("Other users already share filters with the same name");
}
+ verifyCurrentUserCanShareFilter(issueFilter, userSession);
}
}
}));
}
- private boolean isAdmin(String user) {
- return authorizationDao.selectGlobalPermissions(user).contains(Permission.SYSTEM_ADMIN.key());
+ private boolean isAdmin(UserSession userSession) {
+ return userSession.hasGlobalPermission(Permission.SYSTEM_ADMIN);
}
private IssueFilterResult createIssueFilterResult(IssueQueryResult issueQueryResult, IssueQuery issueQuery) {
#
#
- def render_native_access_denied
+ def render_native_access_denied(exception)
render_access_denied
end
render :text => message, :status => exception.httpCode
end
- def render_native_access_denied
- access_denied
+ def render_native_access_denied(exception)
+ if request.xhr?
+ render_server_exception(exception)
+ else
+ access_denied
+ end
end
def render_native_exception(error)
if error.cause.java_kind_of? Java::JavaLang::IllegalArgumentException
render_bad_request(error.cause.getMessage)
elsif error.cause.java_kind_of? Java::OrgSonarServerExceptions::UnauthorizedException
- render_native_access_denied
+ render_native_access_denied(error.cause)
elsif error.cause.java_kind_of? Java::OrgSonarServerExceptions::ForbiddenException
- render_native_access_denied
+ render_native_access_denied(error.cause)
elsif error.cause.java_kind_of? Java::OrgSonarServerExceptions::HttpException
render_server_exception(error.cause)
else
end
@filter.name=params[:name]
@filter.description=params[:description]
- @filter.shared=(params[:shared]=='true')
+ @filter.shared=(params[:shared]=='true') && has_role?(:shareDashboard)
@filter.data=URI.unescape(params[:data])
if @filter.save
current_user.favourited_measure_filters<<@filter if add_to_favourites
@filter.name=params[:name]
@filter.description=params[:description]
- @filter.shared=(params[:shared]=='true')
+ @filter.shared=(params[:shared]=='true') && has_role?(:shareDashboard)
if has_role?(:admin) && params[:owner]
@filter.user = User.find_by_login(params[:owner])
end
target.name=params[:name]
target.description=params[:description]
target.user_id=current_user.id
- target.shared=(params[:shared]=='true')
+ # Copy of filter should never be shared
+ target.shared=false
target.data=source.data
if target.save
current_user.favourited_measure_filters << target
<% else %>
<input id="user" name="user" type="hidden" value="<%= h(@filter.user) if @filter -%>"/>
<% end %>
- <div class="modal-field">
- <% if !@filter || @filter.user == current_user.login %>
- <label for="shared"><%= message('issue_filter.form.share') -%></label>
- <input id="shared" name="shared" type="checkbox" value="true" <%= 'checked' if (@filter && @filter.shared) -%>/>
- <% else %>
- <input id="shared" name="shared" type="hidden" value="<%= @filter.shared if @filter -%>"/>
- <% end %>
- </div>
+ <% if Internal.issues.canUserShareIssueFilter() %>
+ <div class="modal-field">
+ <% if !@filter || @filter.user == current_user.login %>
+ <label for="shared"><%= message('issue_filter.form.share') -%></label>
+ <input id="shared" name="shared" type="checkbox" value="true" <%= 'checked' if (@filter && @filter.shared) -%>/>
+ <% else %>
+ <input id="shared" name="shared" type="hidden" value="<%= @filter.shared if @filter -%>"/>
+ <% end %>
+ </div>
+ <% end %>
</div>
\ No newline at end of file
<%= user_select_tag('owner', :html_id => 'select-filter-owner', :selected_user => @filter.user) -%>
</div>
<% end %>
- <% if @filter.user_id.nil? || @filter.user_id == current_user.id %>
- <div class="modal-field">
- <label for="shared"><%= h message('measure_filter.shared_with_all_users') -%></label>
- <input id="shared" name="shared" type="checkbox" value="true" <%= 'checked' if @filter.shared -%>/>
- </div>
- <% else %>
- <input id="shared" name="shared" type="hidden" value="<%= @filter.shared -%>"/>
+ <% if has_role?(:shareDashboard) %>
+ <% if @filter.user_id.nil? || @filter.user_id == current_user.id %>
+ <div class="modal-field">
+ <label for="shared"><%= h message('measure_filter.shared_with_all_users') -%></label>
+ <input id="shared" name="shared" type="checkbox" value="true" <%= 'checked' if @filter.shared -%>/>
+ </div>
+ <% else %>
+ <input id="shared" name="shared" type="hidden" value="<%= @filter.shared -%>"/>
+ <% end %>
<% end %>
</div>
\ No newline at end of file
}
@Test
- public void should_check_is_user_is_authorized_to_see_issue_filter() {
+ public void should_check_if_user_is_authorized_to_see_issue_filter() {
DefaultIssueFilter issueFilter = new DefaultIssueFilter();
service.isUserAuthorized(issueFilter);
verify(issueFilterService).getLoggedLogin(any(UserSession.class));
verify(issueFilterService).verifyCurrentUserCanReadFilter(eq(issueFilter), anyString());
}
+ @Test
+ public void should_check_if_user_can_share_issue_filter(){
+ service.canUserShareIssueFilter();
+ verify(issueFilterService).canShareFilter(any(UserSession.class));
+ }
+
@Test
public void should_execute_bulk_change() {
Map<String, Object> params = newHashMap();
@Before
public void before() {
- userSession = mock(UserSession.class);
- when(userSession.isLoggedIn()).thenReturn(true);
- when(userSession.userId()).thenReturn(10);
- when(userSession.login()).thenReturn("john");
+ userSession = MockUserSession.create().setLogin("john");
issueFilterDao = mock(IssueFilterDao.class);
issueFilterFavouriteDao = mock(IssueFilterFavouriteDao.class);
@Test
public void should_not_find_by_id_if_not_logged() {
- when(userSession.isLoggedIn()).thenReturn(false);
+ UserSession userSession = MockUserSession.create().setLogin(null);
try {
service.find(1L, userSession);
fail();
@Test
public void should_not_find_by_user_if_not_logged() {
- when(userSession.isLoggedIn()).thenReturn(false);
+ UserSession userSession = MockUserSession.create().setLogin(null);
try {
service.findByUser(userSession);
fail();
@Test
public void should_not_save_if_not_logged() {
- when(userSession.isLoggedIn()).thenReturn(false);
+ UserSession userSession = MockUserSession.create().setLogin(null);
try {
DefaultIssueFilter issueFilter = new DefaultIssueFilter().setName("My Issue");
service.save(issueFilter, userSession);
}
@Test
- public void should_update_sharing() {
- when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Filter").setShared(true).setUserLogin("john"));
+ public void should_have_permission_to_share_filter() {
+ UserSession userSession = MockUserSession.create().setLogin("john").setPermissions(Permission.DASHBOARD_SHARING);
+ when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Filter").setShared(false).setUserLogin("john"));
- DefaultIssueFilter result = service.update(new DefaultIssueFilter().setId(1L).setName("My Filter").setShared(false).setUser("john"), userSession);
- assertThat(result.shared()).isFalse();
+ DefaultIssueFilter result = service.update(new DefaultIssueFilter().setId(1L).setName("My Filter").setShared(true).setUser("john"), userSession);
+ assertThat(result.shared()).isTrue();
verify(issueFilterDao).update(any(IssueFilterDto.class));
}
+ @Test
+ public void should_not_share_filter_if_no_permission() {
+ UserSession userSession = MockUserSession.create().setLogin("john").setPermissions();
+ when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Filter").setShared(false).setUserLogin("john"));
+
+ try {
+ service.update(new DefaultIssueFilter().setId(1L).setName("My Filter").setShared(true).setUser("john"), userSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("User is not authorized to share this filter");
+ }
+ verify(issueFilterDao, never()).update(any(IssueFilterDto.class));
+ }
+
@Test
public void should_not_update_sharing_if_not_owner() {
// John is admin and want to change arthur filter sharing
+ UserSession userSession = MockUserSession.create().setLogin("john").setPermissions(Permission.SYSTEM_ADMIN);
when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("Arthur Filter").setShared(true).setUserLogin("arthur"));
- when(authorizationDao.selectGlobalPermissions("john")).thenReturn(newArrayList(Permission.SYSTEM_ADMIN.key()));
try {
service.update(new DefaultIssueFilter().setId(1L).setName("Arthur Filter").setShared(false).setUser("john"), userSession);
@Test
public void should_update_other_shared_filter_if_admin() {
- when(authorizationDao.selectGlobalPermissions("john")).thenReturn(newArrayList(Permission.SYSTEM_ADMIN.key()));
+ UserSession userSession = MockUserSession.create().setLogin("john").setPermissions(Permission.SYSTEM_ADMIN, Permission.DASHBOARD_SHARING);
when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Old Filter").setDescription("Old description").setUserLogin("arthur").setShared(true));
DefaultIssueFilter result = service.update(new DefaultIssueFilter().setId(1L).setName("My New Filter").setDescription("New description").setShared(true), userSession);
IssueFilterDto sharedFilter = new IssueFilterDto().setId(1L).setName("My filter").setUserLogin("former.owner").setShared(true);
IssueFilterDto expectedDto = new IssueFilterDto().setName("My filter").setUserLogin("new.owner").setShared(true);
- when(authorizationDao.selectGlobalPermissions(currentUser)).thenReturn(newArrayList(Permission.SYSTEM_ADMIN.key()));
+ UserSession userSession = MockUserSession.create().setLogin(currentUser).setPermissions(Permission.SYSTEM_ADMIN, Permission.DASHBOARD_SHARING);
+
when(issueFilterDao.selectById(1L)).thenReturn(sharedFilter);
when(issueFilterDao.selectSharedFilters()).thenReturn(Lists.newArrayList(sharedFilter));
DefaultIssueFilter issueFilter = new DefaultIssueFilter().setId(1L).setName("My filter").setShared(true).setUser("new.owner");
- service.update(issueFilter, MockUserSession.create().setUserId(1).setLogin(currentUser));
+ service.update(issueFilter, userSession);
verify(issueFilterDao).update(argThat(Matches.filter(expectedDto)));
}
@Test
public void should_delete_shared_filter_if_user_is_admin() {
- when(authorizationDao.selectGlobalPermissions("john")).thenReturn(newArrayList(Permission.SYSTEM_ADMIN.key()));
+ UserSession userSession = MockUserSession.create().setLogin("john").setPermissions(Permission.SYSTEM_ADMIN);
when(issueFilterDao.selectById(1L)).thenReturn(new IssueFilterDto().setId(1L).setName("My Issues").setUserLogin("arthur").setShared(true));
service.delete(1L, userSession);
DefaultIssueFilter result = service.copy(1L, issueFilter, userSession);
assertThat(result.name()).isEqualTo("Copy Of My Issue");
assertThat(result.user()).isEqualTo("john");
+ assertThat(result.shared()).isFalse();
verify(issueFilterDao).insert(any(IssueFilterDto.class));
}
@Test
public void should_not_find_favourite_issue_filter_if_not_logged() {
- when(userSession.isLoggedIn()).thenReturn(false);
+ UserSession userSession = MockUserSession.create().setLogin(null);
try {
service.findFavoriteFilters(userSession);