lib/blind_index/model.rb in blind_index-0.3.5 vs lib/blind_index/model.rb in blind_index-1.0.0
- old
+ new
@@ -1,61 +1,86 @@
module BlindIndex
module Model
- def blind_index(name, key: nil, iterations: nil, attribute: nil, expression: nil, bidx_attribute: nil, callback: true, algorithm: nil, insecure_key: nil, encode: nil, cost: nil, size: nil)
- iterations ||= 10000
- attribute ||= name
- bidx_attribute ||= :"encrypted_#{name}_bidx"
+ def blind_index(*attributes, rotate: false, migrating: false, **opts)
+ indexes = attributes.map { |a| [a, opts.dup] }
+ indexes.concat(attributes.map { |a| [a, rotate.merge(rotate: true)] }) if rotate
- name = name.to_sym
- attribute = attribute.to_sym
- method_name = :"compute_#{name}_bidx"
+ indexes.each do |name, options|
+ rotate = options.delete(:rotate)
- class_eval do
- @blind_indexes ||= {}
+ # check here so we validate rotate options as well
+ unknown_keywords = options.keys - [:algorithm, :attribute, :bidx_attribute,
+ :callback, :cost, :encode, :expression, :insecure_key, :iterations, :key,
+ :legacy, :master_key, :size, :slow]
+ raise ArgumentError, "unknown keywords: #{unknown_keywords.join(", ")}" if unknown_keywords.any?
- unless respond_to?(:blind_indexes)
- def self.blind_indexes
- parent_indexes =
- if superclass.respond_to?(:blind_indexes)
- superclass.blind_indexes
- else
- {}
- end
+ attribute = options[:attribute] || name
+ version = (options[:version] || 1).to_i
+ callback = options[:callback].nil? ? true : options[:callback]
+ if options[:bidx_attribute]
+ bidx_attribute = options[:bidx_attribute]
+ else
+ bidx_attribute = name
+ bidx_attribute = "encrypted_#{bidx_attribute}" if options[:legacy]
+ bidx_attribute = "#{bidx_attribute}_bidx"
+ bidx_attribute = "#{bidx_attribute}_v#{version}" if version != 1
+ end
- parent_indexes.merge(@blind_indexes || {})
+ name = "migrated_#{name}" if migrating
+ name = "rotated_#{name}" if rotate
+ name = name.to_sym
+ attribute = attribute.to_sym
+ method_name = :"compute_#{name}_bidx"
+ class_method_name = :"generate_#{name}_bidx"
+
+ key = options[:key]
+ key ||= -> { BlindIndex.index_key(table: table_name, bidx_attribute: bidx_attribute, master_key: options[:master_key], encode: false) }
+
+ class_eval do
+ @blind_indexes ||= {}
+
+ unless respond_to?(:blind_indexes)
+ def self.blind_indexes
+ parent_indexes =
+ if superclass.respond_to?(:blind_indexes)
+ superclass.blind_indexes
+ else
+ {}
+ end
+
+ parent_indexes.merge(@blind_indexes || {})
+ end
end
- end
- raise BlindIndex::Error, "Duplicate blind index: #{name}" if blind_indexes[name]
+ raise BlindIndex::Error, "Duplicate blind index: #{name}" if blind_indexes[name]
- @blind_indexes[name] = {
- key: key,
- iterations: iterations,
- attribute: attribute,
- expression: expression,
- bidx_attribute: bidx_attribute,
- algorithm: algorithm,
- insecure_key: insecure_key,
- encode: encode,
- cost: cost,
- size: size
- }.reject { |_, v| v.nil? }
+ @blind_indexes[name] = options.merge(
+ key: key,
+ attribute: attribute,
+ bidx_attribute: bidx_attribute,
+ migrating: migrating
+ )
- # should have been named generate_#{name}_bidx
- define_singleton_method method_name do |value|
- BlindIndex.generate_bidx(value, blind_indexes[name])
- end
+ define_singleton_method class_method_name do |value|
+ BlindIndex.generate_bidx(value, blind_indexes[name])
+ end
- define_method method_name do
- self.send("#{bidx_attribute}=", self.class.send(method_name, send(attribute)))
- end
+ define_singleton_method method_name do |value|
+ ActiveSupport::Deprecation.warn("Use #{class_method_name} instead")
+ send(class_method_name, value)
+ end
- if callback
- before_validation method_name, if: -> { changes.key?(attribute.to_s) }
- end
+ define_method method_name do
+ self.send("#{bidx_attribute}=", self.class.send(class_method_name, send(attribute)))
+ end
- # use include so user can override
- include InstanceMethods if blind_indexes.size == 1
+ if callback
+ before_validation method_name, if: -> { changes.key?(attribute.to_s) }
+ end
+
+ # use include so user can override
+ include InstanceMethods if blind_indexes.size == 1
+ end
end
end
end
module InstanceMethods