diff --git a/Gemfile b/Gemfile index e9284df..ffe46f5 100644 --- a/Gemfile +++ b/Gemfile @@ -30,6 +30,8 @@ gem 'devise' gem 'rolify' +gem 'cancancan' + gem 'webpacker' gem 'kaminari' diff --git a/Gemfile.lock b/Gemfile.lock index 466bd18..dd38dd4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -84,6 +84,7 @@ GEM bootsnap (1.17.0) msgpack (~> 1.2) builder (3.2.4) + cancancan (3.5.0) capybara (3.39.2) addressable matrix @@ -291,6 +292,7 @@ PLATFORMS DEPENDENCIES bootsnap + cancancan capybara debug devise diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb new file mode 100644 index 0000000..3bc151a --- /dev/null +++ b/app/controllers/admin_controller.rb @@ -0,0 +1,26 @@ +class AdminController < ApplicationController + before_action :authenticate_user! + load_and_authorize_resource class: User + + def new_user + @user = User.new + end + + def create_user + @user = User.new(user_params) + if @user.save + # Add role to the user here if needed e.g., user.add_role :new_role + redirect_to admin_users_path, notice: 'User was successfully created.' + else + render :new_user + end + end + + private + + def user_params + params.require(:user).permit(:email, :password, :password_confirmation) + # Add other fields as needed + end + end + \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index cd7f6aa..eb02814 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,3 +1,7 @@ class ApplicationController < ActionController::Base before_action :authenticate_user! -end + rescue_from CanCan::AccessDenied do |exception| + redirect_to root_url, alert: "Access denied." + end + end + \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d1920fe..3a25598 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -2,6 +2,7 @@ class UsersController < ApplicationController before_action :authenticate_user! before_action :set_user, only: [:edit, :update, :destroy] before_action :require_admin + load_and_authorize_resource def index @users = User.all @@ -10,8 +11,20 @@ class UsersController < ApplicationController def edit end + def create + @user = User.new(user_params) + if @user.save + assign_roles(@user) + redirect_to users_path, notice: 'User was successfully created.' + else + render :new + end + end + def update - if @user.update(user_params) + # Assumes @user is already set from a before_action callback + if @user.update(user_params.except(:roles)) + update_user_roles(@user, user_params[:roles]) redirect_to users_path, notice: 'User was successfully updated.' else render :edit @@ -30,7 +43,7 @@ class UsersController < ApplicationController end def user_params - params.require(:user).permit(:email, :admin) + params.require(:user).permit(:email, :password, :password_confirmation, roles: []) end def require_admin @@ -38,4 +51,25 @@ class UsersController < ApplicationController redirect_to root_path, alert: 'Only admins are allowed to access this section.' end end + + def assign_roles(user) + user.roles.delete_all # Clear all roles before reassigning to prevent duplicates + + # Assuming roles are passed as an array of role names from the form + # and that the form sends an empty string if no roles are selected. + selected_roles = params[:user][:roles].reject(&:blank?) + + selected_roles.each do |role_name| + user.add_role(role_name) unless user.has_role?(role_name) + end + end + + def update_user_roles(user, roles_names) + user.roles.delete_all # Remove existing roles + roles_names.each do |role_name| + user.add_role(role_name) unless role_name.blank? + end + end + + end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb new file mode 100644 index 0000000..d5c6d35 --- /dev/null +++ b/app/helpers/admin_helper.rb @@ -0,0 +1,2 @@ +module AdminHelper +end diff --git a/app/models/ability.rb b/app/models/ability.rb new file mode 100644 index 0000000..7a26de4 --- /dev/null +++ b/app/models/ability.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class Ability + include CanCan::Ability + + def initialize(user) + user ||= User.new # guest user (not logged in) + if user.has_role? :admin + can :manage, :all + can :create, User if user.has_role? :admin + else + can :read, :all + # Define other abilities for other roles + end + end +end diff --git a/app/views/admin/new_user.html.erb b/app/views/admin/new_user.html.erb new file mode 100644 index 0000000..486d9c7 --- /dev/null +++ b/app/views/admin/new_user.html.erb @@ -0,0 +1,52 @@ +