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



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

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

#create(values = {}) ⇒ Object



867
868
869
# File 'lib/sequel/plugins/privacy.rb', line 867

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

#for_vc(vc) ⇒ Object



774
775
776
# File 'lib/sequel/plugins/privacy.rb', line 774

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

#new(values = {}) ⇒ Object



857
858
859
860
861
862
863
# File 'lib/sequel/plugins/privacy.rb', line 857

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



840
841
842
843
844
845
846
847
848
849
850
851
852
853
# File 'lib/sequel/plugins/privacy.rb', line 840

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



790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
# File 'lib/sequel/plugins/privacy.rb', line 790

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 Sequel::Privacy::Enforcer.in_policy_eval?
    next instance if Thread.current[EAGER_VC_KEY]

    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