Welcome to mirror list, hosted at ThFree Co, Russian Federation.

json_schema_validator.rb « validators « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2ef011df73edc286c2761d02236f147a2e256e66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# frozen_string_literal: true
#
# JsonSchemaValidator
#
# Custom validator for json schema.
# Create a json schema within the json_schemas directory
#
#   class Project < ActiveRecord::Base
#     validates :data, json_schema: { filename: "file" }
#   end
#
class JsonSchemaValidator < ActiveModel::EachValidator
  FILENAME_ALLOWED = /\A[a-z0-9_-]*\Z/
  FilenameError = Class.new(StandardError)
  BASE_DIRECTORY = %w[app validators json_schemas].freeze

  def initialize(options)
    raise ArgumentError, "Expected 'filename' as an argument" unless options[:filename]
    raise FilenameError, "Must be a valid 'filename'" unless options[:filename].match?(FILENAME_ALLOWED)

    @base_directory = options.delete(:base_directory) || BASE_DIRECTORY

    super(options)
  end

  def validate_each(record, attribute, value)
    value = value.to_h.stringify_keys if options[:hash_conversion] == true
    value = Gitlab::Json.parse(value.to_s) if options[:parse_json] == true && !value.nil?

    unless valid_schema?(value)
      record.errors.add(attribute, _("must be a valid json schema"))
    end
  end

  private

  attr_reader :base_directory

  def valid_schema?(value)
    validator.valid?(value)
  end

  def validator
    @validator ||= JSONSchemer.schema(Pathname.new(schema_path))
  end

  def schema_path
    @schema_path ||= Rails.root.join(*base_directory, filename_with_extension).to_s
  end

  def filename_with_extension
    "#{options[:filename]}.json"
  end

  def draft_version
    options[:draft] || JSON_VALIDATOR_MAX_DRAFT_VERSION
  end
end

JsonSchemaValidator.prepend_mod