Class: AIRecordFinder::SafetyGuard
- Inherits:
-
Object
- Object
- AIRecordFinder::SafetyGuard
- Defined in:
- lib/ai_record_finder/safety_guard.rb
Overview
Centralized policy checks that enforce fail-closed query safety.
Class Method Summary collapse
- .apply_tenant_scope(model:, relation:) ⇒ Object
- .enforce_limit!(limit:, max_limit:) ⇒ Object
- .validate_joins!(model:, joins:, configuration:) ⇒ Object
- .validate_model!(model:, configuration:) ⇒ Object
Class Method Details
.apply_tenant_scope(model:, relation:) ⇒ Object
37 38 39 40 41 42 43 44 45 |
# File 'lib/ai_record_finder/safety_guard.rb', line 37 def apply_tenant_scope(model:, relation:) return relation unless model.respond_to?(:current_tenant_scope) scope = model.current_tenant_scope return relation unless scope raise InvalidDSL, "current_tenant_scope must return an ActiveRecord::Relation" unless scope.is_a?(ActiveRecord::Relation) relation.merge(scope) end |
.enforce_limit!(limit:, max_limit:) ⇒ Object
47 48 49 50 51 |
# File 'lib/ai_record_finder/safety_guard.rb', line 47 def enforce_limit!(limit:, max_limit:) return if limit.is_a?(Integer) && limit.positive? && limit <= max_limit raise InvalidDSL, "limit must be between 1 and #{max_limit}" end |
.validate_joins!(model:, joins:, configuration:) ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/ai_record_finder/safety_guard.rb', line 18 def validate_joins!(model:, joins:, configuration:) joins = Array(joins) return if joins.empty? allowed = Array(configuration.allowed_associations[model.name] || configuration.allowed_associations[model]) reflection_names = model.reflect_on_all_associations.map { |association| association.name.to_s } joins.each do |join_name| join_name = join_name.to_s unless reflection_names.include?(join_name) raise InvalidDSL, "Unknown association join: #{join_name}" end unless allowed.include?(join_name) raise InvalidDSL, "Join not allowed by policy: #{join_name}" end end end |
.validate_model!(model:, configuration:) ⇒ Object
7 8 9 10 11 12 13 14 15 16 |
# File 'lib/ai_record_finder/safety_guard.rb', line 7 def validate_model!(model:, configuration:) unless defined?(ActiveRecord::Base) && model.is_a?(Class) && model < ActiveRecord::Base raise InvalidModelError, "Model must inherit from ActiveRecord::Base" end allowed_models = Array(configuration.allowed_models) return if allowed_models.include?(model) raise UnauthorizedModel, "Model #{model.name} is not in allowed_models" end |