diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 0b54b14..cb9b88d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,8 @@ class UsersController < ApplicationController include SessionsHelper - before_action :logged_in_user, only: [ :index, :edit, :update ] + before_action :logged_in_user, only: [ :index, :edit, :update, :destroy ] before_action :correct_user, only: [ :edit, :update ] + before_action :admin_user, only: [ :destroy ] def index # @users = User.all @@ -46,6 +47,12 @@ class UsersController < ApplicationController end end + def destroy + User.find(params[:id]).destroy + flash[:success] = "User deleted" + redirect_to users_url + end + private def user_params @@ -65,4 +72,8 @@ class UsersController < ApplicationController @user = User.find(params[:id]) redirect_to(root_url) unless current_user?(@user) end + + def admin_user + redirect_to(root_url) unless current_user.admin? + end end diff --git a/app/views/users/_user.html.erb b/app/views/users/_user.html.erb index d54c0e3..be73320 100644 --- a/app/views/users/_user.html.erb +++ b/app/views/users/_user.html.erb @@ -1,4 +1,11 @@
  • <%= gravatar_for user, size: 50 %> <%= link_to user.name, user %> + <% if current_user.admin? && !current_user?(user) %> + | <%= link_to "delete", user, + data: { + turbo_method: :delete, + confirm: "You sure?" + } %> + <% end %>
  • \ No newline at end of file diff --git a/db/migrate/20250105095157_add_admin_to_users.rb b/db/migrate/20250105095157_add_admin_to_users.rb new file mode 100644 index 0000000..c1f08cf --- /dev/null +++ b/db/migrate/20250105095157_add_admin_to_users.rb @@ -0,0 +1,5 @@ +class AddAdminToUsers < ActiveRecord::Migration[8.0] + def change + add_column :users, :admin, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index ee50448..93b2f85 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_01_02_072521) do +ActiveRecord::Schema[8.0].define(version: 2025_01_05_095157) do create_table "users", force: :cascade do |t| t.string "name" t.string "email" @@ -18,6 +18,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_02_072521) do t.datetime "updated_at", null: false t.string "password_digest" t.string "remember_digest" + t.boolean "admin", default: false t.index ["email"], name: "index_users_on_email", unique: true end end diff --git a/db/seeds.rb b/db/seeds.rb index 155583d..4c18990 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -11,7 +11,8 @@ User.create!(name: "Example User", email: "example@example.com", password: "foobar", - password_confirmation: "foobar") + password_confirmation: "foobar", + admin: true) 99.times do |n| name = Faker::Name.name diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 9aca241..14fba91 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -35,4 +35,30 @@ class UsersControllerTest < ActionDispatch::IntegrationTest assert flash.empty? assert_redirected_to root_url end + + test "should not allow the admin attribute to be edited via the web" do + log_in_as(@other_user) + assert_not @other_user.admin? + patch user_path(@other_user), params: { + user: { password: "password", + password_confirmation: "password", + admin: true } + } + assert_not @other_user.reload.admin? + end + + test "should redirect destroy when not logged in" do + assert_no_difference "User.count" do + delete user_path(@user) + end + assert_redirected_to login_url + end + + test "should redirect destroy when logged in as a non-admin" do + log_in_as(@other_user) + assert_no_difference "User.count" do + delete user_path(@user) + end + assert_redirected_to root_url + end end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 2f60abe..7944493 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -7,6 +7,7 @@ one: michael: name: Michael Example email: michael@example.com + admin: true password_digest: <%= User.digest('password') %> archer: diff --git a/test/integration/users_index_test.rb b/test/integration/users_index_test.rb index a2064d1..5b11830 100644 --- a/test/integration/users_index_test.rb +++ b/test/integration/users_index_test.rb @@ -2,16 +2,26 @@ require "test_helper" class UsersIndexTest < ActionDispatch::IntegrationTest def setup - @user = users(:michael) + @admin = users(:michael) + @non_admin = users(:archer) end - test "index including pagination" do - log_in_as(@user) + test "index including pagination and delete links" do + log_in_as(@admin) get users_path assert_template "users/index" assert_select "ul.pagination" - User.page(1).each do |user| + + first_page_of_users = User.page(1) + first_page_of_users.each do |user| assert_select "a[href=?]", user_path(user), text: user.name + unless user == @admin + assert_select "a[href=?]", user_path(user), text: "delete" + end + end + + assert_difference "User.count", -1 do + delete user_path(@non_admin) end end end