Skip to content

stefkin/fat_model_auth

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fat Model Auth

Wikipedia defines Authorization as ‘the function of specifying access rights to resources’. Fat Model Auth allows the resources themselves to define these rights.

Install

gem intall fat_model_auth (or use with bundler)

Fat Model Auth is a simple, clean authorization system for Rails

  • How simple?

Controller

  • Imagine you have a controller for Articles:

    before_filter :load_article
    
    def edit
    end
    
    def update
      # Update shazam
    end
    
    private
    
    def load_article
      Article.find(params[:id])
    end
    
  • We want to ensure only the Articles Author can view the edit page or update

  • an Article.

  • Just Add a before filter:

    before_filter :auth_required, :only => [:edit, :update]
    
  • Add it AFTER you load the article

Go ahead and try and view the article

  • We are missing something:

    undefined method 'allows' for #<Article:0x204a8d8>

Model

  • Just add the following to your Article model:

    allows :edit, :update,
      :if => proc {|article, user| article.author == user}
    
  • Need different rules for different actions:

    allows :edit,
      :if => proc {|article, user| article.author.name.eql? 'Jeff'}
    
    allows :update,
      :if => proc {|article, user| article.allows_updating?}
    

Control which functions are displayed to a user

View

<%= link_to('EDIT', edit_article_path(article)) if allowed_to? :edit => article -%>
  • What about groups of controls:

    <% if allowed_to? :edit_or_destroy => article -%>
      <funky>html</funky> 
    <% end %>

Thats it.

Test First

The rules that define access control, are defined in the model. If you are testing first, start with a unit test:

  • EDIT

    assert @article.allows(@article.author).to_edit?
    
    deny @article.allows(@someone_else).to_edit?
    
  • UPDATE

    assert @article.allows(@jeff).to_update?
    
    deny @article.allows(@sammy).to_update?
    

These magic methods are created when you define ‘allows’ on your model.

When you say ‘auth_required’ in a before filter: The plugin looks for an object based on the name of the controller:

So if you put the before filter in the ‘articles_controller’ and you call the ‘edit’ action,

it generates the following call:

@article.allows(current_user).to_edit?

What happens if I am editing articles but I am not in the articles_controller?

  • Just add this to the controller

    class RestlessController < ApplicationController
      def override_authority
        @article
      end
    end
    

Remember

  1. A nil current_user will always return access_denied.

Access Denied is 404

Thats right deal with it or fork it.

Trying to access a resource without permission returns 404 In other words:

"Say What?"

New & Create and complex conditons

If you have complex conditions or when creating a new object it may not have the information you need in a before filter.

You can always get the same result by being explicit in the method:

# Articles controller

def create
  @article = current_user.articles.build(params[:article])
  return if access_denied?
end

Testing my controllers

login_as @no_good_user
get :edit, :id => @article.id

assert_response :not_found
assert_template 'public/404'

If you are using mock user, you may want to stub the response

@article.expects(:allows).returns(FatModelAuth::CannedGateKeeper.allows(:edit))

or

@article.expects(:allows).returns(FatModelAuth::CannedGateKeeper.denies(:edit))

Testing my views

Who does that?

step 1. Install should_pricot

login_as @no_good_user
get :edit, :id => @article.id

element('#power_user a[@href="/create/havok"]').should_be_missing

Copyright © 2009 [Brent Greeff], released under the MIT license

About

Simple clean Authorization system for Rails

Resources

License

Stars

Watchers

Forks

Packages

No packages published