Join the two users controllers but split out role setting

This commit is contained in:
David Heinemeier Hansson
2025-04-12 20:30:47 +02:00
parent c463f342bf
commit a106b1b6a7
8 changed files with 51 additions and 33 deletions
@@ -1,24 +1,15 @@
class Accounts::UsersController < ApplicationController
before_action :set_user, only: %i[ update destroy ]
before_action :ensure_permission_to_administer_user, only: %i[ update destroy ]
def index
@users = User.active
end
class Users::RolesController < ApplicationController
before_action :set_user
before_action :ensure_permission_to_administer_user
def update
@user.update(role_params)
redirect_to users_path
end
def destroy
@user.deactivate
redirect_to users_path
end
private
def set_user
@user = User.active.find(params[:id])
@user = User.active.find(params[:user_id])
end
def ensure_permission_to_administer_user
+15 -1
View File
@@ -1,8 +1,13 @@
class UsersController < ApplicationController
require_unauthenticated_access only: %i[ new create ]
before_action :set_user, only: %i[ show edit update ]
before_action :set_user, only: %i[ show edit update destroy ]
before_action :set_account_from_join_code, only: %i[ new create ]
before_action :ensure_permission_to_administer_user, only: %i[ update destroy ]
def index
@users = User.active
end
def new
@user = User.new
@@ -25,6 +30,11 @@ class UsersController < ApplicationController
redirect_to @user
end
def destroy
@user.deactivate
redirect_to users_path
end
private
def set_account_from_join_code
@account = Account.find_by_join_code!(params[:join_code])
@@ -34,6 +44,10 @@ class UsersController < ApplicationController
@user = User.active.find(params[:id])
end
def ensure_permission_to_administer_user
head :forbidden unless Current.user.can_administer?(@user)
end
def user_params
params.expect(user: [ :name, :email_address, :password, :avatar ])
end
@@ -2,12 +2,12 @@
<%= avatar_tag user, class: "flex-item-no-shrink" %>
<strong class="overflow-ellipsis">
<%= link_to user.name, user_path(user), class: "txt-ink btn btn--plain" %>
<%= link_to user.name, user, class: "txt-ink btn btn--plain" %>
</strong>
<hr class="separator--horizontal flex-item-grow" style="--border-color: var(--color-subtle-dark); --border-style: dashed" aria-hidden="true">
<%= form_with model: user, url: account_user_path(user), data: { controller: "form" }, method: :patch do | form | %>
<%= form_with model: user, url: user_role_path(user), data: { controller: "form" }, method: :patch do | form | %>
<label class="btn txt-small flex-item-no-shrink" for="<%= dom_id(user, :role) %>" arial-label="Role: <%= user.admin? ? "Administrator" : "Member" %>">
<%= icon_tag "crown" %>
<%= form.check_box :role, { data: { action: "form#submit" }, disabled: !Current.user.can_administer?(user), hidden: true, id: dom_id(user, :role) }, "admin", "member" %>
@@ -15,7 +15,7 @@
<% end %>
<%# FIXME: Move this Current.user check to a stimulus controller that just checks for admin? or the like we so we can cache user list %>
<%= button_to account_user_path(user), method: :delete, class: "btn txt-small btn--negative flex-item-no-shrink",
<%= button_to user, method: :delete, class: "btn txt-small btn--negative flex-item-no-shrink",
disabled: !Current.user.can_administer?(user),
data: { turbo_confirm: "Are you sure you want to permanently remove this person from the account?" } do %>
<%= icon_tag "minus" %>
@@ -16,9 +16,9 @@
<% end %>
<div class="panel borderless center pad fill-shade flex flex-column margin-block">
<%= render "accounts/users/invite" %>
<%= render "users/invite" %>
</div>
<div class="panel borderless center pad fill-none flex flex-column gap">
<%= render partial: "accounts/users/user", collection: @users %>
<%= render @users %>
</div>
+3 -1
View File
@@ -5,7 +5,9 @@ Rails.application.routes.draw do
resource :join_code, module: :accounts
end
resources :users
resources :users do
resource :role, module: :users
end
resources :collections do
scope module: :collections do
@@ -0,0 +1,22 @@
require "test_helper"
class Users::RolesControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in_as :kevin
end
test "update" do
assert_not users(:david).admin?
put user_role_url(users(:david)), params: { user: { role: "admin" } }
assert_redirected_to users_path
assert users(:david).reload.admin?
end
test "can't promote to special roles" do
assert_no_changes -> { users(:david).reload.role } do
put user_role_url(users(:david)), params: { user: { role: "system" } }
end
end
end
@@ -1,23 +1,12 @@
require "test_helper"
class Accounts::UsersControllerTest < ActionDispatch::IntegrationTest
class UsersControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in_as :kevin
end
test "update" do
assert_not users(:david).admin?
put user_url(users(:david)), params: { user: { role: "admin" } }
assert_redirected_to users_path
assert users(:david).reload.admin?
end
test "can't promote to special roles" do
assert_no_changes -> { users(:david).reload.role } do
put user_url(users(:david)), params: { user: { role: "system" } }
end
assert true
end
test "destroy" do