File: extensions_gallery_metadata_validator.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (87 lines) | stat: -rw-r--r-- 2,671 bytes parent folder | download
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# frozen_string_literal: true

module WebIde
  module Settings
    class ExtensionsGalleryMetadataValidator
      include Messages

      # @param [Hash] context
      # @return [Gitlab::Fp::Result]
      def self.validate(context)
        unless context.fetch(:requested_setting_names).include?(:vscode_extensions_gallery_metadata)
          return Gitlab::Fp::Result.ok(context)
        end

        context => { settings: Hash => settings }
        settings => { vscode_extensions_gallery_metadata: Hash => extensions_gallery_metadata }

        validatable_hash = make_hash_validatable_by_json_schemer(extensions_gallery_metadata)
        errors = validate_against_schema(validatable_hash)

        if errors.none?
          Gitlab::Fp::Result.ok(context)
        else
          Gitlab::Fp::Result.err(
            SettingsVscodeExtensionsGalleryMetadataValidationFailed.new(details: errors.join(". "))
          )
        end
      end

      # @param [Hash] hash
      # @return [Hash]
      def self.make_hash_validatable_by_json_schemer(hash)
        hash
          .deep_stringify_keys
          .transform_values { |v| v.is_a?(Symbol) ? v.to_s : v }
      end

      # @param [Hash] hash_to_validate
      # @return [Array]
      def self.validate_against_schema(hash_to_validate)
        schema = {
          "properties" => {
            "enabled" => {
              "type" => "boolean"
            }
          },
          # do conditional check that "enabled" is boolean type
          "if" => {
            "properties" => {
              "enabled" => {
                "type" => "boolean"
              }
            }
          },
          "then" => {
            # "enabled" is boolean, do conditional check for "enabled" value
            "if" => {
              "properties" => {
                "enabled" => {
                  "const" => true
                }
              }
            },
            "then" => {
              # "enabled" is true, "disabled_reason" is not required
              "required" => %w[enabled]
            },
            "else" => {
              # "enabled" is false, "disabled_reason" is required
              "required" => %w[enabled disabled_reason],
              "properties" => {
                "disabled_reason" => {
                  "type" => "string"
                }
              }
            }
          }
        }

        schemer = JSONSchemer.schema(schema)
        errors = schemer.validate(hash_to_validate)
        errors.map { |error| JSONSchemer::Errors.pretty(error) }
      end
      private_class_method :make_hash_validatable_by_json_schemer, :validate_against_schema
    end
  end
end