diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 12448d9dd..481e519e3 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -2,6 +2,7 @@ class BoardsController < ApplicationController include FilterScoped before_action :set_board, except: %i[ new create ] + before_action :ensure_permission_to_change_all_access, only: %i[ update ] def show if @filter.used?(ignore_boards: true) @@ -47,6 +48,16 @@ class BoardsController < ApplicationController @board = Current.user.boards.find params[:id] end + def ensure_permission_to_change_all_access + if all_access_changed? && !Current.user.can_administer_board?(@board) + head :forbidden + end + end + + def all_access_changed? + params[:board]&.key?(:all_access) + end + def show_filtered_cards @filter.board_ids = [ @board.id ] set_page_and_extract_portion_from @filter.cards diff --git a/app/models/user/role.rb b/app/models/user/role.rb index aaa4bd5ff..029e2740d 100644 --- a/app/models/user/role.rb +++ b/app/models/user/role.rb @@ -21,4 +21,8 @@ module User::Role def can_administer?(other = nil) admin? && other != self end + + def can_administer_board?(board) + admin? || board.creator == self + end end diff --git a/app/views/boards/edit/_users.html.erb b/app/views/boards/edit/_users.html.erb index 5e4e0ae2a..63b7bf9e8 100644 --- a/app/views/boards/edit/_users.html.erb +++ b/app/views/boards/edit/_users.html.erb @@ -16,7 +16,7 @@
diff --git a/test/controllers/boards_controller_test.rb b/test/controllers/boards_controller_test.rb index b6416b5a4..18a74f304 100644 --- a/test/controllers/boards_controller_test.rb +++ b/test/controllers/boards_controller_test.rb @@ -95,4 +95,17 @@ class BoardsControllerTest < ActionDispatch::IntegrationTest assert_redirected_to root_path assert_raises(ActiveRecord::RecordNotFound) { board.reload } end + + test "non-admin cannot change all_access on board they don't own" do + Session.destroy_all + sign_in_as :jz + + board = boards(:writebook) + original_all_access = board.all_access + + patch board_path(board), params: { board: { all_access: !original_all_access } } + + assert_response :forbidden + assert_equal original_all_access, board.reload.all_access + end end diff --git a/test/models/user/role_test.rb b/test/models/user/role_test.rb index 4f3ad0177..4ae9bdf04 100644 --- a/test/models/user/role_test.rb +++ b/test/models/user/role_test.rb @@ -7,4 +7,23 @@ class User::RoleTest < ActiveSupport::TestCase assert_not users(:kevin).can_administer?(users(:kevin)) assert_not users(:jz).can_administer?(users(:kevin)) end + + test "can administer board?" do + writebook_board = boards(:writebook) + private_board = boards(:private) + + # Admin can administer any board + assert users(:kevin).can_administer_board?(writebook_board) + assert users(:kevin).can_administer_board?(private_board) + + # Creator can administer their own board + assert users(:david).can_administer_board?(writebook_board) + + # Regular user cannot administer boards they didn't create + assert_not users(:jz).can_administer_board?(writebook_board) + assert_not users(:jz).can_administer_board?(private_board) + + # Creator cannot administer other people's boards + assert_not users(:david).can_administer_board?(private_board) + end end