I have a rails application which manages all the registered users. All crud operations can be done on the details of the registered users. I now need to restrict the application in such a way that only the admin user should be allowed to view all the registered users. Any user without the admin privilege should be able to view, edit, and delete his/her post only. I have used devise gem for authentication and plans to use cancancan gem for authorization. I have only a single model class called Users which contains a text attribute (to store "Admin" or "Nonadmin"). Here is my controller code:
class UsersController < ApplicationController
before_filter :authenticate_user!
def index
if current_user.role == "Admin"
@users = User.all
else
@user = User.find(current_user.id)
end
redirect_to new_user_registration_path if current_user.nil?
respond_to do |format|
format.html
end
end
def show
if (User.all.pluck(:id).include?params[:id].to_i) == false
flash[:notice] = "You cannot perform such an action"
else
@user = User.find(params[:id])
end
respond_to do |format|
format.html
end
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to :action => 'index'
else
render :action => 'new'
end
end
def user_params
params.require(:user).permit(:first_name, :last_name, :age, :biography, :email)
end
def edit
if (User.all.pluck(:id).include?params[:id].to_i) == false
flash[:notice] = "You cannot perform such an action"
else
@user = User.find(params[:id])
end
respond_to do |format|
format.html
end
end
def update
params.inspect
@user = User.find(params[:id])
if @user.update_attributes(user_params)
redirect_to :action => 'show', :id => @user
else
render :action => 'edit'
end
end
def delete
User.find(params[:id]).destroy
redirect_to :action => 'index'
end
end
My user table has the following fields: id,email,first_name,last_name,biography,email,role. It also contains all the devise-related fields.Below is my User model :
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
after_initialize :default_values
private
def default_values
self.role ||= "Non-admin"
end
end
I have hardcoded my admin credentials in seeds.rb as shown below:
if User.find_by(:role => 'Admin').nil? User.create([{email:"admin_user@usermanagementsystem.com",password: "topsecret",first_name:"admin",last_name:"ums", biography: "i serve as admin at the ums", age:20, role: "Admin"}]) end
View files: Index.html.erb:-
<table id="albums" cellspacing="0">
<thead>
<tr>
<th> NAME </th>
<th> EMAIL </th>
<% if current_user.role == "Admin" %>
<th> EDIT </th>
<th> SHOW </th>
<th> DESTROY </th>
<% end %>
<th colspan="15"></th>
</tr>
</thead>
<% if current_user.role == "Admin" %>
<% @users.each do |user| %>
<tr>
<td><%= user.first_name %></td>
<td><%= user.email %></td>
<td><%= link_to 'Edit', users_edit_path(id: user.id), class: "small button"%></td>
<td><%= link_to 'Show', users_show_path(id: user.id), class: "small button"%></td>
<td><%= link_to 'Destroy', users_delete_path(id: user.id), method: :delete, data: { confirm: 'Are you sure?' } , class: "small button"%></td>
</tr>
<% end %>
<% else %>
<tr>
<td><%= @user.first_name %></td>
<td><%= @user.email %></td>
<td><%= link_to 'Edit', users_edit_path(id: @user.id), class: "small button" %></td>
<td><%= link_to 'Destroy', users_delete_path(id: @user.id), method: :delete, data: { confirm: 'Are you sure?' } , class: "small button"%></td>
</tr>
<%end %>
</table>
<%#= link_to 'Change password', edit_user_registration_path, class: "small button" %>
edit.html.erb:-
<% if @user.nil? == false %>
<%= form_for @user , :as => :user, :url => users_update_path(@user), :method => :PUT do |f| %>
<%= f.label :first_name %>:
<%= f.text_field :first_name %><br>
<%= f.label :last_name %>:
<%= f.text_field :last_name %><br>
<%= f.label :age %>:
<%= f.number_field :age %><br>
<%= f.label :biography %>:
<%= f.text_field :biography %><br>
<%= f.label :email %>:
<%= f.text_field :email %><br>
<%= f.submit :class => 'small button' %>
<% end %>
<%else%>
<h3> Such a user record does not exist. Please click on a specific user </p>
<%end%>
show.html.erb
<br>
<br>
<% if @user.nil? == false %>
<h3>User details</h3>
<table id="albums" cellspacing="0">
<thead>
<tr>
<th>FIRSTNAME</th>
<th>LASTNAME</th>
<th>EMAIL</th>
<th>BIOGRAPHY</th>
<th>AGE</th>
<th colspan="20"></th>
</tr>
</thead>
<tr>
<td> <%= @user.first_name %> </td>
<td> <%= @user.last_name %> </td>
<td> <%= @user.email %> </td>
<td> <%= @user.biography %> </td>
<td> <%= @user.age %> </td>
</tr>
</table>
<%= link_to ' Edit ', users_edit_path(id: @user.id) , class: "small button"%>
<%= link_to 'Delete ', users_delete_path(id: @user.id), method: :delete, data: { confirm: 'Are you sure?' }, class: "small button" %>
<%else%>
<h3> Such a user record does not exist. Please click on a specific user </p>
<%= link_to "Logout", destroy_user_session_path, method: :delete, class: "small button" %>
</footer>
<%end%>
Can anyone help me out in using cancancan gem to restrict any user other than admin from viewing, editing, updating and deleting his own posts. Admin should be able to do these operations on everyone's records.
Please help me improve if you find me doing something wrong with the controller code too. Thanks in advance.
Added the following code to the initialize function of ability.rb and got it working correctly.
if user.role == "Admin" can :manage, :all else can [:index], User, id: user.id can [:show],User, id: user.id can [:edit],User, id: user.id can [:update], User,id: user.id can [:delete],User, id: user.id end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.