resource_policy 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +20 -0
- data/.gitignore +15 -0
- data/.hound.yml +3 -0
- data/.rspec +3 -0
- data/.rubocop.yml +43 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +19 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +232 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/.nojekyll +0 -0
- data/docs/README.md +163 -0
- data/docs/_sidebar.md +6 -0
- data/docs/components/action_validator.md +34 -0
- data/docs/components/actions_policy.md +68 -0
- data/docs/components/attributes_policy.md +68 -0
- data/docs/components/policy.md +202 -0
- data/docs/index.html +70 -0
- data/lib/resource_policy/policy/action_policy_configuration.rb +37 -0
- data/lib/resource_policy/policy/actions_policy/action_policy.rb +32 -0
- data/lib/resource_policy/policy/actions_policy/actions_policy_model.rb +39 -0
- data/lib/resource_policy/policy/actions_policy.rb +35 -0
- data/lib/resource_policy/policy/attributes_policy/attribute_configuration.rb +72 -0
- data/lib/resource_policy/policy/attributes_policy/attribute_policy.rb +49 -0
- data/lib/resource_policy/policy/attributes_policy/attributes_policy_model.rb +52 -0
- data/lib/resource_policy/policy/attributes_policy.rb +58 -0
- data/lib/resource_policy/policy/merge_policies.rb +44 -0
- data/lib/resource_policy/policy/policy_configuration.rb +87 -0
- data/lib/resource_policy/policy.rb +31 -0
- data/lib/resource_policy/protected_resource.rb +43 -0
- data/lib/resource_policy/rails.rb +5 -0
- data/lib/resource_policy/validators/action_policy_validator.rb +54 -0
- data/lib/resource_policy/version.rb +5 -0
- data/lib/resource_policy.rb +11 -0
- data/resource_policy.gemspec +47 -0
- metadata +212 -0
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ResourcePolicy
         | 
| 4 | 
            +
              module Policy
         | 
| 5 | 
            +
                module AttributesPolicy
         | 
| 6 | 
            +
                  # Class which isolates methods defined via attributes_policy config
         | 
| 7 | 
            +
                  class AttributesPolicyModel
         | 
| 8 | 
            +
                    require 'resource_policy/policy/attributes_policy/attribute_policy'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def initialize(policy)
         | 
| 11 | 
            +
                      @policy = policy
         | 
| 12 | 
            +
                      @policy_item_by_name ||= {}
         | 
| 13 | 
            +
                    end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    def all
         | 
| 16 | 
            +
                      @all ||= config.attributes.keys.map do |attribute_name|
         | 
| 17 | 
            +
                        policy_item(attribute_name)
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    def all_allowed_to(status)
         | 
| 22 | 
            +
                      all.select { |attribute| attribute.allowed_to?(status) }
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    def method_missing(method_name)
         | 
| 26 | 
            +
                      return super unless config.attributes.key?(method_name.to_sym)
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                      policy_item(method_name.to_sym)
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                    def respond_to_missing?(method_name, *args)
         | 
| 32 | 
            +
                      config.attributes.key?(method_name.to_sym) || super
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                    private
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    attr_reader :policy
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def config
         | 
| 40 | 
            +
                      policy.class.policy
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                    def policy_item(name)
         | 
| 44 | 
            +
                      @policy_item_by_name[name] ||= begin
         | 
| 45 | 
            +
                        attribute = config.attributes.fetch(name)
         | 
| 46 | 
            +
                        AttributePolicy.new(attribute, policy: policy)
         | 
| 47 | 
            +
                      end
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ResourcePolicy
         | 
| 4 | 
            +
              module Policy
         | 
| 5 | 
            +
                # Allows to define fields policy using configuration block.
         | 
| 6 | 
            +
                #
         | 
| 7 | 
            +
                # Usage example:
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                # class SomeModelPolicy
         | 
| 10 | 
            +
                #   include ResourcePolicy::AttributesPolicy
         | 
| 11 | 
            +
                #
         | 
| 12 | 
            +
                #   policy do |c|
         | 
| 13 | 
            +
                #     c.attribute(:some_name)
         | 
| 14 | 
            +
                #       .allowed(:read, if: :readable?)
         | 
| 15 | 
            +
                #       .allowed(:write, if: :writable?)
         | 
| 16 | 
            +
                #
         | 
| 17 | 
            +
                #     c.group(:current_user_is_admin?) do |g|
         | 
| 18 | 
            +
                #       g.attribute(:password).allowed(:write)
         | 
| 19 | 
            +
                #     end
         | 
| 20 | 
            +
                #   end
         | 
| 21 | 
            +
                #
         | 
| 22 | 
            +
                #   def current_user_is_admin?
         | 
| 23 | 
            +
                #      current_user.admin?
         | 
| 24 | 
            +
                #   end
         | 
| 25 | 
            +
                #   ...
         | 
| 26 | 
            +
                # end
         | 
| 27 | 
            +
                #
         | 
| 28 | 
            +
                module AttributesPolicy
         | 
| 29 | 
            +
                  require 'resource_policy/policy/attributes_policy/attributes_policy_model'
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                  def protected_resource
         | 
| 32 | 
            +
                    @protected_resource ||= ProtectedResource.new(self)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  def action(name)
         | 
| 36 | 
            +
                    actions_policy.public_send(name) if actions_policy.respond_to?(name)
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def attribute(name)
         | 
| 40 | 
            +
                    attributes_policy.public_send(name) if attributes_policy.respond_to?(name)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def policy_target
         | 
| 44 | 
            +
                    send(self.class.policy.policy_target)
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                  def attributes_policy
         | 
| 48 | 
            +
                    @attributes_policy ||= AttributesPolicyModel.new(self)
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  private
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def resource_policy_initialize(*args)
         | 
| 54 | 
            +
                    @policy_target = args.first
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
            end
         | 
| @@ -0,0 +1,44 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ResourcePolicy
         | 
| 4 | 
            +
              module Policy
         | 
| 5 | 
            +
                # Service object using for merging two policy configurations
         | 
| 6 | 
            +
                class MergePolicies
         | 
| 7 | 
            +
                  class OverlappingActionError < ResourcePolicy::Error; end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def self.call(*args)
         | 
| 10 | 
            +
                    new(*args).call
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def initialize(policy, other_policy)
         | 
| 14 | 
            +
                    @policy = policy
         | 
| 15 | 
            +
                    @other_policy = other_policy
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def call
         | 
| 19 | 
            +
                    merge_actions
         | 
| 20 | 
            +
                    merge_attributes
         | 
| 21 | 
            +
                    policy
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                  private
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                  attr_reader :policy, :other_policy
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  def merge_actions
         | 
| 29 | 
            +
                    other_policy.actions.values.each do |action|
         | 
| 30 | 
            +
                      policy.action(action.name).allowed(if: action.conditions)
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  def merge_attributes
         | 
| 35 | 
            +
                    other_policy.attributes.values.each do |attribute|
         | 
| 36 | 
            +
                      attribute.defined_actions.each do |action_name|
         | 
| 37 | 
            +
                        conditions = attribute.conditions_for(action_name)
         | 
| 38 | 
            +
                        policy.attribute(attribute.name).allowed(action_name, if: conditions)
         | 
| 39 | 
            +
                      end
         | 
| 40 | 
            +
                    end
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
            end
         | 
| @@ -0,0 +1,87 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ResourcePolicy
         | 
| 4 | 
            +
              module Policy
         | 
| 5 | 
            +
                # Stores all configuration about policy
         | 
| 6 | 
            +
                class PolicyConfiguration
         | 
| 7 | 
            +
                  require 'resource_policy/policy/action_policy_configuration'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  require 'resource_policy/policy/attributes_policy/attribute_configuration'
         | 
| 10 | 
            +
                  require 'resource_policy/policy/merge_policies'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  EmptyConfiguration = Class.new do
         | 
| 13 | 
            +
                    def group_conditions
         | 
| 14 | 
            +
                      []
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  EMPTY_CONFIGURATION = EmptyConfiguration.new
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def initialize(parent_configuration: EMPTY_CONFIGURATION, extra_group_conditions: [])
         | 
| 21 | 
            +
                    @actions = {}
         | 
| 22 | 
            +
                    @attributes = {}
         | 
| 23 | 
            +
                    @parent_configuration = parent_configuration
         | 
| 24 | 
            +
                    @extra_group_conditions = extra_group_conditions
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  def initialize_copy(_other)
         | 
| 28 | 
            +
                    @actions = @actions.dup.each.with_object({}) { |(key, value), result| result[key] = value.dup }
         | 
| 29 | 
            +
                    @attributes = @attributes.dup.each.with_object({}) { |(key, value), result| result[key] = value.dup }
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def policy_target(policy_target_name = nil)
         | 
| 33 | 
            +
                    @policy_target = policy_target_name if policy_target_name
         | 
| 34 | 
            +
                    @policy_target
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def attribute(attribute_name)
         | 
| 38 | 
            +
                    symbolized_name = attribute_name.to_sym
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    @attributes[symbolized_name] ||= AttributesPolicy::AttributeConfiguration.new(
         | 
| 41 | 
            +
                      symbolized_name, policy_configuration: self
         | 
| 42 | 
            +
                    )
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  def attributes
         | 
| 46 | 
            +
                    @attributes.select { |_name, action| action.configured? }
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  def actions
         | 
| 50 | 
            +
                    @actions.select { |_name, action| action.configured? }
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                  def action(attribute_name)
         | 
| 54 | 
            +
                    symbolized_name = attribute_name.to_sym
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    @actions[symbolized_name] ||= ActionPolicyConfiguration.new(
         | 
| 57 | 
            +
                      symbolized_name, policy_configuration: self
         | 
| 58 | 
            +
                    )
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                  def group(*new_conditions)
         | 
| 62 | 
            +
                    return @group if new_conditions.empty?
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    unique_new_conditions = new_conditions.map(&:to_sym).uniq
         | 
| 65 | 
            +
                    group_config = self.class.new(
         | 
| 66 | 
            +
                      parent_configuration: self,
         | 
| 67 | 
            +
                      extra_group_conditions: unique_new_conditions
         | 
| 68 | 
            +
                    )
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    yield(group_config)
         | 
| 71 | 
            +
                    tap { |config| config.merge(group_config) }
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  def group_conditions
         | 
| 75 | 
            +
                    (parent_configuration.group_conditions + extra_group_conditions).uniq
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  def merge(other)
         | 
| 79 | 
            +
                    MergePolicies.call(self, other)
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  protected
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                  attr_reader :extra_group_conditions, :parent_configuration
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ResourcePolicy
         | 
| 4 | 
            +
              # Gives policy configuration methods for any policy class
         | 
| 5 | 
            +
              module Policy
         | 
| 6 | 
            +
                require 'resource_policy/protected_resource'
         | 
| 7 | 
            +
                require 'resource_policy/policy/policy_configuration'
         | 
| 8 | 
            +
                require 'resource_policy/policy/attributes_policy'
         | 
| 9 | 
            +
                require 'resource_policy/policy/actions_policy'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # Class methods.
         | 
| 12 | 
            +
                module ClassMethods
         | 
| 13 | 
            +
                  def policy
         | 
| 14 | 
            +
                    @policy ||= Policy::PolicyConfiguration.new
         | 
| 15 | 
            +
                    yield(@policy) if block_given?
         | 
| 16 | 
            +
                    @policy
         | 
| 17 | 
            +
                  end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                  def inherited(subclass)
         | 
| 20 | 
            +
                    super
         | 
| 21 | 
            +
                    subclass.instance_variable_set(:@policy, policy.dup)
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.included(receiver)
         | 
| 26 | 
            +
                  receiver.send(:extend, ClassMethods)
         | 
| 27 | 
            +
                  receiver.send(:include, ::ResourcePolicy::Policy::ActionsPolicy)
         | 
| 28 | 
            +
                  receiver.send(:include, ::ResourcePolicy::Policy::AttributesPolicy)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module ResourcePolicy
         | 
| 4 | 
            +
              # Generates resource which has same attributes as policy target,
         | 
| 5 | 
            +
              # but returns `nil` when attribute in not readable according to policy
         | 
| 6 | 
            +
              class ProtectedResource
         | 
| 7 | 
            +
                def initialize(policy)
         | 
| 8 | 
            +
                  @policy = policy
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def method_missing(method_name, *args)
         | 
| 12 | 
            +
                  return super unless target_respond_to?(method_name, *args)
         | 
| 13 | 
            +
                  return nil unless policy.attribute(method_name).readable?
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  policy_target.public_send(method_name, *args)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def respond_to_missing?(*args)
         | 
| 19 | 
            +
                  target_respond_to?(*args) || super
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                private
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                attr_reader :policy
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                def target_respond_to?(method_name, *args)
         | 
| 27 | 
            +
                  accessible_attributes.include?(method_name.to_sym) &&
         | 
| 28 | 
            +
                    policy_target.respond_to?(method_name, *args)
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def accessible_attributes
         | 
| 32 | 
            +
                  attributes = policy.class.policy.attributes.values.select do |attribute|
         | 
| 33 | 
            +
                    attribute.defined_action?(:read)
         | 
| 34 | 
            +
                  end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  attributes.map(&:name)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def policy_target
         | 
| 40 | 
            +
                  policy.policy_target
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Available options:
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            #   * `:allowed_to` (required) - action type which we need to check.
         | 
| 6 | 
            +
            #   * `:as` (optional) - key which will be used to display errors.
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            # Usage example:
         | 
| 9 | 
            +
            #
         | 
| 10 | 
            +
            #   class SomeClass
         | 
| 11 | 
            +
            #     validates :some_policy, 'resource_policy/action': { allowed_to: :create, as: :some_item }
         | 
| 12 | 
            +
            #
         | 
| 13 | 
            +
            #     def some_policy
         | 
| 14 | 
            +
            #       SomePolicy.new
         | 
| 15 | 
            +
            #     end
         | 
| 16 | 
            +
            #   end
         | 
| 17 | 
            +
            #
         | 
| 18 | 
            +
            module ResourcePolicy
         | 
| 19 | 
            +
              class ActionValidator < ActiveModel::EachValidator
         | 
| 20 | 
            +
                def validate_each(record, default_attribute, policy)
         | 
| 21 | 
            +
                  attribute = options.fetch(:as, default_attribute)
         | 
| 22 | 
            +
                  action_policy = policy.action(action_name)
         | 
| 23 | 
            +
                  validate_action_policy(action_policy, record:, attribute:)
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                private
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def validate_action_policy(policy, record:, attribute:)
         | 
| 29 | 
            +
                  if policy.nil?
         | 
| 30 | 
            +
                    add_missing_policy_error_for(record, attribute:)
         | 
| 31 | 
            +
                  elsif !policy.allowed?
         | 
| 32 | 
            +
                    add_not_permitted_error_for(record, attribute:)
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def action_name
         | 
| 37 | 
            +
                  @action_name ||= options.fetch(:allowed_to)
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def add_missing_policy_error_for(record, attribute:)
         | 
| 41 | 
            +
                  record.errors.add(
         | 
| 42 | 
            +
                    attribute,
         | 
| 43 | 
            +
                    "does not have #{action_name.to_s.inspect} action policy defined"
         | 
| 44 | 
            +
                  )
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                def add_not_permitted_error_for(record, attribute:)
         | 
| 48 | 
            +
                  record.errors.add(
         | 
| 49 | 
            +
                    attribute,
         | 
| 50 | 
            +
                    "action #{action_name.to_s.inspect} is not allowed"
         | 
| 51 | 
            +
                  )
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            lib = File.expand_path('lib', __dir__)
         | 
| 4 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 5 | 
            +
            require 'resource_policy/version'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            Gem::Specification.new do |spec|
         | 
| 8 | 
            +
              spec.name          = 'resource_policy'
         | 
| 9 | 
            +
              spec.version       = ResourcePolicy::VERSION
         | 
| 10 | 
            +
              spec.authors       = ['Povilas Jurcys']
         | 
| 11 | 
            +
              spec.email         = ['po.jurcys@gmail.com']
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              spec.summary       = "Access control for single resource and it's methods"
         | 
| 14 | 
            +
              spec.homepage      = 'https://github.com/samesystem/resource_policy'
         | 
| 15 | 
            +
              spec.license       = 'MIT'
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
         | 
| 18 | 
            +
              # to allow pushing to a single host or delete this section to allow pushing to any host.
         | 
| 19 | 
            +
              if spec.respond_to?(:metadata)
         | 
| 20 | 
            +
                spec.metadata['homepage_uri'] = spec.homepage
         | 
| 21 | 
            +
                spec.metadata['source_code_uri'] = 'https://github.com/samesystem/resource_policy'
         | 
| 22 | 
            +
                spec.metadata['changelog_uri'] = \
         | 
| 23 | 
            +
                  "https://github.com/samesystem/resource_policy/blob/v#{ResourcePolicy::VERSION}/CHANGELOG.md"
         | 
| 24 | 
            +
              else
         | 
| 25 | 
            +
                raise 'RubyGems 2.0 or newer is required to protect against ' \
         | 
| 26 | 
            +
                  'public gem pushes.'
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              # Specify which files should be added to the gem when it is released.
         | 
| 30 | 
            +
              # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
         | 
| 31 | 
            +
              spec.files = Dir.chdir(File.expand_path(__dir__)) do
         | 
| 32 | 
            +
                `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              spec.bindir        = 'exe'
         | 
| 35 | 
            +
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 36 | 
            +
              spec.require_paths = ['lib']
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              spec.add_development_dependency 'bundler', '~> 2.0'
         | 
| 39 | 
            +
              spec.add_development_dependency 'pry-byebug'
         | 
| 40 | 
            +
              spec.add_development_dependency 'rake', '~> 13.0'
         | 
| 41 | 
            +
              spec.add_development_dependency 'rspec', '~> 3.0'
         | 
| 42 | 
            +
              spec.add_development_dependency 'rubocop'
         | 
| 43 | 
            +
              spec.add_development_dependency 'rubocop-performance'
         | 
| 44 | 
            +
              spec.add_development_dependency 'rubocop-rails'
         | 
| 45 | 
            +
              spec.add_development_dependency 'rubocop-rspec'
         | 
| 46 | 
            +
              spec.add_development_dependency 'rails', '~> 7.0.0'
         | 
| 47 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,212 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: resource_policy
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 1.0.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Povilas Jurcys
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: exe
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2023-02-02 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bundler
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '2.0'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '2.0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: pry-byebug
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - ">="
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '0'
         | 
| 34 | 
            +
              type: :development
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - ">="
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rake
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '13.0'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '13.0'
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: rspec
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - "~>"
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: '3.0'
         | 
| 62 | 
            +
              type: :development
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - "~>"
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: '3.0'
         | 
| 69 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 70 | 
            +
              name: rubocop
         | 
| 71 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 72 | 
            +
                requirements:
         | 
| 73 | 
            +
                - - ">="
         | 
| 74 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            +
                    version: '0'
         | 
| 76 | 
            +
              type: :development
         | 
| 77 | 
            +
              prerelease: false
         | 
| 78 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 79 | 
            +
                requirements:
         | 
| 80 | 
            +
                - - ">="
         | 
| 81 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 82 | 
            +
                    version: '0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: rubocop-performance
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - ">="
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '0'
         | 
| 90 | 
            +
              type: :development
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - ">="
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '0'
         | 
| 97 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 98 | 
            +
              name: rubocop-rails
         | 
| 99 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 100 | 
            +
                requirements:
         | 
| 101 | 
            +
                - - ">="
         | 
| 102 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            +
                    version: '0'
         | 
| 104 | 
            +
              type: :development
         | 
| 105 | 
            +
              prerelease: false
         | 
| 106 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 | 
            +
                requirements:
         | 
| 108 | 
            +
                - - ">="
         | 
| 109 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            +
                    version: '0'
         | 
| 111 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 112 | 
            +
              name: rubocop-rspec
         | 
| 113 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 114 | 
            +
                requirements:
         | 
| 115 | 
            +
                - - ">="
         | 
| 116 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 117 | 
            +
                    version: '0'
         | 
| 118 | 
            +
              type: :development
         | 
| 119 | 
            +
              prerelease: false
         | 
| 120 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 121 | 
            +
                requirements:
         | 
| 122 | 
            +
                - - ">="
         | 
| 123 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 124 | 
            +
                    version: '0'
         | 
| 125 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 126 | 
            +
              name: rails
         | 
| 127 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 128 | 
            +
                requirements:
         | 
| 129 | 
            +
                - - "~>"
         | 
| 130 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            +
                    version: 7.0.0
         | 
| 132 | 
            +
              type: :development
         | 
| 133 | 
            +
              prerelease: false
         | 
| 134 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 | 
            +
                requirements:
         | 
| 136 | 
            +
                - - "~>"
         | 
| 137 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            +
                    version: 7.0.0
         | 
| 139 | 
            +
            description: 
         | 
| 140 | 
            +
            email:
         | 
| 141 | 
            +
            - po.jurcys@gmail.com
         | 
| 142 | 
            +
            executables: []
         | 
| 143 | 
            +
            extensions: []
         | 
| 144 | 
            +
            extra_rdoc_files: []
         | 
| 145 | 
            +
            files:
         | 
| 146 | 
            +
            - ".github/workflows/ruby.yml"
         | 
| 147 | 
            +
            - ".gitignore"
         | 
| 148 | 
            +
            - ".hound.yml"
         | 
| 149 | 
            +
            - ".rspec"
         | 
| 150 | 
            +
            - ".rubocop.yml"
         | 
| 151 | 
            +
            - ".ruby-version"
         | 
| 152 | 
            +
            - ".travis.yml"
         | 
| 153 | 
            +
            - CHANGELOG.md
         | 
| 154 | 
            +
            - CODE_OF_CONDUCT.md
         | 
| 155 | 
            +
            - Gemfile
         | 
| 156 | 
            +
            - Gemfile.lock
         | 
| 157 | 
            +
            - LICENSE.txt
         | 
| 158 | 
            +
            - Rakefile
         | 
| 159 | 
            +
            - bin/console
         | 
| 160 | 
            +
            - bin/setup
         | 
| 161 | 
            +
            - docs/.nojekyll
         | 
| 162 | 
            +
            - docs/README.md
         | 
| 163 | 
            +
            - docs/_sidebar.md
         | 
| 164 | 
            +
            - docs/components/action_validator.md
         | 
| 165 | 
            +
            - docs/components/actions_policy.md
         | 
| 166 | 
            +
            - docs/components/attributes_policy.md
         | 
| 167 | 
            +
            - docs/components/policy.md
         | 
| 168 | 
            +
            - docs/index.html
         | 
| 169 | 
            +
            - lib/resource_policy.rb
         | 
| 170 | 
            +
            - lib/resource_policy/policy.rb
         | 
| 171 | 
            +
            - lib/resource_policy/policy/action_policy_configuration.rb
         | 
| 172 | 
            +
            - lib/resource_policy/policy/actions_policy.rb
         | 
| 173 | 
            +
            - lib/resource_policy/policy/actions_policy/action_policy.rb
         | 
| 174 | 
            +
            - lib/resource_policy/policy/actions_policy/actions_policy_model.rb
         | 
| 175 | 
            +
            - lib/resource_policy/policy/attributes_policy.rb
         | 
| 176 | 
            +
            - lib/resource_policy/policy/attributes_policy/attribute_configuration.rb
         | 
| 177 | 
            +
            - lib/resource_policy/policy/attributes_policy/attribute_policy.rb
         | 
| 178 | 
            +
            - lib/resource_policy/policy/attributes_policy/attributes_policy_model.rb
         | 
| 179 | 
            +
            - lib/resource_policy/policy/merge_policies.rb
         | 
| 180 | 
            +
            - lib/resource_policy/policy/policy_configuration.rb
         | 
| 181 | 
            +
            - lib/resource_policy/protected_resource.rb
         | 
| 182 | 
            +
            - lib/resource_policy/rails.rb
         | 
| 183 | 
            +
            - lib/resource_policy/validators/action_policy_validator.rb
         | 
| 184 | 
            +
            - lib/resource_policy/version.rb
         | 
| 185 | 
            +
            - resource_policy.gemspec
         | 
| 186 | 
            +
            homepage: https://github.com/samesystem/resource_policy
         | 
| 187 | 
            +
            licenses:
         | 
| 188 | 
            +
            - MIT
         | 
| 189 | 
            +
            metadata:
         | 
| 190 | 
            +
              homepage_uri: https://github.com/samesystem/resource_policy
         | 
| 191 | 
            +
              source_code_uri: https://github.com/samesystem/resource_policy
         | 
| 192 | 
            +
              changelog_uri: https://github.com/samesystem/resource_policy/blob/v1.0.0/CHANGELOG.md
         | 
| 193 | 
            +
            post_install_message: 
         | 
| 194 | 
            +
            rdoc_options: []
         | 
| 195 | 
            +
            require_paths:
         | 
| 196 | 
            +
            - lib
         | 
| 197 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 198 | 
            +
              requirements:
         | 
| 199 | 
            +
              - - ">="
         | 
| 200 | 
            +
                - !ruby/object:Gem::Version
         | 
| 201 | 
            +
                  version: '0'
         | 
| 202 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 203 | 
            +
              requirements:
         | 
| 204 | 
            +
              - - ">="
         | 
| 205 | 
            +
                - !ruby/object:Gem::Version
         | 
| 206 | 
            +
                  version: '0'
         | 
| 207 | 
            +
            requirements: []
         | 
| 208 | 
            +
            rubygems_version: 3.3.7
         | 
| 209 | 
            +
            signing_key: 
         | 
| 210 | 
            +
            specification_version: 4
         | 
| 211 | 
            +
            summary: Access control for single resource and it's methods
         | 
| 212 | 
            +
            test_files: []
         |