debian-mirror-gitlab/app/validators/json_schema_validator.rb

60 lines
1.5 KiB
Ruby
Raw Normal View History

2020-06-23 00:09:42 +05:30
# 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/.freeze
FilenameError = Class.new(StandardError)
2021-04-29 21:17:54 +05:30
BASE_DIRECTORY = %w(app validators json_schemas).freeze
2020-06-23 00:09:42 +05:30
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)
2021-04-29 21:17:54 +05:30
@base_directory = options.delete(:base_directory) || BASE_DIRECTORY
2020-06-23 00:09:42 +05:30
super(options)
end
def validate_each(record, attribute, value)
2021-12-07 22:27:20 +05:30
value = value.to_h.stringify_keys if options[:hash_conversion] == true
2020-06-23 00:09:42 +05:30
unless valid_schema?(value)
2021-12-07 22:27:20 +05:30
record.errors.add(attribute, _("must be a valid json schema"))
2020-06-23 00:09:42 +05:30
end
end
private
2021-04-29 21:17:54 +05:30
attr_reader :base_directory
2020-06-23 00:09:42 +05:30
def valid_schema?(value)
2021-04-29 21:17:54 +05:30
validator.valid?(value)
end
def validator
@validator ||= JSONSchemer.schema(Pathname.new(schema_path))
2020-06-23 00:09:42 +05:30
end
def schema_path
2021-04-29 21:17:54 +05:30
@schema_path ||= Rails.root.join(*base_directory, filename_with_extension).to_s
end
def filename_with_extension
"#{options[:filename]}.json"
2020-06-23 00:09:42 +05:30
end
2021-02-22 17:27:13 +05:30
def draft_version
options[:draft] || JSON_VALIDATOR_MAX_DRAFT_VERSION
end
2020-06-23 00:09:42 +05:30
end
2021-04-29 21:17:54 +05:30
2021-06-08 01:23:25 +05:30
JsonSchemaValidator.prepend_mod