1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- # frozen_string_literal: true
- # == Schema Information
- #
- # Table name: webhooks
- #
- # id :bigint(8) not null, primary key
- # url :string not null
- # events :string default([]), not null, is an Array
- # secret :string default(""), not null
- # enabled :boolean default(TRUE), not null
- # created_at :datetime not null
- # updated_at :datetime not null
- # template :text
- #
- class Webhook < ApplicationRecord
- EVENTS = %w(
- account.approved
- account.created
- account.updated
- report.created
- report.updated
- status.created
- status.updated
- ).freeze
- attr_writer :current_account
- scope :enabled, -> { where(enabled: true) }
- validates :url, presence: true, url: true
- validates :secret, presence: true, length: { minimum: 12 }
- validates :events, presence: true
- validate :events_validation_error, if: :invalid_events?
- validate :validate_permissions
- validate :validate_template
- normalizes :events, with: ->(events) { events.filter_map { |event| event.strip.presence } }
- before_validation :generate_secret
- def rotate_secret!
- update!(secret: SecureRandom.hex(20))
- end
- def enable!
- update!(enabled: true)
- end
- def disable!
- update!(enabled: false)
- end
- def required_permissions
- events.map { |event| Webhook.permission_for_event(event) }
- end
- def self.permission_for_event(event)
- case event
- when 'account.approved', 'account.created', 'account.updated'
- :manage_users
- when 'report.created', 'report.updated'
- :manage_reports
- when 'status.created', 'status.updated'
- :view_devops
- end
- end
- private
- def events_validation_error
- errors.add(:events, :invalid)
- end
- def invalid_events?
- events.blank? || events.difference(EVENTS).any?
- end
- def validate_permissions
- errors.add(:events, :invalid_permissions) if defined?(@current_account) && required_permissions.any? { |permission| !@current_account.user_role.can?(permission) }
- end
- def validate_template
- return if template.blank?
- begin
- parser = Webhooks::PayloadRenderer::TemplateParser.new
- parser.parse(template)
- rescue Parslet::ParseFailed
- errors.add(:template, :invalid)
- end
- end
- def generate_secret
- self.secret = SecureRandom.hex(20) if secret.blank?
- end
- end
|