Skip to content

Commit

Permalink
Merge branch 'edge'
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Oberholzer committed Aug 18, 2011
2 parents dca1f5f + a2d06ae commit fad2673
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 96 deletions.
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -2,7 +2,7 @@ require 'rubygems'
require 'rake'
require 'echoe'

Echoe.new('easy_roles', '1.2.0') do |p|
Echoe.new('easy_roles', '2.0.0.beta') do |p|
p.description = "Easy role authorization in rails"
p.url = "http://github.com/platform45/easy_roles"
p.author = "Platform45"
Expand Down
112 changes: 18 additions & 94 deletions lib/easy_roles.rb
@@ -1,107 +1,31 @@
require 'active_support'

module EasyRoles
def self.included(base)
base.extend ClassMethods
extend ActiveSupport::Concern

included do |base|
base.send :alias_method_chain, :method_missing, :roles
base.send :alias_method_chain, :respond_to?, :roles
end

ALLOWED_METHODS = [:serialize, :bitmask]

ALLOWED_METHODS.each do |method|
autoload method.capitalize.to_sym, "methods/#{method}"
end

module ClassMethods
def easy_roles(name, options = {})

options[:method] ||= :serialize

if options[:method] == :serialize
serialize name.to_sym, Array

ActiveSupport::Deprecation.silence do
respond_to?(:before_validation_on_create) ? before_validation_on_create(:make_default_roles) : before_validation(:make_default_roles, :on => :create)
end

class_eval <<-EOC
def has_role?(role)
#{name}.include?(role)
end
def add_role(role)
clear_roles if self.#{name}.nil?
has_role?(role) ? false : self.#{name} << role
end

begin
raise NameError unless ALLOWED_METHODS.include? options[:method]

def add_role!(role)
add_role(role)
self.save!
end
def remove_role(role)
self.#{name}.delete(role)
end
def remove_role!(role)
remove_role(role)
self.save!
end
def clear_roles
self.#{name} = []
end
def make_default_roles
clear_roles if #{name}.nil?
end
"EasyRoles::#{options[:method].to_s.camelize}".constantize.new(self, name, options)
rescue NameError
puts "[Easy Roles] Storage method does not exist reverting to Serialize"

private :make_default_roles
EOC
elsif options[:method] == :bitmask

def_name = (name == :roles) ? :easy_roles : :roles

class_eval <<-EOC
def self.list_roles
#{name.to_s.upcase}
end
def #{def_name}=(roles)
self.#{name} = (roles & #{name.to_s.upcase}).map { |r| 2**#{name.to_s.upcase}.index(r) }.sum
end
def #{def_name}
#{name.to_s.upcase}.reject { |r| ((#{name} || 0) & 2**#{name.to_s.upcase}.index(r)).zero? }
end
def has_role?(role)
#{def_name}.include?(role)
end
def add_role(role)
new_roles = #{def_name}.push(role).uniq
self.#{def_name} = new_roles
end
def add_role!(role)
add_role(role)
self.save!
end
def remove_role(role)
new_roles = #{def_name}
new_roles.delete(role)
self.#{def_name} = new_roles
end
def remove_role!(role)
remove_role(role)
self.save!
end
def clear_roles
self.#{name} = 0
end
def clear_roles!
self.#{name} = 0
self.save!
end
EOC
EasyRoles::Serialize.new(self, name, options)
end
end
end
Expand Down
55 changes: 55 additions & 0 deletions lib/methods/bitmask.rb
@@ -0,0 +1,55 @@
module EasyRoles
class Bitmask
def initialize(base, column_name, options)
base.send :define_method, :_roles= do |roles|
states = base.const_get(column_name.upcase.to_sym)

self[column_name.to_sym] = (roles & states).map { |r| 2**states.index(r) }.sum
end

base.send :define_method, :_roles do
states = base.const_get(column_name.upcase.to_sym)

states.reject { |r| ((self[column_name.to_sym] || 0) & 2**states.index(r)).zero? }
end

base.send :define_method, :has_role? do |role|
self._roles.inspect

self._roles.include?(role)
end

base.send :define_method, :add_role do |role|
new_roles = self._roles.push(role).uniq
self._roles = new_roles
end

base.send :define_method, :add_role! do |role|
add_role(role)
self.save!
end

base.send :define_method, :remove_role do |role|
new_roles = self._roles
new_roles.delete(role)

self._roles = new_roles
end

base.send :define_method, :remove_role! do |role|
remove_role(role)
self.save!
end

base.send :define_method, :clear_roles do
self[column_name.to_sym] = 0
end

base.send :define_method, :clear_roles! do
self.clear_roles

self.save!
end
end
end
end
45 changes: 45 additions & 0 deletions lib/methods/serialize.rb
@@ -0,0 +1,45 @@
module EasyRoles
class Serialize
def initialize(base, column_name, options)
base.serialize column_name.to_sym, Array

ActiveSupport::Deprecation.silence do
base.respond_to?(:before_validation_on_create) ? base.before_validation_on_create(:make_default_roles) : base.before_validation(:make_default_roles, :on => :create)
end

base.send :define_method, :has_role? do |role|
self[column_name.to_sym].include?(role)
end

base.send :define_method, :add_role do |role|
clear_roles if self[column_name.to_sym].blank?

has_role?(role) ? false : self[column_name.to_sym] << role
end

base.send :define_method, :add_role! do |role|
add_role(role)
self.save!
end

base.send :define_method, :remove_role do |role|
self[column_name.to_sym].delete(role)
end

base.send :define_method, :remove_role! do |role|
remove_role(role)
self.save!
end

base.send :define_method, :clear_roles do
self[column_name.to_sym] = []
end

base.send :define_method, :make_default_roles do
clear_roles if self[column_name.to_sym].blank?
end

base.send :private, :make_default_roles
end
end
end
2 changes: 1 addition & 1 deletion spec/easy_roles_spec.rb
Expand Up @@ -174,7 +174,7 @@
it "should allow me to set a users role" do
user = BitmaskUser.new
user.add_role 'admin'
user.roles.include?("admin").should be_true
user._roles.include?("admin").should be_true
end

it "should return true for is_admin? if the admin role is added to the user" do
Expand Down

0 comments on commit fad2673

Please sign in to comment.