Usually you login in to be authenicated on a web app.
Defintion of authenticate
'prove or show (something) to be true, genuine, or valid.'
'COMPUTING (of a user or process) have one's identity verified.'
Authenticated users may not be authorised to see all the content on a website.
For example, an admin user will see a lot more features.
Defintion of authorise
give official permission for or approval to (an undertaking or agent).
https://guides.railsgirls.com/devise https://www.sitepoint.com/devise-authentication-in-depth/ https://www.pluralsight.com/guides/implementing-a-custom-devise-sign-in-and-actioncable-rails-5
Add the following lines to the end of the gemfile
/Gemfile
gem 'devise'
gem 'cancancan'
Then at the command line run
bundle install
Run the devise
generators
rails generate devise:install
rails generate devise User
rails generate devise:views
Now lets update the database with the new user table
rake db:migrate
Add the following code between body
tags as shown below:
/app/views/layouts/application.html.erb
[...]
<body>
<div class="container">
<div id="navbar">
<ul class="nav navbar-nav">
<li><%= link_to 'Home', root_path %></li>
</ul>
<ul class="nav navbar-nav pull-right">
<% if user_signed_in? %>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><%= link_to 'Profile', edit_user_registration_path %></li>
<li><%= link_to 'Log out', destroy_user_session_path, method: :delete %></li>
</ul>
</li>
<% else %>
<li><%= link_to 'Log In', new_user_session_path %></li>
<li><%= link_to 'Sign Up', new_user_registration_path %></li>
<% end %>
</ul>
</div>
<% flash.each do |key, value| %>
<%= value %>
<% end %>
<%= yield %>
</div>
</body>
[...]
Add a test user
- click Sign-up
- enter test user details
- click profile to review
We will be using the can can gem we added earlier.
Create the Ability class from CanCanCan
rails generate cancan:ability
Uncomment the simple user test as follows
/app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
# Define abilities for the passed in user here. For example:
#
user ||= User.new # guest user (not logged in)
if user.admin?
can :manage, :all
else
can :read, :all
end
#
# The first argument to `can` is the action you are giving the user
# permission to do.
# If you pass :manage it will apply to every action. Other common actions
# here are :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on.
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
# class of the resource.
#
# The third argument is an optional hash of conditions to further filter the
# objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
#
# See the wiki for details:
# https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
end
end
Add an admin column to the User table
rails generate migration AddAdminToUser admin:boolean
Open the migration generated to verify the column being added.
Add an admin user using seeds.rb
by calling the User constructor as follows:
[...]
puts 'Creating an admin user'
User.new({ :email => 'admin@admin.com.au', :password => 'password321', :password_confirmation => 'password321', :admin => 'true'}).save
puts "Seeding Over"
Add a CanCan check around the edit link in the index page as follows:
/app/views/restaurants/index.html.erb
<h1>Restaurants</h1>
<ul>
<% @restaurants.each_with_index do |restaurant, index| %>
<li>
<%= restaurant.title %> - <%= restaurant.food_type %>
<%= link_to "show", restaurant_path(restaurant.id) %>
<% if can? :update, restaurant %>
<%= link_to "edit", edit_restaurant_path(restaurant.id) %>
<% end %>
<p>Reviews: <%= restaurant.reviews.count %></p>
</li>
<% end %>
</ul>
Unauthorised users may try to access links that are not visible
eg: http://localhost:3000/restaurants/4/edit
Add a call to authorize_resource
method in the restaurant controller to authorize it automatically for every action in that controller.
class RestaurantsController < ApplicationController
authorize_resource
[...]
-
Add CanCanCan checks so only admin users can edit, update and delete
-
Add a CanCanCan check for user around the Add Review link. If not logged in display a message to say must login to create a review and add a link to the login and sign up forms
-
Add a moderator user that can delete reviews but cannot edit or delete restaurants
-
test while logged in as each user type
-
test while not logged in
-
Add Bootstrap (if you don't already have it) and update the layout for the devise logina nd sign-up forms and profile page
-
continue working on the additional steps to the restaurant app from previous challenge:
https://gist.github.com/leahgarrett/9100cfdbc2a2b0765c1de5c810d1f785 -
Add devise and CanCan to the book app