Sha256: 33c7531a64d36f8cc5fa2d5abcad13adf57120093bb8c85a975d90ec0ce8b827

Contents?: true

Size: 1.82 KB

Versions: 3

Compression:

Stored size: 1.82 KB

Contents

# frozen_string_literal: true

require 'dry/monads/result'
require 'dry/monads/do'
require 'lamassu/policy_container'

module Lamassu
  # Guardian object for authorizing a subject
  class Guardian
    include Dry::Monads::Result::Mixin
    include Dry::Monads::List::Mixin
    include Dry::Monads::Do.for(:authorize_many)

    attr_reader :container

    def initialize(container: PolicyContainer.new)
      @container = container
      @namespace_resolver = Lamassu.namespace_resolver
    end

    alias_method :policies, :container

    # Check authorization for subject on target for one or more policies
    #
    # If more than one policy is specified, it will return the last Success if
    # all policies are successful. Otherwise, it will return the first Failure
    #
    # :reek:LongParameterList
    # @param [Object] subject Subject for authorization check
    # @param [Object,Module] target Target for authorization check
    # @param [Symbol,String] policies Policy or policies to check
    # @return [Dry::Result]
    def authorize(subject, target, *policies)
      case policies.length
      when 0
        raise ArgumentError, 'No policy given'
      when 1
        authorize_one(subject, target, *policies)
      else
        authorize_many(subject, target, *policies)
      end
    end

    private

    def authorize_one(subject, target, policy)
      namespace = @namespace_resolver.call(target)
      policy = container.resolve("#{namespace}.#{policy}")

      policy.call(subject, target).to_result
    end

    def authorize_many(subject, target, *policies)
      namespace = @namespace_resolver.call(target)

      Success(
        List.new(policies)
          .fmap { |policy| "#{namespace}.#{policy}" }
          .fmap(container.method(:resolve))
          .fmap { |policy| yield policy.call(subject, target) }
      )
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
lamassu-0.2.0 lib/lamassu/guardian.rb
lamassu-0.1.1 lib/lamassu/guardian.rb
lamassu-0.1.0 lib/lamassu/guardian.rb