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
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-26 17:39:41 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-26 17:39:41 +0300
commit93fd80667dcfbacca2b41168da6fcb3f67c0899b (patch)
tree17d0bd9c303b7a0dbed87811e438d10fee49991f /lib
parentf332982c82ad95ae2ee22242c39f78717613165f (diff)
Add latest changes from gitlab-org/security/gitlab@15-3-stable-ee
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/set_cache.rb4
-rw-r--r--lib/gitlab/zentao/client.rb50
2 files changed, 47 insertions, 7 deletions
diff --git a/lib/gitlab/set_cache.rb b/lib/gitlab/set_cache.rb
index feb2c3c1d7d..896e7e3f65e 100644
--- a/lib/gitlab/set_cache.rb
+++ b/lib/gitlab/set_cache.rb
@@ -68,6 +68,10 @@ module Gitlab
with { |redis| redis.ttl(cache_key(key)) }
end
+ def count(key)
+ with { |redis| redis.scard(cache_key(key)) }
+ end
+
private
def with(&blk)
diff --git a/lib/gitlab/zentao/client.rb b/lib/gitlab/zentao/client.rb
index 0c2b3049670..a9e89b99a27 100644
--- a/lib/gitlab/zentao/client.rb
+++ b/lib/gitlab/zentao/client.rb
@@ -5,6 +5,10 @@ module Gitlab
class Client
Error = Class.new(StandardError)
ConfigError = Class.new(Error)
+ RequestError = Class.new(Error)
+
+ CACHE_MAX_SET_SIZE = 5_000
+ CACHE_TTL = 1.month.freeze
attr_reader :integration
@@ -33,11 +37,21 @@ module Gitlab
end
def fetch_issues(params = {})
- get("products/#{zentao_product_xid}/issues", params)
+ get("products/#{zentao_product_xid}/issues", params).tap do |response|
+ mark_issues_as_seen_in_product(response['issues'])
+ end
end
def fetch_issue(issue_id)
- raise Gitlab::Zentao::Client::Error, 'invalid issue id' unless issue_id_pattern.match(issue_id)
+ raise Error, 'invalid issue id' unless issue_id_pattern.match(issue_id)
+
+ # Only return issues that are associated with the product configured in
+ # the integration. Due to a lack of available data in the ZenTao APIs, we
+ # can only determine if an issue belongs to a product if the issue was
+ # previously returned in the `#fetch_issues` call.
+ #
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/360372#note_1016963713
+ raise RequestError unless issue_seen_in_product?(issue_id)
get("issues/#{issue_id}")
end
@@ -52,17 +66,15 @@ module Gitlab
options = { headers: headers, query: params }
response = Gitlab::HTTP.get(url(path), options)
- raise Gitlab::Zentao::Client::Error, 'request error' unless response.success?
+ raise RequestError unless response.success?
Gitlab::Json.parse(response.body)
rescue JSON::ParserError
- raise Gitlab::Zentao::Client::Error, 'invalid response format'
+ raise Error, 'invalid response format'
end
def url(path)
- host = integration.api_url.presence || integration.url
-
- URI.parse(Gitlab::Utils.append_path(host, "api.php/v1/#{path}"))
+ URI.parse(Gitlab::Utils.append_path(integration.client_url, "api.php/v1/#{path}"))
end
def headers
@@ -75,6 +87,30 @@ module Gitlab
def zentao_product_xid
integration.zentao_product_xid
end
+
+ def issue_ids_cache_key
+ @issue_ids_cache_key ||= [
+ :zentao_product_issues,
+ OpenSSL::Digest::SHA256.hexdigest(integration.client_url),
+ zentao_product_xid
+ ].join(':')
+ end
+
+ def issue_ids_cache
+ @issue_ids_cache ||= ::Gitlab::SetCache.new(expires_in: CACHE_TTL)
+ end
+
+ def mark_issues_as_seen_in_product(issues)
+ return unless issues && issue_ids_cache.count(issue_ids_cache_key) < CACHE_MAX_SET_SIZE
+
+ ids = issues.map { _1['id'] }
+
+ issue_ids_cache.write(issue_ids_cache_key, ids)
+ end
+
+ def issue_seen_in_product?(id)
+ issue_ids_cache.include?(issue_ids_cache_key, id)
+ end
end
end
end