Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
# frozen_string_literal: true

require 'json'
require 'rbac'
require 'delegate'

module FacultyRBAC
  # Permits RBAC queries relating to a specific user
  class User
    PERMISSIONS_QUERY = %(
      select ug.username, gp.filter, gp.filter_params, gp.filter_args
      from rbac_user_group ug
      join rbac_recursive_group gg on gg.member_group_id = ug.group_id
      join rbac_group_permission gp on gp.group_id = gg.group_id
      where ug.username = ? and gp.permission_name = ?
    )

    HAS_PERMISSION_QUERY = %(
      select exists (#{PERMISSIONS_QUERY})
    )

    # Delegator which decorates permission enumerables
    class PermissionDelegator < SimpleDelegator
      def permitted?(**context)
        return true if context.empty? && !empty?

        cleaned_context = context.transform_keys(&:to_s)

        any? do |filter|
          filter.all? { |k, v| !v.nil? && cleaned_context[k] == v }
        end
      end
    end

    def initialize(controller, username)
      @username = username.to_s
      @controller = controller
    end

    attr_reader :username

    def to_s
      @username
    end

    def _db
      @controller.db
    end

    def _parametric_filter(filter_params, filter_args)
      filter_params.transform_values { |parameter| filter_args[parameter] }
    end

    def _permission_filters(permission)
      _db[PERMISSIONS_QUERY, @username, permission.to_s].lazy.map do |row|
        parametric_filter = _parametric_filter(row[:filter_params], row[:filter_args])
        row[:filter].merge(parametric_filter)
      end
    end

    def lazy_permissions(permission)
      PermissionDelegator.new(_permission_filters(permission))
    end

    def permissions(permission)
      PermissionDelegator.new(_permission_filters(permission).to_a)
    end

    def allowed_to?(permission, **context)
      if context.empty?
        _db[HAS_PERMISSION_QUERY, @username, permission.to_s].get(:exists)
      else
        lazy_permissions(permission).permitted?(**context)
      end
    end
  end
end