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

definition.rb « type « audit « gitlab « lib - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: af5dc9f4b44e66aa9e5675306fcf8f1b228a8ac0 (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
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# frozen_string_literal: true

module Gitlab
  module Audit
    module Type
      class Definition
        include ActiveModel::Validations

        attr_reader :path
        attr_reader :attributes

        validate :validate_schema
        validate :validate_file_name

        InvalidAuditEventTypeError = Class.new(StandardError)

        AUDIT_EVENT_TYPE_SCHEMA_PATH = Rails.root.join('config', 'audit_events', 'types', 'type_schema.json')
        AUDIT_EVENT_TYPE_SCHEMA = JSONSchemer.schema(AUDIT_EVENT_TYPE_SCHEMA_PATH)

        # The PARAMS in config/audit_events/types/type_schema.json
        PARAMS = %i[
          name
          description
          introduced_by_issue
          introduced_by_mr
          group
          milestone
          saved_to_database
          streamed
        ].freeze

        PARAMS.each do |param|
          define_method(param) do
            attributes[param]
          end
        end

        def initialize(path, opts = {})
          @path = path
          @attributes = {}

          # assign nil, for all unknown opts
          PARAMS.each do |param|
            @attributes[param] = opts[param]
          end
        end

        def key
          name.to_sym
        end

        private

        def validate_schema
          schema_errors = AUDIT_EVENT_TYPE_SCHEMA
                            .validate(attributes.to_h.deep_stringify_keys)
                            .map { |error| JSONSchemer::Errors.pretty(error) }

          errors.add(:base, schema_errors) if schema_errors.present?
        end

        def validate_file_name
          # ignoring Style/GuardClause because if we move this into one line, we cause Layout/LineLength errors
          # rubocop:disable Style/GuardClause
          unless File.basename(path, ".yml") == name
            errors.add(:base, "Audit event type '#{name}' has an invalid path: '#{path}'. " \
              "'#{name}' must match the filename")
          end
          # rubocop:enable Style/GuardClause
        end

        class << self
          def paths
            @paths ||= [Rails.root.join('config', 'audit_events', 'types', '*.yml')]
          end

          def definitions
            # We lazily load all definitions
            @definitions ||= load_all!
          end

          def get(key)
            definitions[key.to_sym]
          end

          private

          def load_all!
            paths.each_with_object({}) do |glob_path, definitions|
              load_all_from_path!(definitions, glob_path)
            end
          end

          def load_all_from_path!(definitions, glob_path)
            Dir.glob(glob_path).each do |path|
              definition = load_from_file(path)

              if previous = definitions[definition.key]
                raise InvalidAuditEventTypeError, "Audit event type '#{definition.key}' " \
                  "is already defined in '#{previous.path}'"
              end

              definitions[definition.key] = definition
            end
          end

          def load_from_file(path)
            definition = File.read(path)
            definition = YAML.safe_load(definition)
            definition.deep_symbolize_keys!

            new(path, definition).tap(&:validate!)
          rescue StandardError => e
            raise InvalidAuditEventTypeError, "Invalid definition for `#{path}`: #{e.message}"
          end
        end
      end
    end
  end
end

Gitlab::Audit::Type::Definition.prepend_mod