Module: Sequel::Plugins::Privacy::DatasetMethods

Extended by:
T::Generic, T::Helpers, T::Sig
Defined in:
lib/sequel/plugins/privacy.rb

Constant Summary collapse

EAGER_VC_KEY =

Thread-local key for propagating the current VC to eager-load datasets via the :eager_block injected in ClassMethods#associate.

:sequel_privacy_eager_vc

Instance Method Summary collapse

Instance Method Details

#allObject



791
792
793
794
# File 'lib/sequel/plugins/privacy.rb', line 791

def all
  results = super
  opts[:viewer_context] ? results.compact : results
end

#create(values = {}) ⇒ Object



828
829
830
# File 'lib/sequel/plugins/privacy.rb', line 828

def create(values = {})
  T.cast(new(values), Sequel::Model).save
end

#for_vc(vc) ⇒ Object



748
749
750
# File 'lib/sequel/plugins/privacy.rb', line 748

def for_vc(vc)
  clone(viewer_context: vc)
end

#new(values = {}) ⇒ Object



819
820
821
822
823
824
825
# File 'lib/sequel/plugins/privacy.rb', line 819

def new(values = {})
  instance = T.unsafe(model).new(values)
  if (vc = opts[:viewer_context])
    instance.instance_variable_set(:@viewer_context, vc)
  end
  instance
end

#post_load(all_records) ⇒ Object



803
804
805
806
807
808
809
810
811
812
813
814
815
816
# File 'lib/sequel/plugins/privacy.rb', line 803

def post_load(all_records)
  vc = opts[:viewer_context]
  return super unless vc && opts[:eager]

  all_records.compact!

  old = Thread.current[EAGER_VC_KEY]
  Thread.current[EAGER_VC_KEY] = vc
  begin
    super
  ensure
    Thread.current[EAGER_VC_KEY] = old
  end
end

#row_procObject



760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
# File 'lib/sequel/plugins/privacy.rb', line 760

def row_proc
  vc = opts[:viewer_context]
  return super unless vc

  model_class = T.cast(model, ClassMethods)
  vc_key = model_class.privacy_vc_key
  proc do |values|
    old_vc = Thread.current[vc_key]
    Thread.current[vc_key] = vc
    begin
      instance = model_class.(values)
    ensure
      Thread.current[vc_key] = old_vc
    end

    next nil if instance.nil?

    instance.instance_variable_set(:@viewer_context, vc)
    next instance if opts[:privacy_eager_load]
    next instance if Sequel::Privacy::Enforcer.in_policy_eval?

    if T.cast(instance, InstanceMethods).allow?(vc, :view)
      instance
    else
      Sequel::Privacy.logger&.debug { "Privacy denied :view on #{model_class}[#{instance.pk}]" }
      nil
    end
  end
end