Created
December 1, 2008 23:56
-
-
Save paul/30912 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Privilege # ensure that Privilege class is loaded | |
# This module provides access control behavior to ActiveRecord models. | |
# The class into which it is included must provide a '#client' method | |
# the result of which will be used as the context for authorization | |
# checks. | |
module AccessControl | |
# Indicates if +an_account+ is allowed to know of the existence of this | |
# object. | |
def visible_to?(an_account) | |
raise NotImplementedError | |
end | |
# Indicates if +an_account+ should allowed to create this object. | |
# This should be called before calling +#save+ on a new model object | |
# and the save should be performed only if true is returned. | |
def creatable_by?(an_account) | |
raise NotImplementedError | |
end | |
# Indicates if +an_account+ should be allowed to modify this object. | |
# This should before performing any actions which result in the | |
# database being updated. Such action should only be performed if | |
# true is returned. | |
def modifiable_by?(an_account) | |
raise NotImplementedError | |
end | |
def self.included(a_class) | |
a_class.extend(ActiveRecordClassMethods) | |
a_class.send(:visibility_privilege, "view_#{a_class.name.underscore}") | |
a_class.send(:creation_privilege, "create_#{a_class.name.underscore}") | |
a_class.send(:modification_privilege, "modify_#{a_class.name.underscore}") | |
end | |
module ActiveRecordClassMethods | |
protected | |
# Declares that object of the class on which this is called are | |
# visible to users that have the specified privilege. | |
def visibility_privilege(privilege_name) | |
define_method(:visible_to?) do |an_account| | |
an_account.has_privilege_at?(privilege_name, client) | |
end | |
end | |
# Declares that objects of this class are creatable by accounts who | |
# hold the +privilege+ at the client which owns this resource. | |
def creation_privilege(privilege_name) | |
define_method(:creatable_by?) do |an_account| | |
an_account.has_privilege_at?(privilege_name, client) | |
end | |
(class << self; self; end).instance_eval do | |
define_method(:creatable_by?) do |an_account| | |
!an_account.clients_at_which_account_has(Privilege(privilege_name)).empty? | |
end | |
end | |
end | |
# Declares that objects of this class are modifiable by accounts | |
# who hold the +privilege+ at the client which owns this resource. | |
def modification_privilege(privilege_name) | |
define_method(:modifiable_by?) do |an_account| | |
an_account.has_privilege_at?(privilege_name, client) | |
end | |
end | |
# Adds optional +:visible_to => an_account+ option to +#find(:all, | |
# options)+. This option will exclude any objects which are not | |
# visible to the specified account from the returned collection. | |
def find_every_with_visible_to_handling(options) | |
if account = options[:visible_to] | |
find_every_without_visible_to_handling(options).select {|rec| rec.visible_to?(account)} | |
else | |
find_every_without_visible_to_handling(options) | |
end | |
end | |
# Validates that the options passed to +#find()+ are all valid | |
# options | |
def validate_find_options(options) | |
options.assert_valid_keys((class << ::ActiveRecord::Base; self; end)::VALID_FIND_OPTIONS + [:visible_to]) | |
end | |
def self.extended(ar_class) | |
(class << ar_class; self; end).alias_method_chain :find_every, :visible_to_handling | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def index | |
@clients = Client.find(:all, :visible_to => requester) | |
respond_to :last_modified_at => @clients.maximum(:updated_at) do |format| | |
format.html { } | |
format.any(:sskj1, :ssj) { } | |
end | |
end | |
def show | |
@client = Client.find(params[:id], :visible_to => requester) | |
respond_to :last_modified_at => @client.updated_at do |format| | |
format.html { } | |
format.any(:sskj1, :ssj) { } | |
end | |
end | |
def new | |
@client = Client.new | |
raise NotPermittedError unless requester.may_create? Client | |
respond_to :html | |
end | |
def create | |
munge_json_params! | |
@client = Client.new(params[:client]) | |
raise NotPermittedError unless requester.may_create? @client | |
respond_to do |wants| | |
if @client.save | |
wants.html { redirect_to client_url(@client) } | |
wants.any(:ssj, :sskj1) { head(:created, :location => client_url(@client)) } | |
else | |
wants.html { render :action => 'new' } | |
wants.any(:ssj, :sskj1) { raise ActiveRecord::RecordInvalid, @client } | |
end | |
end | |
end | |
def edit | |
@client = client | |
raise NotPermittedError unless requester.may_modify? @client | |
respond_to :html, :last_modified_at => @client.updated_at | |
end | |
def update | |
@client = client | |
raise NotPermittedError unless requester.may_modify? @client | |
munge_json_params! | |
@client.update_attributes!(params[:client]) | |
respond_to do |wants| | |
wants.html { redirect_to client_url(@client) } | |
wants.any(:sskj1, :ssj) { head(:ok) } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment