From 634ba7e901766ead4d55b2adb53e04e6c31e2df4 Mon Sep 17 00:00:00 2001 From: cryptogopher Date: Mon, 24 Apr 2023 23:08:55 +0200 Subject: [PATCH] Add access control and :forbidden error handling --- app/controllers/application_controller.rb | 9 +++++ app/controllers/users_controller.rb | 8 +++-- app/views/layouts/application.html.erb | 5 ++- app/views/users/index.html.erb | 40 ++++++++++++----------- config/application.rb.dist | 2 ++ 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a9c4fd7..cab3c1f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,6 +1,15 @@ class ApplicationController < ActionController::Base + helper_method :current_user_at_least + before_action :authenticate_user! + class AccessForbidden < StandardError + end + + def current_user_at_least(status) + User.statuses[current_user.status] >= User.statuses[status] + end + protected def after_sign_out_path_for(scope) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index ff96518..85f6554 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,9 @@ class UsersController < ApplicationController - before_action :set_user, only: %i[ show edit update destroy ] + before_action :find_user, only: [:show, :edit, :update, :destroy] + before_action do + raise AccessForbidden unless (current_user == @user) || current_user_at_least(:admin) + end - # GET /users def index @users = User.all end @@ -47,7 +49,7 @@ class UsersController < ApplicationController private # Use callbacks to share common setup or constraints between actions. - def set_user + def find_user @user = User.find(params[:id]) end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 800e0ad..7060ffb 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -34,7 +34,10 @@ diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index e37f739..f353947 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -1,21 +1,23 @@ - - - - - - - - - <% @users.each do |user| %> +<% if current_user_at_least(:admin) %> +
<%= User.human_attribute_name(:email).capitalize %><%= User.human_attribute_name(:status).capitalize %><%= User.human_attribute_name(:created_at).capitalize %> UTC<%= User.human_attribute_name(:confirmed_at).capitalize %><%= t :actions %>
- - - - - + + + + + - <% end %> -
<%= user.email %><%= user.status %><%= user.created_at.to_fs(:db_without_sec) %> - <%= svg_tag "pictograms/checkbox-marked-outline.svg#icon" if user.confirmed_at.present? %> - <%= image_link_to "Delete", "account-remove-outline", user_path(user), - data: { turbo: true, turbo_method: :delete } %><%= User.human_attribute_name(:email).capitalize %><%= User.human_attribute_name(:status).capitalize %><%= User.human_attribute_name(:created_at).capitalize %> UTC<%= User.human_attribute_name(:confirmed_at).capitalize %><%= t :actions %>
+ <% @users.each do |user| %> + + <%= user.email %> + <%= user.status %> + <%= user.created_at.to_fs(:db_without_sec) %> + + <%= svg_tag "pictograms/checkbox-marked-outline" if user.confirmed_at.present? %> + + <%= image_link_to "Delete", "account-remove-outline", user_path(user), + data: { turbo: true, turbo_method: :delete } %> + + <% end %> + +<% end %> diff --git a/config/application.rb.dist b/config/application.rb.dist index 1494571..e496cd7 100644 --- a/config/application.rb.dist +++ b/config/application.rb.dist @@ -31,6 +31,8 @@ module FixinMe # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") + config.action_dispatch.rescue_responses['ApplicationController::AccessForbidden'] = :forbidden + # SETUP: Below settings need to be updated on a per-installation basis. # # URL to use in sent e-mails.