Access Keys:
Skip to content (Access Key - 0)

Knowledgebase

Administration and Restricting Access


Contents

Restricting access and activity is important to Role based sites. You will now add the ability to restrict access to certain parts of the site dependent upon which roles the user has been granted. You will also bootstrap an Admin (or Super User) account that will have the access ability to assign roles to other users.

Add Helper Methods


Add the following methods to app/controller/application_controller.rb

  def current_user?
    !session[:user_id].nil?
  end
  
  def logged_in
    unless current_user?
      flash[:error] = "Please Log In First"
      redirect_to log_in_path
    end
  end
  
  def admin?
    current_user.role_ids.include?(Role.find_by_name("Admin").id)
  end
  
  def authorize
    unless admin?
      flash[:error] = "Unauthorized Access"
      redirect_to root_url
      false
    end
  end

Add these lines to same file to make the helper methods available to all controllers:

  helper_method :current_user?
  helper_method :admin?
  helper_method :authorize
  helper_method :logged_in
  private

These methods basically return Boolean values that correspond to the method names. We will use these methods to determine, "Is there is a current user?", "Is the user the admin?", and "Is the user authorized to do this?".

The simple line "private" ensures these methods are private.

Restricting Access to Logged In Users


Add the before_filter line below to call a method before calling controller methods. This example shows how to restrict access to viewing and assigning roles to only users that are currently logged in.

Add the following line to the beginning of the class in app/controllers/roles_controller.rb:

  before_filter :logged_in

Make sure you are logged out and navigate to http://localhost:3000/roles. You should see the flash message that you must be logged in and redirected to the log in page.

Add Administrator Account


Add another rake task to bootstrap Admin and User roles to the database. The Admin role will grant users access to more restricted areas and methods. These tasks will also add an Admin account to the database. This account will be managed in a method User::authAdmin.

Add the following to lib/tasks/populate.rake:

  task :all => [:AuthServiceURL, :AdminRoleID] do
    puts "All rake tasks performed"
  end

  task :Admin => :environment do
    admin = User.new
    admin.username = "admin"
    admin.cred = "not null"
    admin.firstname = "Site"
    admin.lastname = "Administrator"
    admin.password = "not_actual_password" #password must be present but is set in User:authAdmin
    if admin.save
      puts "Admin account saved successful"
    else
      puts "Admin account unsuccessful save"
    end
  end
  
  task :Role => :environment do
    addRole("Admin", "Site Administrator")
    addRole("User", "Normal User")
  end
  
  task :AdminRoleID => [:Role, :Admin] do
    role = Role.find_by_name("Admin")
    role.user_ids = role.user_ids << User.find_by_username("admin").id
    if role.save
      puts "Admin role assigned successful"
    else
      puts "Admin role unsuccessfully assigned"
    end
  end

 def addRole(name, description)
    role = Role.new
    role.name = name
    role.description = description
    if role.save
      puts name + " role save successful"
    else
      puts name + " role unsuccessful save"
    end
  end

Rake tasks follow dependency rules. The line :AdminRoleID => [:Role, :Admin] means the :Role and :Admin tasks will be called before :AdminRoleID task will run. Therefore, just run the :AdminRoleID task to run all of these tasks.

GridClient %> rake populate:AdminRoleID

You should see the following output:

Admin save successful
User save successful
Admin account saved successful
Admin role assigned successful
The ":all" task depends on both :AuthServiceURL and :AdminRoldID. Running this task will run all tasks in the populate.rake file. Any new tasks created can easily be added to the hash of dependencies of the :all task.

Admin Credentials


The authAdmin method below will check the Admin account credentials at log in. Add the method to app/models/user.rb:

  def self.authAdmin(password)
    if password == "1234"
      return find_by_username("admin")
    end
  end
This is where the bootstrapped Admin account password is stored. This account is necessary because it will be the only account able to access and assign roles. Once another user is assigned the "Admin" role, this account can be deleted. However, only site administrators should have access to change this code.

Replace the create method in app/controllers/sessions_controller.rb with the following:

  def create
    if params[:username] == "admin"
      user = User.authAdmin(params[:password])
      cred = nil
    else
      username = String.new(params[:username])
      userCred = User.authUser(username.downcase, params[:password], params[:auth_service_url])
      if !userCred.nil?
        user = userCred.at(0)      
        if userCred.length > 1
          cred = userCred.at(1)
        end
      end
    end
    if user
      session[:user_id] = user.id
      session[:globus] = cred
      redirect_to roles_path, :notice => "Logged in!"
    else
      flash.now.alert = "Invalid username or password"
      render "new"
    end
    
  end

Restricting Access


Open the file app/views/roles/index.html.erb and add the code just below the <h1>Listing Roles<h1> header:

<% if admin? %>
<td><%= link_to 'Assign Roles to Users', role_assign_path %></td>
<% end %>
<br></br>

This code will call the admin? method to check if the current user has the admin role assigned to them. If they do, then the link will be displayed.

Check this by starting the rails server, log in with the credentials:

Dorian username: admin
Dorian password: 1234

Now, on the http://localhost:3000/roles page, a link to "Assign Roles to Users" should be available.

Here you can see the two user accounts, admin and mark, and the roles assigned to each. Notice "mark" does not have the admin role.

Here is the roles index page when logged in with "mark". Notice there is no link to "Assign Roles to Users".

This is an good example of how to hide items in the view from users without proper access. This is good because a separate administration view is not needed, as admin options can just be added in line to the existing view. However, users can still access the assign roles page if they navigate to http://localhost:3000/role/assign. The above code just hides the link on the page. To restrict which methods are available to users, add the following filter to class in app/controllers/roles_controller.rb

  before_filter :authorize, :except => [:index]

This will restrict user's access to just the index location, http://localhost:3000/roles. Any other attempts to access role pages or methods will redirected and will display the "Unauthorized Access" error message.

To make more methods available to users, such as "show", just add more methods to the hash in the filter (ex. before_filter :authorize, :except => [:index, :show]). Remove the except option to restrict all methods in the controller.

Be sure no unauthorized changes to roles will occur by adding the following filter to app/controllers/users_controller.rb:

  before_filter :authorize, :except => [:new, :create, :index]
Last edited by
Mark Vance (654 days ago) , ...
Adaptavist Theme Builder Powered by Atlassian Confluence