mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-04-09 14:37:47 +09:00
Merge pull request #120 from basecamp/allow-restricting-new-room-creation-to-admins
Add new has_json to add Account#settings to restrict room creation to only administrators
This commit is contained in:
4
Gemfile
4
Gemfile
@@ -4,9 +4,11 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||
|
||||
# Rails
|
||||
gem "rails", github: "rails/rails", branch: "main"
|
||||
gem "ostruct"
|
||||
gem "benchmark"
|
||||
|
||||
# Drivers
|
||||
gem "sqlite3", "~> 2.7"
|
||||
gem "sqlite3"
|
||||
gem "redis", "~> 5.4"
|
||||
|
||||
# Deployment
|
||||
|
||||
@@ -135,6 +135,7 @@ GEM
|
||||
ast (2.4.3)
|
||||
base64 (0.3.0)
|
||||
bcrypt (3.1.20)
|
||||
benchmark (0.5.0)
|
||||
bigdecimal (3.3.1)
|
||||
brakeman (7.1.1)
|
||||
racc
|
||||
@@ -239,6 +240,7 @@ GEM
|
||||
nokogiri (1.18.10-x86_64-linux-gnu)
|
||||
racc (~> 1.4)
|
||||
openssl (3.3.0)
|
||||
ostruct (0.6.3)
|
||||
parallel (1.27.0)
|
||||
parser (3.3.9.0)
|
||||
ast (~> 2.4.1)
|
||||
@@ -408,6 +410,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
bcrypt
|
||||
benchmark
|
||||
brakeman
|
||||
capybara
|
||||
debug
|
||||
@@ -419,6 +422,7 @@ DEPENDENCIES
|
||||
kredis
|
||||
mocha
|
||||
net-http-persistent
|
||||
ostruct
|
||||
platform_agent
|
||||
propshaft!
|
||||
puma (~> 6.6)
|
||||
@@ -432,7 +436,7 @@ DEPENDENCIES
|
||||
selenium-webdriver
|
||||
sentry-rails
|
||||
sentry-ruby
|
||||
sqlite3 (~> 2.7)
|
||||
sqlite3
|
||||
stimulus-rails
|
||||
thruster
|
||||
turbo-rails!
|
||||
|
||||
@@ -17,7 +17,7 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:name, :logo)
|
||||
params.require(:account).permit(:name, :logo, settings: {})
|
||||
end
|
||||
|
||||
def account_users
|
||||
|
||||
@@ -3,6 +3,7 @@ class Rooms::ClosedsController < RoomsController
|
||||
before_action :ensure_can_administer, only: %i[ update ]
|
||||
before_action :remember_last_room_visited, only: :show
|
||||
before_action :force_room_type, only: %i[ edit update ]
|
||||
before_action :ensure_permission_to_create_rooms, only: %i[ new create ]
|
||||
|
||||
DEFAULT_ROOM_NAME = "New room"
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ class Rooms::OpensController < RoomsController
|
||||
before_action :ensure_can_administer, only: %i[ update ]
|
||||
before_action :remember_last_room_visited, only: :show
|
||||
before_action :force_room_type, only: %i[ edit update ]
|
||||
before_action :ensure_permission_to_create_rooms, only: %i[ new create ]
|
||||
|
||||
DEFAULT_ROOM_NAME = "New room"
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@ class RoomsController < ApplicationController
|
||||
head :forbidden unless Current.user.can_administer?(@room)
|
||||
end
|
||||
|
||||
def ensure_permission_to_create_rooms
|
||||
if Current.account.settings.restrict_room_creation_to_administrators? && !Current.user.administrator?
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def find_messages
|
||||
messages = @room.messages.with_creator.with_attachment_details.with_boosts
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ class Account < ApplicationRecord
|
||||
include Joinable
|
||||
|
||||
has_one_attached :logo
|
||||
has_json :settings, restrict_room_creation_to_administrators: false
|
||||
end
|
||||
|
||||
@@ -53,7 +53,7 @@ class Webhook < ApplicationRecord
|
||||
end
|
||||
|
||||
def extract_text_from(response)
|
||||
response.body.dup.force_encoding("UTF-8") if response.code == "200" && response.content_type.in?(%w[ text/html text/plain ])
|
||||
String.new(response.body).force_encoding("UTF-8") if response.code == "200" && response.content_type.in?(%w[ text/html text/plain ])
|
||||
end
|
||||
|
||||
def receive_text_reply_to(room, text:)
|
||||
|
||||
@@ -64,6 +64,30 @@
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="margin-block-start pad-block pad-inline-double fill-shade border-radius">
|
||||
<%= form_with model: @account, method: :put, data: { controller: "form" }, class: "flex align-center gap center" do |form| %>
|
||||
<div class="flex-item-grow flex align-center gap txt-align-start">
|
||||
<%= image_tag "crown.svg", class: "colorize--black", aria: { hidden: "true" }, size: 18 %> Must be admin to create new rooms
|
||||
</div>
|
||||
<%= form.fields_for :settings, @account.settings do |settings_form| %>
|
||||
<%= settings_form.hidden_field :restrict_room_creation_to_administrators,
|
||||
value: !Current.account.settings.restrict_room_creation_to_administrators? %>
|
||||
<% end %>
|
||||
|
||||
<label class="switch">
|
||||
<input type="checkbox"
|
||||
class="switch__input"
|
||||
<%= "checked" if Current.account.settings.restrict_room_creation_to_administrators? %>
|
||||
data-action="change->form#submit">
|
||||
<span class="switch__btn round"></span>
|
||||
<span class="for-screen-reader">
|
||||
Must be admin to create new rooms
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= account_logo_tag style: "txt-xx-large center" %>
|
||||
<h1 class="flex-item-grow txt-x-large"><%= @account.name %></h1>
|
||||
|
||||
@@ -36,8 +36,10 @@
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to new_rooms_open_path, class: "rooms__new-btn btn room align-center gap txt-reversed", aria: { label: "New Chat Room" } do %>
|
||||
<%= image_tag "add.svg", size: 20, aria: { hidden: "true" }, style: "view-transition-name: new-room" %>
|
||||
<% if Current.user.administrator? || !Current.account.settings.restrict_room_creation_to_administrators? %>
|
||||
<%= link_to new_rooms_open_path, class: "rooms__new-btn btn room align-center gap txt-reversed", aria: { label: "New Chat Room" } do %>
|
||||
<%= image_tag "add.svg", size: 20, aria: { hidden: "true" }, style: "view-transition-name: new-room" %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
5
db/migrate/20251126130131_add_account_settings.rb
Normal file
5
db/migrate/20251126130131_add_account_settings.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddAccountSettings < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
add_column :accounts, :settings, :json
|
||||
end
|
||||
end
|
||||
3
db/schema.rb
generated
3
db/schema.rb
generated
@@ -10,12 +10,13 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.1].define(version: 2025_11_26_115722) do
|
||||
ActiveRecord::Schema[8.2].define(version: 2025_11_26_130131) do
|
||||
create_table "accounts", force: :cascade do |t|
|
||||
t.datetime "created_at", null: false
|
||||
t.text "custom_styles"
|
||||
t.string "join_code", null: false
|
||||
t.string "name", null: false
|
||||
t.json "settings"
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
|
||||
@@ -29,6 +29,16 @@ class Rooms::ClosedsControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_redirected_to room_url(Room.last)
|
||||
end
|
||||
|
||||
test "create forbidden by non-admin when account restricts creation to admins" do
|
||||
accounts(:signal).settings.restrict_room_creation_to_administrators = true
|
||||
accounts(:signal).save!
|
||||
|
||||
sign_in :jz
|
||||
post rooms_closeds_url, params: { room: { name: "My New Room" }, user_ids: [ users(:david).id, users(:kevin).id, users(:jason).id ] }
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
|
||||
test "update with membership revisions" do
|
||||
assert_difference -> { rooms(:designers).reload.users.count }, -1 do
|
||||
put rooms_closed_url(rooms(:designers)), params: {
|
||||
|
||||
@@ -24,6 +24,15 @@ class Rooms::OpensControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_redirected_to room_url(Room.last)
|
||||
end
|
||||
|
||||
test "create forbidden by non-admin when account restricts creation to admins" do
|
||||
accounts(:signal).settings.restrict_room_creation_to_administrators = true
|
||||
accounts(:signal).save!
|
||||
|
||||
sign_in :jz
|
||||
post rooms_opens_url, params: { room: { name: "My New Room" } }
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "only admins or creators can update" do
|
||||
sign_in :jz
|
||||
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
require "test_helper"
|
||||
|
||||
class AccountTest < ActiveSupport::TestCase
|
||||
test "settings" do
|
||||
accounts(:signal).settings.restrict_room_creation_to_administrators = true
|
||||
assert accounts(:signal).settings.restrict_room_creation_to_administrators?
|
||||
assert_equal({ "restrict_room_creation_to_administrators" => true }, accounts(:signal)[:settings])
|
||||
|
||||
accounts(:signal).update!(settings: { "restrict_room_creation_to_administrators" => "true" })
|
||||
assert accounts(:signal).reload.settings.restrict_room_creation_to_administrators?
|
||||
|
||||
accounts(:signal).settings.restrict_room_creation_to_administrators = false
|
||||
assert_not accounts(:signal).settings.restrict_room_creation_to_administrators?
|
||||
assert_equal({ "restrict_room_creation_to_administrators" => false }, accounts(:signal)[:settings])
|
||||
accounts(:signal).update!(settings: { "restrict_room_creation_to_administrators" => "false" })
|
||||
assert_not accounts(:signal).reload.settings.restrict_room_creation_to_administrators?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ require "rails/test_help"
|
||||
require "minitest/unit"
|
||||
require "mocha/minitest"
|
||||
require "webmock/minitest"
|
||||
require "turbo/broadcastable/test_helper"
|
||||
|
||||
WebMock.enable!
|
||||
|
||||
|
||||
Reference in New Issue
Block a user