Skip to content

Instantly share code, notes, and snippets.

@mrkurt
Created July 24, 2008 21:19
Show Gist options
  • Save mrkurt/2303 to your computer and use it in GitHub Desktop.
Save mrkurt/2303 to your computer and use it in GitHub Desktop.
A mixin for creating secured proxy objects based on permission levels
module Securable
def self.included(base)
base.extend(ClassMethods)
end
class Secured
def initialize(p, o)
@o = o
@o.class.methods_with_permissions(p) {|m| define_proxy_method(m)}
end
def self.is_permission_match?(p, min_p)
case min_p
when :guest
true
when :admin
(p == :admin)
when :owner
(p == :admin || p == :owner)
else
false
end
end
private
def define_proxy_method(m)
(class << self; self; end).class_eval do
define_method m do |*args|
@o.send m, *args
end
end
end
end
module ClassMethods
def methods_with_permissions(p)
(@method_permissions ||= {}).each do |k, v|
yield k if Securable::Secured.is_permission_match?(p, v)
end
nil
end
private
def attr_accessor_secure(p, *args)
args.each do |a|
require_permissions_for_method(a, p)
attr_reader a
end
end
def require_permissions_for_method(m, p)
(@method_permissions ||= {})[m] = p
end
end
end
class User
include Securable
attr_accessor_secure :guest, :username
attr_accessor_secure :owner, :email, :password
attr_accessor_secure :admin, :role
end
u = User.new
u.username = 'kurt'
u.password = 'test'
u.email = 'kurt@mubble.net'
s = User::Secured.new(:guest, u)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment