Sha256: 836ac89897ceecbeffa78c3484411114e2542b4781a531bac6c848f7459b1b70

Contents?: true

Size: 1.77 KB

Versions: 1

Compression:

Stored size: 1.77 KB

Contents

require "callable"
require "fattr"

module YouShallNotPass
  class Authorizator
    def initialize(**attrs)
      attrs.each do |attr, value|
        send attr, value
      end
    end

    def can?(permission, **args)
      Array(policies.fetch(permission)).all? do |policy|
        Callable(policy).call(**args) == true
      end
    rescue KeyError => exception
      break_down_can(permission, exception, **args)
    end

    def break_down_can(permission, exception, **args)
      case permission
      when /_and_/
        permission.to_s.split("_and_").all? { |policy| can?(policy.to_sym, **args)}
      when /_or_/
        permission.to_s.split("_or_").any? { |policy| can?(policy.to_sym, **args)}
      when /\Anot_/
        policy = permission.to_s.gsub(/\Anot_/, "")
        ! can?(policy.to_sym, **args)
      else
        raise exception
      end
    end

    def perform_if(permission, **args)
      yield if can?(permission, **args)
    end

    def perform_unless(permission, **args)
      yield unless can?(permission, **args)
    end

    def policies
      @policies ||= __set_policies__
    end

    private

    def __set_policies__
      the_policies = methods.grep(/_policies\z/).map {|name| send(name)}.each_with_object({}) do |curr, res|
        res.merge!(curr)
      end

      the_policies.merge!( self.class.__dsl_policies__.each_with_object({}) { |policy, h|
                            block =  policy.last
                            h[policy.first] = instance_eval(&block)
                          })

      the_policies
    end

    def self.__dsl_policies__
      @__dsl_policies__ ||= {}
    end

    def self.policy(name, &block)
      __dsl_policies__[name] = block
    end

    def self.attribute(attr)
      fattr attr
    end
    private_class_method :attribute
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
you_shall_not_pass-0.2.1 lib/you_shall_not_pass/authorizator.rb