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



797
798
799
800
# File 'lib/sequel/plugins/privacy.rb', line 797

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

#create(values = {}) ⇒ Object



842
843
844
# File 'lib/sequel/plugins/privacy.rb', line 842

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

#for_vc(vc) ⇒ Object



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

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

#new(values = {}) ⇒ Object



832
833
834
835
836
837
838
# File 'lib/sequel/plugins/privacy.rb', line 832

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



815
816
817
818
819
820
821
822
823
824
825
826
827
828
# File 'lib/sequel/plugins/privacy.rb', line 815

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



765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
# File 'lib/sequel/plugins/privacy.rb', line 765

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