summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-04 12:07:52 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-04 12:07:52 +0000
commitc6c7437861bff9572747674095c4dfbdfbea4988 (patch)
tree237d1ed922193f19ae326923457344c082003788
parentd80f3cd75e700b6e62910865bfd36734644ffa89 (diff)
downloadgitlab-ce-c6c7437861bff9572747674095c4dfbdfbea4988.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/controllers/concerns/invisible_captcha_on_signup.rb (renamed from app/controllers/concerns/invisible_captcha.rb)2
-rw-r--r--app/controllers/projects/releases_controller.rb14
-rw-r--r--app/controllers/registrations_controller.rb2
-rw-r--r--app/graphql/mutations/issues/update.rb4
-rw-r--r--app/models/merge_request_diff_commit.rb3
-rw-r--r--app/presenters/project_hook_presenter.rb (renamed from app/presenters/hooks/project_hook_presenter.rb)0
-rw-r--r--app/presenters/service_hook_presenter.rb (renamed from app/presenters/hooks/service_hook_presenter.rb)0
-rw-r--r--app/services/post_receive_service.rb2
-rw-r--r--app/views/snippets/notes/_actions.html.haml1
-rw-r--r--changelogs/unreleased/199220-snippet-index-desc.yml5
-rw-r--r--changelogs/unreleased/27300-add-filepath-redirect-url.yml5
-rw-r--r--changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-snippets-notes.yml5
-rw-r--r--changelogs/unreleased/limit-broadcast-notifications-to-ui.yml5
-rw-r--r--changelogs/unreleased/sha-params-validator.yml5
-rw-r--r--config/routes/project.rb1
-rw-r--r--db/migrate/20200303074328_add_index_on_snippet_description.rb18
-rw-r--r--db/schema.rb3
-rw-r--r--doc/administration/audit_events.md1
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql4
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json20
-rw-r--r--doc/api/users.md7
-rw-r--r--lib/api/helpers/custom_validators.rb12
-rw-r--r--lib/api/users.rb13
-rw-r--r--lib/declarative_policy.rb2
-rw-r--r--lib/declarative_policy/preferred_scope.rb4
-rw-r--r--lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb140
-rw-r--r--lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb22
-rw-r--r--lib/gitlab/background_migration/user_mentions/models/design_management/design.rb (renamed from lib/gitlab/background_migration/user_mentions/models/design.rb)2
-rw-r--r--lib/gitlab/background_migration/user_mentions/models/epic.rb4
-rw-r--r--lib/gitlab/background_migration/user_mentions/models/note.rb2
-rw-r--r--lib/gitlab/background_migration/user_mentions/models/snippet.rb4
-rw-r--r--lib/gitlab/ci/config/entry/artifacts.rb2
-rw-r--r--lib/gitlab/ci/config/entry/bridge.rb2
-rw-r--r--lib/gitlab/ci/config/entry/cache.rb2
-rw-r--r--lib/gitlab/ci/config/entry/default.rb2
-rw-r--r--lib/gitlab/ci/config/entry/job.rb5
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb2
-rw-r--r--lib/gitlab/ci/config/entry/release.rb2
-rw-r--r--lib/gitlab/ci/config/entry/release/assets.rb2
-rw-r--r--lib/gitlab/ci/config/entry/root.rb4
-rw-r--r--lib/gitlab/ci/config/entry/service.rb34
-rw-r--r--lib/gitlab/config/entry/configurable.rb12
-rw-r--r--lib/gitlab/email.rb22
-rw-r--r--lib/gitlab/email/receiver.rb17
-rw-r--r--lib/gitlab/sidekiq_queue.rb27
-rw-r--r--lib/gitlab/utils/json_size_estimator.rb104
-rw-r--r--lib/gitlab/utils/log_limited_array.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb2
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb57
-rw-r--r--spec/factories/broadcast_messages.rb6
-rw-r--r--spec/lib/api/helpers/custom_validators_spec.rb32
-rw-r--r--spec/lib/gitlab/lograge/custom_options_spec.rb50
-rw-r--r--spec/lib/gitlab/sidekiq_queue_spec.rb9
-rw-r--r--spec/lib/gitlab/utils/json_size_estimator_spec.rb39
-rw-r--r--spec/presenters/project_hook_presenter_spec.rb (renamed from spec/presenters/hooks/project_hook_presenter_spec.rb)0
-rw-r--r--spec/presenters/service_hook_presenter_spec.rb (renamed from spec/presenters/hooks/service_hook_presenter_spec.rb)0
-rw-r--r--spec/requests/api/users_spec.rb19
-rw-r--r--spec/services/post_receive_service_spec.rb12
59 files changed, 595 insertions, 186 deletions
diff --git a/app/controllers/concerns/invisible_captcha.rb b/app/controllers/concerns/invisible_captcha_on_signup.rb
index 45c0a5c58ef..9bea6145ff3 100644
--- a/app/controllers/concerns/invisible_captcha.rb
+++ b/app/controllers/concerns/invisible_captcha_on_signup.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-module InvisibleCaptcha
+module InvisibleCaptchaOnSignup
extend ActiveSupport::Concern
included do
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb
index 7ad841d645d..d5f93c4baf6 100644
--- a/app/controllers/projects/releases_controller.rb
+++ b/app/controllers/projects/releases_controller.rb
@@ -3,7 +3,7 @@
class Projects::ReleasesController < Projects::ApplicationController
# Authorize
before_action :require_non_empty_project, except: [:index]
- before_action :release, only: %i[edit show update]
+ before_action :release, only: %i[edit show update downloads]
before_action :authorize_read_release!
before_action do
push_frontend_feature_flag(:release_issue_summary, project)
@@ -40,6 +40,10 @@ class Projects::ReleasesController < Projects::ApplicationController
end
end
+ def downloads
+ redirect_to link.url
+ end
+
protected
def releases
@@ -69,6 +73,14 @@ class Projects::ReleasesController < Projects::ApplicationController
@release ||= project.releases.find_by_tag!(sanitized_tag_name)
end
+ def link
+ release.links.find_by_filepath!(sanitized_filepath)
+ end
+
+ def sanitized_filepath
+ CGI.unescape(params[:filepath])
+ end
+
def sanitized_tag_name
CGI.unescape(params[:tag])
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 1c6cbf72cfa..855f69a0f98 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -4,7 +4,7 @@ class RegistrationsController < Devise::RegistrationsController
include Recaptcha::Verify
include AcceptsPendingInvitations
include RecaptchaExperimentHelper
- include InvisibleCaptcha
+ include InvisibleCaptchaOnSignup
layout :choose_layout
diff --git a/app/graphql/mutations/issues/update.rb b/app/graphql/mutations/issues/update.rb
index 4a21df98898..3710144fff5 100644
--- a/app/graphql/mutations/issues/update.rb
+++ b/app/graphql/mutations/issues/update.rb
@@ -17,12 +17,12 @@ module Mutations
argument :due_date,
Types::TimeType,
- required: true,
+ required: false,
description: copy_field_description(Types::IssueType, :due_date)
argument :confidential,
GraphQL::BOOLEAN_TYPE,
- required: true,
+ required: false,
description: copy_field_description(Types::IssueType, :confidential)
def resolve(project_path:, iid:, **args)
diff --git a/app/models/merge_request_diff_commit.rb b/app/models/merge_request_diff_commit.rb
index 7310aa4f580..2819ea7ce1e 100644
--- a/app/models/merge_request_diff_commit.rb
+++ b/app/models/merge_request_diff_commit.rb
@@ -10,8 +10,9 @@ class MergeRequestDiffCommit < ApplicationRecord
sha_attribute :sha
alias_attribute :id, :sha
+ # Deprecated; use `bulk_insert!` from `BulkInsertSafe` mixin instead.
+ # cf. https://gitlab.com/gitlab-org/gitlab/issues/207989 for progress
def self.create_bulk(merge_request_diff_id, commits)
- warn 'Deprecated; use `bulk_insert` from `BulkInsertSafe` mixin instead'
rows = commits.map.with_index do |commit, index|
# See #parent_ids.
commit_hash = commit.to_hash.except(:parent_ids)
diff --git a/app/presenters/hooks/project_hook_presenter.rb b/app/presenters/project_hook_presenter.rb
index a65c7221b5a..a65c7221b5a 100644
--- a/app/presenters/hooks/project_hook_presenter.rb
+++ b/app/presenters/project_hook_presenter.rb
diff --git a/app/presenters/hooks/service_hook_presenter.rb b/app/presenters/service_hook_presenter.rb
index bc20d5b1a3b..bc20d5b1a3b 100644
--- a/app/presenters/hooks/service_hook_presenter.rb
+++ b/app/presenters/service_hook_presenter.rb
diff --git a/app/services/post_receive_service.rb b/app/services/post_receive_service.rb
index e3818e76c4c..bc5ec22e77f 100644
--- a/app/services/post_receive_service.rb
+++ b/app/services/post_receive_service.rb
@@ -28,7 +28,7 @@ class PostReceiveService
response.add_alert_message(message)
end
- broadcast_message = BroadcastMessage.current&.last&.message
+ broadcast_message = BroadcastMessage.current_banner_messages&.last&.message
response.add_alert_message(broadcast_message)
response.add_merge_request_urls(merge_request_urls)
diff --git a/app/views/snippets/notes/_actions.html.haml b/app/views/snippets/notes/_actions.html.haml
index 6e20890a47f..28fbeaa25f0 100644
--- a/app/views/snippets/notes/_actions.html.haml
+++ b/app/views/snippets/notes/_actions.html.haml
@@ -2,7 +2,6 @@
- if note.emoji_awardable?
.note-actions-item
= link_to '#', title: _('Add reaction'), class: "note-action-button note-emoji-button js-add-award js-note-emoji has-tooltip", data: { position: 'right' } do
- = icon('spinner spin')
%span{ class: 'link-highlight award-control-icon-neutral' }= sprite_icon('slight-smile')
%span{ class: 'link-highlight award-control-icon-positive' }= sprite_icon('smiley')
%span{ class: 'link-highlight award-control-icon-super-positive' }= sprite_icon('smile')
diff --git a/changelogs/unreleased/199220-snippet-index-desc.yml b/changelogs/unreleased/199220-snippet-index-desc.yml
new file mode 100644
index 00000000000..c1a1063eef5
--- /dev/null
+++ b/changelogs/unreleased/199220-snippet-index-desc.yml
@@ -0,0 +1,5 @@
+---
+title: Add trigram index on snippet description
+merge_request: 26341
+author:
+type: performance
diff --git a/changelogs/unreleased/27300-add-filepath-redirect-url.yml b/changelogs/unreleased/27300-add-filepath-redirect-url.yml
new file mode 100644
index 00000000000..31645ba3050
--- /dev/null
+++ b/changelogs/unreleased/27300-add-filepath-redirect-url.yml
@@ -0,0 +1,5 @@
+---
+title: Add filepath redirect url
+merge_request: 25541
+author:
+type: added
diff --git a/changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-snippets-notes.yml b/changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-snippets-notes.yml
new file mode 100644
index 00000000000..4f28db06eab
--- /dev/null
+++ b/changelogs/unreleased/Resolve-Migrate--fa-spinner-app-views-snippets-notes.yml
@@ -0,0 +1,5 @@
+---
+title: Remove .fa-spinner from app/views/snippets/notes
+merge_request: 25036
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/limit-broadcast-notifications-to-ui.yml b/changelogs/unreleased/limit-broadcast-notifications-to-ui.yml
new file mode 100644
index 00000000000..f10b3b4fb95
--- /dev/null
+++ b/changelogs/unreleased/limit-broadcast-notifications-to-ui.yml
@@ -0,0 +1,5 @@
+---
+title: Limit notification-type broadcast display to web interface
+merge_request: 26236
+author: Aleksandrs Ļedovskis
+type: changed
diff --git a/changelogs/unreleased/sha-params-validator.yml b/changelogs/unreleased/sha-params-validator.yml
new file mode 100644
index 00000000000..ff8717bd3a1
--- /dev/null
+++ b/changelogs/unreleased/sha-params-validator.yml
@@ -0,0 +1,5 @@
+---
+title: Add grape custom validator for sha params
+merge_request: 26220
+author: Rajendra Kadam
+type: added
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 72dda11435c..809c1386f2c 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -171,6 +171,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :releases, only: [:index, :show, :edit], param: :tag, constraints: { tag: %r{[^/]+} } do
member do
get :evidence
+ get :downloads, path: 'downloads/*filepath', format: false
end
end
diff --git a/db/migrate/20200303074328_add_index_on_snippet_description.rb b/db/migrate/20200303074328_add_index_on_snippet_description.rb
new file mode 100644
index 00000000000..f23e5f8bf8e
--- /dev/null
+++ b/db/migrate/20200303074328_add_index_on_snippet_description.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexOnSnippetDescription < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_snippets_on_description_trigram'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :snippets, :description, name: INDEX_NAME, using: :gin, opclass: { description: :gin_trgm_ops }
+ end
+
+ def down
+ remove_concurrent_index_by_name :snippets, INDEX_NAME
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index cb632d983f9..32fab15182c 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2020_02_27_165129) do
+ActiveRecord::Schema.define(version: 2020_03_03_074328) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@@ -3964,6 +3964,7 @@ ActiveRecord::Schema.define(version: 2020_02_27_165129) do
t.index ["author_id"], name: "index_snippets_on_author_id"
t.index ["content"], name: "index_snippets_on_content_trigram", opclass: :gin_trgm_ops, using: :gin
t.index ["created_at"], name: "index_snippets_on_created_at"
+ t.index ["description"], name: "index_snippets_on_description_trigram", opclass: :gin_trgm_ops, using: :gin
t.index ["file_name"], name: "index_snippets_on_file_name_trigram", opclass: :gin_trgm_ops, using: :gin
t.index ["project_id", "visibility_level"], name: "index_snippets_on_project_id_and_visibility_level"
t.index ["title"], name: "index_snippets_on_title_trigram", opclass: :gin_trgm_ops, using: :gin
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index 5b3052789e4..cc8135a86c4 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -107,6 +107,7 @@ recorded:
- User was deleted ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/251) in GitLab 12.8)
- User was added ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/251) in GitLab 12.8)
- User was blocked via Admin Area ([introduced](https://gitlab.com/gitlab-org/gitlab/issues/251) in GitLab 12.8)
+- User was blocked via API ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25872) in GitLab 12.9)
It's possible to filter particular actions by choosing an audit data type from
the filter dropdown box. You can further filter by specific group, project, or user
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index eae3626515e..7dda073d8ae 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -8011,7 +8011,7 @@ input UpdateIssueInput {
"""
Indicates the issue is confidential
"""
- confidential: Boolean!
+ confidential: Boolean
"""
Description of the issue
@@ -8021,7 +8021,7 @@ input UpdateIssueInput {
"""
Due date of the issue
"""
- dueDate: Time!
+ dueDate: Time
"""
The desired health status
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index bf59c94f6cc..83b098dc73d 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -21114,13 +21114,9 @@
"name": "dueDate",
"description": "Due date of the issue",
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "Time",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "Time",
+ "ofType": null
},
"defaultValue": null
},
@@ -21128,13 +21124,9 @@
"name": "confidential",
"description": "Indicates the issue is confidential",
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "Boolean",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
},
"defaultValue": null
},
diff --git a/doc/api/users.md b/doc/api/users.md
index 49bd090f294..1eed5d08d38 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -1168,8 +1168,11 @@ Parameters:
- `id` (required) - id of specified user
-Will return `201 OK` on success, `404 User Not Found` is user cannot be found or
-`403 Forbidden` when trying to block an already blocked user by LDAP synchronization.
+Returns:
+
+- `201 OK` on success.
+- `404 User Not Found` if user cannot be found.
+- `403 Forbidden` when trying to block an already blocked user by LDAP synchronization.
## Unblock user
diff --git a/lib/api/helpers/custom_validators.rb b/lib/api/helpers/custom_validators.rb
index dab4ca1d1f1..4c15c1d01cd 100644
--- a/lib/api/helpers/custom_validators.rb
+++ b/lib/api/helpers/custom_validators.rb
@@ -14,6 +14,17 @@ module API
end
end
+ class GitSha < Grape::Validations::Base
+ def validate_param!(attr_name, params)
+ sha = params[attr_name]
+
+ return if Commit::EXACT_COMMIT_SHA_PATTERN.match?(sha)
+
+ raise Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)],
+ message: "should be a valid sha"
+ end
+ end
+
class Absence < Grape::Validations::Base
def validate_param!(attr_name, params)
return if params.respond_to?(:key?) && !params.key?(attr_name)
@@ -50,6 +61,7 @@ module API
end
Grape::Validations.register_validator(:file_path, ::API::Helpers::CustomValidators::FilePath)
+Grape::Validations.register_validator(:git_sha, ::API::Helpers::CustomValidators::GitSha)
Grape::Validations.register_validator(:absence, ::API::Helpers::CustomValidators::Absence)
Grape::Validations.register_validator(:integer_none_any, ::API::Helpers::CustomValidators::IntegerNoneAny)
Grape::Validations.register_validator(:array_none_any, ::API::Helpers::CustomValidators::ArrayNoneAny)
diff --git a/lib/api/users.rb b/lib/api/users.rb
index c6dc7c08b11..5b51f114fb4 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -528,11 +528,18 @@ module API
user = User.find_by(id: params[:id])
not_found!('User') unless user
- if !user.ldap_blocked?
- user.block
- else
+ if user.ldap_blocked?
forbidden!('LDAP blocked users cannot be modified by the API')
end
+
+ break if user.blocked?
+
+ result = ::Users::BlockService.new(current_user).execute(user)
+ if result[:status] == :success
+ true
+ else
+ render_api_error!(result[:message], result[:http_status])
+ end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/declarative_policy.rb b/lib/declarative_policy.rb
index 9e9df88373a..e51f30af581 100644
--- a/lib/declarative_policy.rb
+++ b/lib/declarative_policy.rb
@@ -13,6 +13,8 @@ require_dependency 'declarative_policy/step'
require_dependency 'declarative_policy/base'
module DeclarativePolicy
+ extend PreferredScope
+
CLASS_CACHE_MUTEX = Mutex.new
CLASS_CACHE_IVAR = :@__DeclarativePolicy_CLASS_CACHE
diff --git a/lib/declarative_policy/preferred_scope.rb b/lib/declarative_policy/preferred_scope.rb
index 9b7d1548056..d653a0ec1e1 100644
--- a/lib/declarative_policy/preferred_scope.rb
+++ b/lib/declarative_policy/preferred_scope.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module DeclarativePolicy
- PREFERRED_SCOPE_KEY = :"DeclarativePolicy.preferred_scope"
+ module PreferredScope
+ PREFERRED_SCOPE_KEY = :"DeclarativePolicy.preferred_scope"
- class << self
def with_preferred_scope(scope)
Thread.current[PREFERRED_SCOPE_KEY], old_scope = scope, Thread.current[PREFERRED_SCOPE_KEY]
yield
diff --git a/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb b/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb
index 1fac4b230ca..69ba3f9132b 100644
--- a/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb
+++ b/lib/gitlab/background_migration/user_mentions/models/concerns/isolated_mentionable.rb
@@ -4,95 +4,97 @@ module Gitlab
module BackgroundMigration
module UserMentions
module Models
- # == IsolatedMentionable concern
- #
- # Shortcutted for isolation version of Mentionable to be used in mentions migrations
- #
- module IsolatedMentionable
- extend ::ActiveSupport::Concern
-
- class_methods do
- # Indicate which attributes of the Mentionable to search for GFM references.
- def attr_mentionable(attr, options = {})
- attr = attr.to_s
- mentionable_attrs << [attr, options]
+ module Concerns
+ # == IsolatedMentionable concern
+ #
+ # Shortcutted for isolation version of Mentionable to be used in mentions migrations
+ #
+ module IsolatedMentionable
+ extend ::ActiveSupport::Concern
+
+ class_methods do
+ # Indicate which attributes of the Mentionable to search for GFM references.
+ def attr_mentionable(attr, options = {})
+ attr = attr.to_s
+ mentionable_attrs << [attr, options]
+ end
end
- end
- included do
- # Accessor for attributes marked mentionable.
- cattr_accessor :mentionable_attrs, instance_accessor: false do
- []
- end
+ included do
+ # Accessor for attributes marked mentionable.
+ cattr_accessor :mentionable_attrs, instance_accessor: false do
+ []
+ end
- if self < Participable
- participant -> (user, ext) { all_references(user, extractor: ext) }
+ if self < Participable
+ participant -> (user, ext) { all_references(user, extractor: ext) }
+ end
end
- end
- def all_references(current_user = nil, extractor: nil)
- # Use custom extractor if it's passed in the function parameters.
- if extractor
- extractors[current_user] = extractor
- else
- extractor = extractors[current_user] ||= ::Gitlab::ReferenceExtractor.new(project, current_user)
+ def all_references(current_user = nil, extractor: nil)
+ # Use custom extractor if it's passed in the function parameters.
+ if extractor
+ extractors[current_user] = extractor
+ else
+ extractor = extractors[current_user] ||= ::Gitlab::ReferenceExtractor.new(project, current_user)
- extractor.reset_memoized_values
- end
+ extractor.reset_memoized_values
+ end
- self.class.mentionable_attrs.each do |attr, options|
- text = __send__(attr) # rubocop:disable GitlabSecurity/PublicSend
- options = options.merge(
- cache_key: [self, attr],
- author: author,
- skip_project_check: skip_project_check?
- ).merge(mentionable_params)
+ self.class.mentionable_attrs.each do |attr, options|
+ text = __send__(attr) # rubocop:disable GitlabSecurity/PublicSend
+ options = options.merge(
+ cache_key: [self, attr],
+ author: author,
+ skip_project_check: skip_project_check?
+ ).merge(mentionable_params)
- cached_html = self.try(:updated_cached_html_for, attr.to_sym)
- options[:rendered] = cached_html if cached_html
+ cached_html = self.try(:updated_cached_html_for, attr.to_sym)
+ options[:rendered] = cached_html if cached_html
- extractor.analyze(text, options)
- end
+ extractor.analyze(text, options)
+ end
- extractor
- end
+ extractor
+ end
- def extractors
- @extractors ||= {}
- end
+ def extractors
+ @extractors ||= {}
+ end
- def skip_project_check?
- false
- end
+ def skip_project_check?
+ false
+ end
- def build_mention_values(resource_foreign_key)
- refs = all_references(author)
+ def build_mention_values(resource_foreign_key)
+ refs = all_references(author)
- mentioned_users_ids = array_to_sql(refs.mentioned_users.pluck(:id))
- mentioned_projects_ids = array_to_sql(refs.mentioned_projects.pluck(:id))
- mentioned_groups_ids = array_to_sql(refs.mentioned_groups.pluck(:id))
+ mentioned_users_ids = array_to_sql(refs.mentioned_users.pluck(:id))
+ mentioned_projects_ids = array_to_sql(refs.mentioned_projects.pluck(:id))
+ mentioned_groups_ids = array_to_sql(refs.mentioned_groups.pluck(:id))
- return if mentioned_users_ids.blank? && mentioned_projects_ids.blank? && mentioned_groups_ids.blank?
+ return if mentioned_users_ids.blank? && mentioned_projects_ids.blank? && mentioned_groups_ids.blank?
- {
- "#{resource_foreign_key}": user_mention_resource_id,
- note_id: user_mention_note_id,
- mentioned_users_ids: mentioned_users_ids,
- mentioned_projects_ids: mentioned_projects_ids,
- mentioned_groups_ids: mentioned_groups_ids
- }
- end
+ {
+ "#{resource_foreign_key}": user_mention_resource_id,
+ note_id: user_mention_note_id,
+ mentioned_users_ids: mentioned_users_ids,
+ mentioned_projects_ids: mentioned_projects_ids,
+ mentioned_groups_ids: mentioned_groups_ids
+ }
+ end
- def array_to_sql(ids_array)
- return unless ids_array.present?
+ def array_to_sql(ids_array)
+ return unless ids_array.present?
- '{' + ids_array.join(", ") + '}'
- end
+ '{' + ids_array.join(", ") + '}'
+ end
- private
+ private
- def mentionable_params
- {}
+ def mentionable_params
+ {}
+ end
end
end
end
diff --git a/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb b/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb
index fa479cb0ed3..efb08d44100 100644
--- a/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb
+++ b/lib/gitlab/background_migration/user_mentions/models/concerns/mentionable_migration_methods.rb
@@ -4,17 +4,19 @@ module Gitlab
module BackgroundMigration
module UserMentions
module Models
- # Extract common no_quote_columns method used in determining the columns that do not need
- # to be quoted for corresponding models
- module MentionableMigrationMethods
- extend ::ActiveSupport::Concern
+ module Concerns
+ # Extract common no_quote_columns method used in determining the columns that do not need
+ # to be quoted for corresponding models
+ module MentionableMigrationMethods
+ extend ::ActiveSupport::Concern
- class_methods do
- def no_quote_columns
- [
- :note_id,
- user_mention_model.resource_foreign_key
- ]
+ class_methods do
+ def no_quote_columns
+ [
+ :note_id,
+ user_mention_model.resource_foreign_key
+ ]
+ end
end
end
end
diff --git a/lib/gitlab/background_migration/user_mentions/models/design.rb b/lib/gitlab/background_migration/user_mentions/models/design_management/design.rb
index 66cff561bcb..0cdfc6447c7 100644
--- a/lib/gitlab/background_migration/user_mentions/models/design.rb
+++ b/lib/gitlab/background_migration/user_mentions/models/design_management/design.rb
@@ -7,7 +7,7 @@ module Gitlab
module Models
module DesignManagement
class Design < ActiveRecord::Base
- include MentionableMigrationMethods
+ include Concerns::MentionableMigrationMethods
def self.user_mention_model
Gitlab::BackgroundMigration::UserMentions::Models::DesignUserMention
diff --git a/lib/gitlab/background_migration/user_mentions/models/epic.rb b/lib/gitlab/background_migration/user_mentions/models/epic.rb
index ad1d904cde7..a76391d64bb 100644
--- a/lib/gitlab/background_migration/user_mentions/models/epic.rb
+++ b/lib/gitlab/background_migration/user_mentions/models/epic.rb
@@ -6,9 +6,9 @@ module Gitlab
module UserMentions
module Models
class Epic < ActiveRecord::Base
- include IsolatedMentionable
+ include Concerns::IsolatedMentionable
+ include Concerns::MentionableMigrationMethods
include CacheMarkdownField
- include MentionableMigrationMethods
attr_mentionable :title, pipeline: :single_line
attr_mentionable :description
diff --git a/lib/gitlab/background_migration/user_mentions/models/note.rb b/lib/gitlab/background_migration/user_mentions/models/note.rb
index dc364d7af5a..fb61de638a8 100644
--- a/lib/gitlab/background_migration/user_mentions/models/note.rb
+++ b/lib/gitlab/background_migration/user_mentions/models/note.rb
@@ -6,7 +6,7 @@ module Gitlab
module UserMentions
module Models
class Note < ActiveRecord::Base
- include IsolatedMentionable
+ include Concerns::IsolatedMentionable
include CacheMarkdownField
self.table_name = 'notes'
diff --git a/lib/gitlab/background_migration/user_mentions/models/snippet.rb b/lib/gitlab/background_migration/user_mentions/models/snippet.rb
index 1481cfcc562..cdbada76429 100644
--- a/lib/gitlab/background_migration/user_mentions/models/snippet.rb
+++ b/lib/gitlab/background_migration/user_mentions/models/snippet.rb
@@ -6,9 +6,9 @@ module Gitlab
module UserMentions
module Models
class Snippet < ActiveRecord::Base
- include IsolatedMentionable
+ include Concerns::IsolatedMentionable
+ include Concerns::MentionableMigrationMethods
include CacheMarkdownField
- include MentionableMigrationMethods
attr_mentionable :title, pipeline: :single_line
attr_mentionable :description
diff --git a/lib/gitlab/ci/config/entry/artifacts.rb b/lib/gitlab/ci/config/entry/artifacts.rb
index aebc1675bec..241c73db3bb 100644
--- a/lib/gitlab/ci/config/entry/artifacts.rb
+++ b/lib/gitlab/ci/config/entry/artifacts.rb
@@ -44,8 +44,6 @@ module Gitlab
end
end
- helpers :reports
-
def value
@config[:reports] = reports_value if @config.key?(:reports)
@config
diff --git a/lib/gitlab/ci/config/entry/bridge.rb b/lib/gitlab/ci/config/entry/bridge.rb
index 721c7c8b6d7..6fdaa373170 100644
--- a/lib/gitlab/ci/config/entry/bridge.rb
+++ b/lib/gitlab/ci/config/entry/bridge.rb
@@ -49,8 +49,6 @@ module Gitlab
description: 'Environment variables available for this job.',
inherit: false
- helpers :trigger, :needs, :variables
-
attributes :when, :allow_failure
def self.matching?(name, config)
diff --git a/lib/gitlab/ci/config/entry/cache.rb b/lib/gitlab/ci/config/entry/cache.rb
index ef07c319ce4..a304d9b724f 100644
--- a/lib/gitlab/ci/config/entry/cache.rb
+++ b/lib/gitlab/ci/config/entry/cache.rb
@@ -28,8 +28,6 @@ module Gitlab
entry :paths, Entry::Paths,
description: 'Specify which paths should be cached across builds.'
- helpers :key
-
attributes :policy
def value
diff --git a/lib/gitlab/ci/config/entry/default.rb b/lib/gitlab/ci/config/entry/default.rb
index 88db17a75da..ab493ff7d78 100644
--- a/lib/gitlab/ci/config/entry/default.rb
+++ b/lib/gitlab/ci/config/entry/default.rb
@@ -61,8 +61,6 @@ module Gitlab
description: 'Default artifacts.',
inherit: false
- helpers :before_script, :image, :services, :after_script, :cache
-
private
def overwrite_entry(deps, key, current_entry)
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 931f769e920..8db21b116eb 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -128,11 +128,6 @@ module Gitlab
description: 'This job will produce a release.',
inherit: false
- helpers :before_script, :script, :type, :after_script,
- :cache, :image, :services, :variables,
- :artifacts, :environment, :coverage, :retry,
- :needs, :interruptible, :release, :tags
-
attributes :script, :tags, :allow_failure, :when, :dependencies,
:needs, :retry, :parallel, :start_in,
:interruptible, :timeout, :resource_group, :release
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index 19e6601e31f..bfa2905ed77 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -54,8 +54,6 @@ module Gitlab
allowed_when: %w[on_success on_failure always never manual delayed].freeze
}
- helpers :stage, :only, :except, :rules
-
attributes :extends, :rules
end
diff --git a/lib/gitlab/ci/config/entry/release.rb b/lib/gitlab/ci/config/entry/release.rb
index 3eceaa0ccd9..b4e4c149730 100644
--- a/lib/gitlab/ci/config/entry/release.rb
+++ b/lib/gitlab/ci/config/entry/release.rb
@@ -33,8 +33,6 @@ module Gitlab
validates :description, type: String, presence: true
end
- helpers :assets
-
def value
@config[:assets] = assets_value if @config.key?(:assets)
@config
diff --git a/lib/gitlab/ci/config/entry/release/assets.rb b/lib/gitlab/ci/config/entry/release/assets.rb
index 82ed39f51e0..1f7057d1bf6 100644
--- a/lib/gitlab/ci/config/entry/release/assets.rb
+++ b/lib/gitlab/ci/config/entry/release/assets.rb
@@ -23,8 +23,6 @@ module Gitlab
validates :links, array_of_hashes: true, presence: true
end
- helpers :links
-
def value
@config[:links] = links_value if @config.key?(:links)
@config
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
index 620f6a95e9d..caa0725c4bd 100644
--- a/lib/gitlab/ci/config/entry/root.rb
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -67,9 +67,7 @@ module Gitlab
entry :workflow, Entry::Workflow,
description: 'List of evaluable rules to determine Pipeline status'
- helpers :default, :stages, :types, :variables, :workflow
-
- helpers :jobs, dynamic: true
+ dynamic_helpers :jobs
delegate :before_script_value,
:image_value,
diff --git a/lib/gitlab/ci/config/entry/service.rb b/lib/gitlab/ci/config/entry/service.rb
index 8d16371e857..247bf930d3b 100644
--- a/lib/gitlab/ci/config/entry/service.rb
+++ b/lib/gitlab/ci/config/entry/service.rb
@@ -7,8 +7,13 @@ module Gitlab
##
# Entry that represents a configuration of Docker service.
#
- class Service < Image
+ # TODO: remove duplication with Image superclass by defining a common
+ # Imageable concern.
+ # https://gitlab.com/gitlab-org/gitlab/issues/208774
+ class Service < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
+ include ::Gitlab::Config::Entry::Attributable
+ include ::Gitlab::Config::Entry::Configurable
ALLOWED_KEYS = %i[name entrypoint command alias ports].freeze
@@ -16,9 +21,9 @@ module Gitlab
validates :config, hash_or_string: true
validates :config, allowed_keys: ALLOWED_KEYS
validates :config, disallowed_keys: %i[ports], unless: :with_image_ports?
-
validates :name, type: String, presence: true
validates :entrypoint, array_of_strings: true, allow_nil: true
+
validates :command, array_of_strings: true, allow_nil: true
validates :alias, type: String, allow_nil: true
validates :alias, type: String, presence: true, unless: ->(record) { record.ports.blank? }
@@ -27,6 +32,8 @@ module Gitlab
entry :ports, Entry::Ports,
description: 'Ports used to expose the service'
+ attributes :ports
+
def alias
value[:alias]
end
@@ -34,6 +41,29 @@ module Gitlab
def command
value[:command]
end
+
+ def name
+ value[:name]
+ end
+
+ def entrypoint
+ value[:entrypoint]
+ end
+
+ def value
+ return { name: @config } if string?
+ return @config if hash?
+
+ {}
+ end
+
+ def with_image_ports?
+ opt(:with_image_ports)
+ end
+
+ def skip_config_hash_validation?
+ true
+ end
end
end
end
diff --git a/lib/gitlab/config/entry/configurable.rb b/lib/gitlab/config/entry/configurable.rb
index 75e15cd8cb1..3fd562c2904 100644
--- a/lib/gitlab/config/entry/configurable.rb
+++ b/lib/gitlab/config/entry/configurable.rb
@@ -75,7 +75,8 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def entry(key, entry, description: nil, default: nil, inherit: nil, reserved: nil, metadata: {})
- raise ArgumentError, "Entry #{key} already defined" if @nodes.to_h[key.to_sym]
+ entry_name = key.to_sym
+ raise ArgumentError, "Entry #{key} already defined" if @nodes.to_h[entry_name]
factory = ::Gitlab::Config::Entry::Factory.new(entry)
.with(description: description)
@@ -84,10 +85,17 @@ module Gitlab
.with(reserved: reserved)
.metadata(metadata)
- (@nodes ||= {}).merge!(key.to_sym => factory)
+ @nodes ||= {}
+ @nodes[entry_name] = factory
+
+ helpers(entry_name)
end
# rubocop: enable CodeReuse/ActiveRecord
+ def dynamic_helpers(*nodes)
+ helpers(*nodes, dynamic: true)
+ end
+
def helpers(*nodes, dynamic: false)
nodes.each do |symbol|
if method_defined?("#{symbol}_defined?") || method_defined?("#{symbol}_value")
diff --git a/lib/gitlab/email.rb b/lib/gitlab/email.rb
new file mode 100644
index 00000000000..5f935880764
--- /dev/null
+++ b/lib/gitlab/email.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Email
+ ProcessingError = Class.new(StandardError)
+ EmailUnparsableError = Class.new(ProcessingError)
+ SentNotificationNotFoundError = Class.new(ProcessingError)
+ ProjectNotFound = Class.new(ProcessingError)
+ EmptyEmailError = Class.new(ProcessingError)
+ AutoGeneratedEmailError = Class.new(ProcessingError)
+ UserNotFoundError = Class.new(ProcessingError)
+ UserBlockedError = Class.new(ProcessingError)
+ UserNotAuthorizedError = Class.new(ProcessingError)
+ NoteableNotFoundError = Class.new(ProcessingError)
+ InvalidRecordError = Class.new(ProcessingError)
+ InvalidNoteError = Class.new(InvalidRecordError)
+ InvalidIssueError = Class.new(InvalidRecordError)
+ InvalidMergeRequestError = Class.new(InvalidRecordError)
+ UnknownIncomingEmail = Class.new(ProcessingError)
+ InvalidAttachment = Class.new(ProcessingError)
+ end
+end
diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb
index b7b9288517d..bf6c28b9f90 100644
--- a/lib/gitlab/email/receiver.rb
+++ b/lib/gitlab/email/receiver.rb
@@ -5,23 +5,6 @@ require_dependency 'gitlab/email/handler'
# Inspired in great part by Discourse's Email::Receiver
module Gitlab
module Email
- ProcessingError = Class.new(StandardError)
- EmailUnparsableError = Class.new(ProcessingError)
- SentNotificationNotFoundError = Class.new(ProcessingError)
- ProjectNotFound = Class.new(ProcessingError)
- EmptyEmailError = Class.new(ProcessingError)
- AutoGeneratedEmailError = Class.new(ProcessingError)
- UserNotFoundError = Class.new(ProcessingError)
- UserBlockedError = Class.new(ProcessingError)
- UserNotAuthorizedError = Class.new(ProcessingError)
- NoteableNotFoundError = Class.new(ProcessingError)
- InvalidRecordError = Class.new(ProcessingError)
- InvalidNoteError = Class.new(InvalidRecordError)
- InvalidIssueError = Class.new(InvalidRecordError)
- InvalidMergeRequestError = Class.new(InvalidRecordError)
- UnknownIncomingEmail = Class.new(ProcessingError)
- InvalidAttachment = Class.new(ProcessingError)
-
class Receiver
def initialize(raw)
@raw = raw
diff --git a/lib/gitlab/sidekiq_queue.rb b/lib/gitlab/sidekiq_queue.rb
index 9e9ad3107f3..807c27a71ff 100644
--- a/lib/gitlab/sidekiq_queue.rb
+++ b/lib/gitlab/sidekiq_queue.rb
@@ -14,7 +14,8 @@ module Gitlab
end
def drop_jobs!(search_metadata, timeout:)
- completed = false
+ start_time = Gitlab::Metrics::System.monotonic_time
+ completed = true
deleted_jobs = 0
job_search_metadata =
@@ -27,18 +28,16 @@ module Gitlab
raise NoMetadataError if job_search_metadata.empty?
raise InvalidQueueError unless queue
- begin
- Timeout.timeout(timeout) do
- queue.each do |job|
- next unless job_matches?(job, job_search_metadata)
+ queue.each do |job|
+ if timeout_exceeded?(start_time, timeout)
+ completed = false
+ break
+ end
- job.delete
- deleted_jobs += 1
- end
+ next unless job_matches?(job, job_search_metadata)
- completed = true
- end
- rescue Timeout::Error
+ job.delete
+ deleted_jobs += 1
end
{
@@ -48,6 +47,8 @@ module Gitlab
}
end
+ private
+
def queue
strong_memoize(:queue) do
# Sidekiq::Queue.new always returns a queue, even if it doesn't
@@ -59,5 +60,9 @@ module Gitlab
def job_matches?(job, job_search_metadata)
job_search_metadata.all? { |key, value| job[key] == value }
end
+
+ def timeout_exceeded?(start_time, timeout)
+ (Gitlab::Metrics::System.monotonic_time - start_time) > timeout
+ end
end
end
diff --git a/lib/gitlab/utils/json_size_estimator.rb b/lib/gitlab/utils/json_size_estimator.rb
new file mode 100644
index 00000000000..9f8ea3e61f9
--- /dev/null
+++ b/lib/gitlab/utils/json_size_estimator.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Utils
+ # This class estimates the JSON blob byte size of a ruby object using as
+ # little allocations as possible.
+ # The estimation should be quite accurate when using simple objects.
+ #
+ # Example:
+ #
+ # Gitlab::Utils::JsonSizeEstimator.estimate(["a", { b: 12, c: nil }])
+ class JsonSizeEstimator
+ ARRAY_BRACKETS_SIZE = 2 # []
+ OBJECT_BRACKETS_SIZE = 2 # {}
+ DOUBLEQUOTE_SIZE = 2 # ""
+ COLON_SIZE = 1 # : character size from {"a": 1}
+ MINUS_SIGN_SIZE = 1 # - character size from -1
+ NULL_SIZE = 4 # null
+
+ class << self
+ # Returns: integer (number of bytes)
+ def estimate(object)
+ case object
+ when Hash
+ estimate_hash(object)
+ when Array
+ estimate_array(object)
+ when String
+ estimate_string(object)
+ when Integer
+ estimate_integer(object)
+ when Float
+ estimate_float(object)
+ when DateTime, Time
+ estimate_time(object)
+ when NilClass
+ NULL_SIZE
+ else
+ # might be incorrect, but #to_s is safe, #to_json might be disabled for some objects: User
+ estimate_string(object.to_s)
+ end
+ end
+
+ private
+
+ def estimate_hash(hash)
+ size = 0
+ item_count = 0
+
+ hash.each do |key, value|
+ item_count += 1
+
+ size += estimate(key.to_s) + COLON_SIZE + estimate(value)
+ end
+
+ size + OBJECT_BRACKETS_SIZE + comma_count(item_count)
+ end
+
+ def estimate_array(array)
+ size = 0
+ item_count = 0
+
+ array.each do |item|
+ item_count += 1
+
+ size += estimate(item)
+ end
+
+ size + ARRAY_BRACKETS_SIZE + comma_count(item_count)
+ end
+
+ def estimate_string(string)
+ string.bytesize + DOUBLEQUOTE_SIZE
+ end
+
+ def estimate_float(float)
+ float.to_s.bytesize
+ end
+
+ def estimate_integer(integer)
+ if integer > 0
+ integer_string_size(integer)
+ elsif integer < 0
+ integer_string_size(integer.abs) + MINUS_SIGN_SIZE
+ else # 0
+ 1
+ end
+ end
+
+ def estimate_time(time)
+ time.to_json.size
+ end
+
+ def integer_string_size(integer)
+ Math.log10(integer).floor + 1
+ end
+
+ def comma_count(item_count)
+ item_count == 0 ? 0 : item_count - 1
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/utils/log_limited_array.rb b/lib/gitlab/utils/log_limited_array.rb
index 9c207758580..e0589c3df4c 100644
--- a/lib/gitlab/utils/log_limited_array.rb
+++ b/lib/gitlab/utils/log_limited_array.rb
@@ -13,7 +13,7 @@ module Gitlab
total_length = 0
limited_array = array.take_while do |arg|
- total_length += arg.to_json.length
+ total_length += JsonSizeEstimator.estimate(arg)
total_length <= MAXIMUM_ARRAY_LENGTH
end
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
index 89aba112407..10dd684546f 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
@@ -3,7 +3,7 @@
module QA
context 'Release' do
describe 'Deploy key creation' do
- it 'user adds a deploy key' do
+ it 'user adds a deploy key', quarantine: 'https://gitlab.com/gitlab-org/gitlab/issues/208761' do
Flow::Login.sign_in
key = Runtime::Key::RSA.new
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
index 581e6b8299e..ca32d5a84f0 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
@@ -35,7 +35,7 @@ module QA
]
keys.each do |(key_class, bits)|
- it "user sets up a deploy key with #{key_class}(#{bits}) to clone code using pipelines" do
+ it "user sets up a deploy key with #{key_class}(#{bits}) to clone code using pipelines", quarantine: 'https://gitlab.com/gitlab-org/gitlab/issues/208761' do
key = key_class.new(*bits)
Resource::DeployKey.fabricate_via_browser_ui! do |resource|
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index a03fabad2de..58fb2a95ce6 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -198,6 +198,63 @@ describe Projects::ReleasesController do
end
end
+ context 'GET #downloads' do
+ subject do
+ get :downloads, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ tag: tag,
+ filepath: filepath
+ }
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ let(:release) { create(:release, project: project, tag: tag ) }
+ let(:tag) { 'v11.9.0-rc2' }
+ let(:db_filepath) { '/binaries/linux-amd64' }
+ let!(:link) do
+ create :release_link,
+ release: release,
+ name: 'linux-amd64 binaries',
+ filepath: db_filepath,
+ url: 'https://downloads.example.com/bin/gitlab-linux-amd64'
+ end
+
+ context 'valid filepath' do
+ let(:filepath) { CGI.escape('/binaries/linux-amd64') }
+
+ it 'redirects to the asset direct link' do
+ subject
+
+ expect(response).to redirect_to(link.url)
+ end
+ end
+
+ context 'invalid filepath' do
+ let(:filepath) { CGI.escape('/binaries/win32') }
+
+ it 'is not found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'ignores filepath extension' do
+ let(:db_filepath) { '/binaries/linux-amd64.json' }
+ let(:filepath) { CGI.escape(db_filepath) }
+
+ it 'redirects to the asset direct link' do
+ subject
+
+ expect(response).to redirect_to(link.url)
+ end
+ end
+ end
+
describe 'GET #evidence' do
let_it_be(:tag_name) { "v1.1.0-evidence" }
let!(:release) { create(:release, :with_evidence, project: project, tag: tag_name) }
diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb
index ed6e267e7c4..fa8d255ae79 100644
--- a/spec/factories/broadcast_messages.rb
+++ b/spec/factories/broadcast_messages.rb
@@ -6,6 +6,8 @@ FactoryBot.define do
starts_at { 1.day.ago }
ends_at { 1.day.from_now }
+ broadcast_type { :banner }
+
trait :expired do
starts_at { 5.days.ago }
ends_at { 3.days.ago }
@@ -15,5 +17,9 @@ FactoryBot.define do
starts_at { 5.days.from_now }
ends_at { 6.days.from_now }
end
+
+ trait :notification do
+ broadcast_type { :notification }
+ end
end
end
diff --git a/spec/lib/api/helpers/custom_validators_spec.rb b/spec/lib/api/helpers/custom_validators_spec.rb
index 10505210e65..66b86d0a055 100644
--- a/spec/lib/api/helpers/custom_validators_spec.rb
+++ b/spec/lib/api/helpers/custom_validators_spec.rb
@@ -29,6 +29,38 @@ describe API::Helpers::CustomValidators do
end
end
+ describe API::Helpers::CustomValidators::GitSha do
+ let(:sha) { RepoHelpers.sample_commit.id }
+ let(:short_sha) { sha[0, Gitlab::Git::Commit::MIN_SHA_LENGTH] }
+ let(:too_short_sha) { sha[0, Gitlab::Git::Commit::MIN_SHA_LENGTH - 1] }
+
+ subject do
+ described_class.new(['test'], {}, false, scope.new)
+ end
+
+ context 'valid sha' do
+ it 'does not raise a validation error' do
+ expect_no_validation_error('test' => sha)
+ expect_no_validation_error('test' => short_sha)
+ end
+ end
+
+ context 'empty params' do
+ it 'raises a validation error' do
+ expect_validation_error('test' => nil)
+ expect_validation_error('test' => '')
+ end
+ end
+
+ context 'invalid sha' do
+ it 'raises a validation error' do
+ expect_validation_error('test' => "#{sha}2") # Sha length > 40
+ expect_validation_error('test' => 'somestring')
+ expect_validation_error('test' => too_short_sha) # sha length < MIN_SHA_LENGTH (7)
+ end
+ end
+ end
+
describe API::Helpers::CustomValidators::FilePath do
subject do
described_class.new(['test'], {}, false, scope.new)
diff --git a/spec/lib/gitlab/lograge/custom_options_spec.rb b/spec/lib/gitlab/lograge/custom_options_spec.rb
new file mode 100644
index 00000000000..48d06283b7a
--- /dev/null
+++ b/spec/lib/gitlab/lograge/custom_options_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Lograge::CustomOptions do
+ describe '.call' do
+ let(:params) do
+ {
+ 'controller' => 'ApplicationController',
+ 'action' => 'show',
+ 'format' => 'html',
+ 'a' => 'b'
+ }
+ end
+
+ let(:event) do
+ ActiveSupport::Notifications::Event.new(
+ 'test',
+ 1,
+ 2,
+ 'transaction_id',
+ { params: params, user_id: 'test' }
+ )
+ end
+
+ subject { described_class.call(event) }
+
+ it 'ignores some parameters' do
+ param_keys = subject[:params].map { |param| param[:key] }
+
+ expect(param_keys).not_to include(*described_class::IGNORE_PARAMS)
+ end
+
+ it 'formats the parameters' do
+ expect(subject[:params]).to eq([{ key: 'a', value: 'b' }])
+ end
+
+ it 'adds the current time' do
+ travel_to(5.days.ago) do
+ expected_time = Time.now.utc.iso8601(3)
+
+ expect(subject[:time]).to eq(expected_time)
+ end
+ end
+
+ it 'adds the user id' do
+ expect(subject[:user_id]).to eq('test')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_queue_spec.rb b/spec/lib/gitlab/sidekiq_queue_spec.rb
index 7a4d47563b6..9516ea10511 100644
--- a/spec/lib/gitlab/sidekiq_queue_spec.rb
+++ b/spec/lib/gitlab/sidekiq_queue_spec.rb
@@ -31,14 +31,7 @@ describe Gitlab::SidekiqQueue do
context 'when the queue is not processed in time' do
before do
- calls = 0
-
- allow(sidekiq_queue).to receive(:job_matches?).and_wrap_original do |m, *args|
- raise Timeout::Error if calls > 0
-
- calls += 1
- m.call(*args)
- end
+ allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(1, 2, 12)
end
it 'returns a non-completion flag, the number of jobs deleted, and the remaining queue size' do
diff --git a/spec/lib/gitlab/utils/json_size_estimator_spec.rb b/spec/lib/gitlab/utils/json_size_estimator_spec.rb
new file mode 100644
index 00000000000..ae24e25558a
--- /dev/null
+++ b/spec/lib/gitlab/utils/json_size_estimator_spec.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Utils::JsonSizeEstimator do
+ RSpec::Matchers.define :match_json_bytesize_of do |expected|
+ match do |actual|
+ actual == expected.to_json.bytesize
+ end
+ end
+
+ def estimate(object)
+ described_class.estimate(object)
+ end
+
+ [
+ [],
+ [[[[]]]],
+ [1, "str", 3.14, ["str", { a: -1 }]],
+ {},
+ { a: {} },
+ { a: { b: { c: [1, 2, 3], e: Time.now, f: nil } } },
+ { 100 => 500 },
+ { '狸' => '狸' },
+ nil
+ ].each do |example|
+ it { expect(estimate(example)).to match_json_bytesize_of(example) }
+ end
+
+ it 'calls #to_s on unknown object' do
+ klass = Class.new do
+ def to_s
+ 'hello'
+ end
+ end
+
+ expect(estimate(klass.new)).to match_json_bytesize_of(klass.new.to_s) # "hello"
+ end
+end
diff --git a/spec/presenters/hooks/project_hook_presenter_spec.rb b/spec/presenters/project_hook_presenter_spec.rb
index 773e8ccf51e..773e8ccf51e 100644
--- a/spec/presenters/hooks/project_hook_presenter_spec.rb
+++ b/spec/presenters/project_hook_presenter_spec.rb
diff --git a/spec/presenters/hooks/service_hook_presenter_spec.rb b/spec/presenters/service_hook_presenter_spec.rb
index bea57768e3e..bea57768e3e 100644
--- a/spec/presenters/hooks/service_hook_presenter_spec.rb
+++ b/spec/presenters/service_hook_presenter_spec.rb
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 8b9d0391b79..4a89069cbec 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -2165,14 +2165,20 @@ describe API::Users, :do_not_mock_admin_mode do
end
describe 'POST /users/:id/block' do
+ let(:blocked_user) { create(:user, state: 'blocked') }
+
before do
admin
end
it 'blocks existing user' do
post api("/users/#{user.id}/block", admin)
- expect(response).to have_gitlab_http_status(:created)
- expect(user.reload.state).to eq('blocked')
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response.body).to eq('true')
+ expect(user.reload.state).to eq('blocked')
+ end
end
it 'does not re-block ldap blocked users' do
@@ -2192,6 +2198,15 @@ describe API::Users, :do_not_mock_admin_mode do
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('404 User Not Found')
end
+
+ it 'returns a 201 if user is already blocked' do
+ post api("/users/#{blocked_user.id}/block", admin)
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:created)
+ expect(response.body).to eq('null')
+ end
+ end
end
describe 'POST /users/:id/unblock' do
diff --git a/spec/services/post_receive_service_spec.rb b/spec/services/post_receive_service_spec.rb
index 9b9200fd33e..64b4a1125e8 100644
--- a/spec/services/post_receive_service_spec.rb
+++ b/spec/services/post_receive_service_spec.rb
@@ -130,14 +130,22 @@ describe PostReceiveService do
end
end
- context 'broadcast message exists' do
+ context 'broadcast message banner exists' do
it 'outputs a broadcast message' do
- broadcast_message = create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now)
+ broadcast_message = create(:broadcast_message)
expect(subject).to include(build_alert_message(broadcast_message.message))
end
end
+ context 'broadcast message notification exists' do
+ it 'does not output a broadcast message' do
+ create(:broadcast_message, :notification)
+
+ expect(has_alert_messages?(subject)).to be_falsey
+ end
+ end
+
context 'broadcast message does not exist' do
it 'does not output a broadcast message' do
expect(has_alert_messages?(subject)).to be_falsey