Sha256: c9794c5255b8fff096a032f6219b4ad9a31fbf6d593a82fa4a950ae911981e28

Contents?: true

Size: 1.93 KB

Versions: 31

Compression:

Stored size: 1.93 KB

Contents

# frozen_string_literal: true

require "active_support/concern"

module Decidim
  # This module adds support functionality to be able to generate a unique fingerprint
  # from a model, given some fields. Its goal is to provide a way to give an informal
  # "receipt" to a user to they can detect tampering.
  #
  module Fingerprintable
    extend ActiveSupport::Concern

    class_methods do
      attr_reader :fingerprint_options

      # Public: Configures fingerprinting for this model.
      #
      # fields - An `Array` of `symbols` specifying the fields that will be part of
      #          the fingerprint generation.
      # block  - (optional) When provided, it's given an instance of the model as a
      #          parameter so the fingerprint can be generated in runtime.
      #
      # Returns nothing.
      def fingerprint(fields: nil, &block)
        @fingerprint_options = {}

        if block_given?
          @fingerprint_options[:block] = block
        else
          raise "You must provide a set of fields to generate the fingerprint." unless fields

          @fingerprint_options[:fields] = fields
        end
      end
    end

    # Public: Returns an instance of `FingerprintCalculator` containing the fingerprint.
    #
    # Example:
    #
    #    model.fingerprint.value  # Returns the fingerprint as a String
    #    model.fingerprint.source # Returns the source String (usually a json) from which
    #                             # the fingerprint is generated.
    def fingerprint
      @fingerprint ||= FingerprintCalculator.new(fingerprint_data)
    end

    private

    def fingerprint_data
      options = self.class.fingerprint_options

      if options[:block]
        options[:block].call(self)
      elsif options[:fields]
        options[:fields].index_with do |field|
          send(field)
        end
      else
        raise "Fingerprinting needs to be set up via the `fingerprint` class method."
      end
    end
  end
end

Version data entries

31 entries across 31 versions & 1 rubygems

Version Path
decidim-core-0.27.9 lib/decidim/fingerprintable.rb
decidim-core-0.27.8 lib/decidim/fingerprintable.rb
decidim-core-0.27.7 lib/decidim/fingerprintable.rb
decidim-core-0.27.6 lib/decidim/fingerprintable.rb
decidim-core-0.26.10 lib/decidim/fingerprintable.rb
decidim-core-0.26.9 lib/decidim/fingerprintable.rb
decidim-core-0.27.5 lib/decidim/fingerprintable.rb
decidim-core-0.26.8 lib/decidim/fingerprintable.rb
decidim-core-0.27.4 lib/decidim/fingerprintable.rb
decidim-core-0.27.3 lib/decidim/fingerprintable.rb
decidim-core-0.26.7 lib/decidim/fingerprintable.rb
decidim-core-0.26.5 lib/decidim/fingerprintable.rb
decidim-core-0.27.2 lib/decidim/fingerprintable.rb
decidim-core-0.27.1 lib/decidim/fingerprintable.rb
decidim-core-0.26.4 lib/decidim/fingerprintable.rb
decidim-core-0.27.0 lib/decidim/fingerprintable.rb
decidim-core-0.26.3 lib/decidim/fingerprintable.rb
decidim-core-0.27.0.rc2 lib/decidim/fingerprintable.rb
decidim-core-0.27.0.rc1 lib/decidim/fingerprintable.rb
decidim-core-0.26.2 lib/decidim/fingerprintable.rb