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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/hooks')
-rw-r--r--app/models/hooks/project_hook.rb15
-rw-r--r--app/models/hooks/system_hook.rb2
-rw-r--r--app/models/hooks/web_hook.rb39
3 files changed, 55 insertions, 1 deletions
diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb
index b7ace34141e..bcbf43ee38b 100644
--- a/app/models/hooks/project_hook.rb
+++ b/app/models/hooks/project_hook.rb
@@ -27,6 +27,8 @@ class ProjectHook < WebHook
belongs_to :project
validates :project, presence: true
+ scope :for_projects, ->(project) { where(project: project) }
+
def pluralized_name
_('Webhooks')
end
@@ -41,6 +43,19 @@ class ProjectHook < WebHook
project
end
+ override :update_last_failure
+ def update_last_failure
+ return if executable?
+
+ key = "web_hooks:last_failure:project-#{project_id}"
+ time = Time.current.utc.iso8601
+
+ Gitlab::Redis::SharedState.with do |redis|
+ prev = redis.get(key)
+ redis.set(key, time) if !prev || prev < time
+ end
+ end
+
private
override :web_hooks_disable_failed?
diff --git a/app/models/hooks/system_hook.rb b/app/models/hooks/system_hook.rb
index c8a0cc05912..c0073f9a9b8 100644
--- a/app/models/hooks/system_hook.rb
+++ b/app/models/hooks/system_hook.rb
@@ -26,6 +26,6 @@ class SystemHook < WebHook
end
def help_path
- 'system_hooks/system_hooks'
+ 'administration/system_hooks'
end
end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 37fd612e652..f428d07cd7f 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -3,6 +3,8 @@
class WebHook < ApplicationRecord
include Sortable
+ InterpolationError = Class.new(StandardError)
+
MAX_FAILURES = 100
FAILURE_THRESHOLD = 3 # three strikes
INITIAL_BACKOFF = 10.minutes
@@ -36,6 +38,7 @@ class WebHook < ApplicationRecord
validates :token, format: { without: /\n/ }
validates :push_events_branch_filter, branch_filter: true
validates :url_variables, json_schema: { filename: 'web_hooks_url_variables' }
+ validate :no_missing_url_variables
after_initialize :initialize_url_variables
@@ -45,6 +48,11 @@ class WebHook < ApplicationRecord
where('recent_failures <= ? AND (disabled_until IS NULL OR disabled_until < ?)', FAILURE_THRESHOLD, Time.current)
end
+ # Inverse of executable
+ scope :disabled, -> do
+ where('recent_failures > ? OR disabled_until >= ?', FAILURE_THRESHOLD, Time.current)
+ end
+
def executable?
!temporarily_disabled? && !permanently_disabled?
end
@@ -164,6 +172,24 @@ class WebHook < ApplicationRecord
super(options)
end
+ # See app/validators/json_schemas/web_hooks_url_variables.json
+ VARIABLE_REFERENCE_RE = /\{([A-Za-z_][A-Za-z0-9_]+)\}/.freeze
+
+ def interpolated_url
+ return url unless url.include?('{')
+
+ vars = url_variables
+ url.gsub(VARIABLE_REFERENCE_RE) do
+ vars.fetch(_1.delete_prefix('{').delete_suffix('}'))
+ end
+ rescue KeyError => e
+ raise InterpolationError, "Invalid URL template. Missing key #{e.key}"
+ end
+
+ def update_last_failure
+ # Overridden in child classes.
+ end
+
private
def web_hooks_disable_failed?
@@ -177,4 +203,17 @@ class WebHook < ApplicationRecord
def rate_limiter
@rate_limiter ||= Gitlab::WebHooks::RateLimiter.new(self)
end
+
+ def no_missing_url_variables
+ return if url.nil?
+
+ variable_names = url_variables.keys
+ used_variables = url.scan(VARIABLE_REFERENCE_RE).map(&:first)
+
+ missing = used_variables - variable_names
+
+ return if missing.empty?
+
+ errors.add(:url, "Invalid URL template. Missing keys: #{missing}")
+ end
end