From f53112de5931144ac74819f87c227f06e115ba58 Mon Sep 17 00:00:00 2001 From: Ash McKenzie Date: Thu, 18 Jul 2019 12:09:30 +1000 Subject: New GroupMember.of_ldap_type scope --- app/models/members/group_member.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb index 4cba69069bb..341d2fe2149 100644 --- a/app/models/members/group_member.rb +++ b/app/models/members/group_member.rb @@ -13,8 +13,8 @@ class GroupMember < Member default_scope { where(source_type: SOURCE_TYPE) } scope :of_groups, ->(groups) { where(source_id: groups.select(:id)) } - scope :count_users_by_group_id, -> { joins(:user).group(:source_id).count } + scope :of_ldap_type, -> { where(ldap: true) } after_create :update_two_factor_requirement, unless: :invite? after_destroy :update_two_factor_requirement, unless: :invite? -- cgit v1.2.1 From dfcf4cf5f1e87a29f0d9fcc5ff2bba47258893bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C5=82gorzata=20Ksionek?= Date: Thu, 18 Jul 2019 10:27:02 +0200 Subject: Add captcha if there are multiple failed login attempts Add method to store session ids by ip Add new specs for storing session ids Add cleaning up records after login Add retrieving anonymous sessions Add login recaptcha setting Add new setting to sessions controller Add conditions for showing captcha Add sessions controller specs Add admin settings specs for login protection Add new settings to api Add stub to devise spec Add new translation key Add cr remarks Rename class call Add cr remarks Change if-clause for consistency Add cr remarks Add code review remarks Refactor AnonymousSession class Add changelog entry Move AnonymousSession class to lib Move store unauthenticated sessions to sessions controller Move link to recaptcha info Regenerate text file Improve copy on the spam page Change action filter for storing anonymous sessions Fix rubocop offences Add code review remarks --- app/models/application_setting.rb | 8 ++++++-- app/models/application_setting_implementation.rb | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index a769a8f07fd..16e35c1be67 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -73,11 +73,11 @@ class ApplicationSetting < ApplicationRecord validates :recaptcha_site_key, presence: true, - if: :recaptcha_enabled + if: :recaptcha_or_login_protection_enabled validates :recaptcha_private_key, presence: true, - if: :recaptcha_enabled + if: :recaptcha_or_login_protection_enabled validates :akismet_api_key, presence: true, @@ -285,4 +285,8 @@ class ApplicationSetting < ApplicationRecord def self.cache_backend Gitlab::ThreadMemoryCache.cache_backend end + + def recaptcha_or_login_protection_enabled + recaptcha_enabled || login_recaptcha_protection_enabled + end end diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index 1e612bd0e78..b8e6156d231 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -63,6 +63,7 @@ module ApplicationSettingImplementation polling_interval_multiplier: 1, project_export_enabled: true, recaptcha_enabled: false, + login_recaptcha_protection_enabled: false, repository_checks_enabled: true, repository_storages: ['default'], require_two_factor_authentication: false, -- cgit v1.2.1 From 927f608f2c4905e430d2df1c455cec793ef41aa9 Mon Sep 17 00:00:00 2001 From: Patrick Derichs Date: Mon, 15 Jul 2019 13:29:56 +0200 Subject: Fix HTML injection for label description Add changelog entry Add spec --- app/models/label.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/label.rb b/app/models/label.rb index 25de26b8384..19f684c32af 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -197,7 +197,11 @@ class Label < ApplicationRecord end def title=(value) - write_attribute(:title, sanitize_title(value)) if value.present? + write_attribute(:title, sanitize_value(value)) if value.present? + end + + def description=(value) + write_attribute(:description, sanitize_value(value)) if value.present? end ## @@ -258,7 +262,7 @@ class Label < ApplicationRecord end end - def sanitize_title(value) + def sanitize_value(value) CGI.unescapeHTML(Sanitize.clean(value.to_s)) end -- cgit v1.2.1 From 492a7e753d0ef06458163aecc5ca43892a5acc73 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Tue, 16 Jul 2019 16:49:47 -0300 Subject: Fix DNS rebind vulnerability for JIRA integration Uses Gitlab::HTTP for JIRA requests instead of Net::Http. Gitlab::Http comes with some built in SSRF protections. --- app/models/project_services/jira_service.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index d08fcd8954d..0728c83005e 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -64,7 +64,12 @@ class JiraService < IssueTrackerService end def client - @client ||= JIRA::Client.new(options) + @client ||= begin + JIRA::Client.new(options).tap do |client| + # Replaces JIRA default http client with our implementation + client.request_client = Gitlab::Jira::HttpClient.new(client.options) + end + end end def help -- cgit v1.2.1 From 139df74253214fbab6aa703ed8ce381d0871aa46 Mon Sep 17 00:00:00 2001 From: Igor Drozdov Date: Mon, 12 Aug 2019 15:07:15 +0300 Subject: Add merge note type as cross reference --- app/models/system_note_metadata.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/system_note_metadata.rb b/app/models/system_note_metadata.rb index 9a2640db9ca..a19755d286a 100644 --- a/app/models/system_note_metadata.rb +++ b/app/models/system_note_metadata.rb @@ -9,7 +9,7 @@ class SystemNoteMetadata < ApplicationRecord TYPES_WITH_CROSS_REFERENCES = %w[ commit cross_reference close duplicate - moved + moved merge ].freeze ICON_TYPES = %w[ -- cgit v1.2.1 From 0eff75fa2b6691b6fba31fcc2842f51debd249a9 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 8 Jul 2019 17:11:59 +0100 Subject: Cache branch and tag names as Redis sets This allows us to check inclusion for the *_exists? methods without downloading the full list of branch names, which is over 100KiB in size for gitlab-ce at the moment. --- app/models/repository.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'app/models') diff --git a/app/models/repository.rb b/app/models/repository.rb index 9d45a12fa6e..561c6579086 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -239,13 +239,13 @@ class Repository def branch_exists?(branch_name) return false unless raw_repository - branch_names.include?(branch_name) + branch_names_include?(branch_name) end def tag_exists?(tag_name) return false unless raw_repository - tag_names.include?(tag_name) + tag_names_include?(tag_name) end def ref_exists?(ref) @@ -561,10 +561,10 @@ class Repository end delegate :branch_names, to: :raw_repository - cache_method :branch_names, fallback: [] + cache_method_as_redis_set :branch_names, fallback: [] delegate :tag_names, to: :raw_repository - cache_method :tag_names, fallback: [] + cache_method_as_redis_set :tag_names, fallback: [] delegate :branch_count, :tag_count, :has_visible_content?, to: :raw_repository cache_method :branch_count, fallback: 0 @@ -1126,6 +1126,10 @@ class Repository @cache ||= Gitlab::RepositoryCache.new(self) end + def redis_set_cache + @redis_set_cache ||= Gitlab::RepositorySetCache.new(self) + end + def request_store_cache @request_store_cache ||= Gitlab::RepositoryCache.new(self, backend: Gitlab::SafeRequestStore) end -- cgit v1.2.1 From 2067f677df69200338d8d2b78f239759fc293fee Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Mon, 19 Aug 2019 17:33:07 -0300 Subject: Fix N+1s queries while loading users --- app/models/users_star_project.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/models') diff --git a/app/models/users_star_project.rb b/app/models/users_star_project.rb index 3c7a805cc5c..c633e2d8b3d 100644 --- a/app/models/users_star_project.rb +++ b/app/models/users_star_project.rb @@ -17,6 +17,7 @@ class UsersStarProject < ApplicationRecord scope :by_project, -> (project) { where(project_id: project.id) } scope :with_visible_profile, -> (user) { joins(:user).merge(User.with_visible_profile(user)) } scope :with_public_profile, -> { joins(:user).merge(User.with_public_profile) } + scope :preload_users, -> { preload(:user) } class << self def sort_by_attribute(method) -- cgit v1.2.1 From 93a618f0e54b5ae28f7525b8861763130c692415 Mon Sep 17 00:00:00 2001 From: Luke Duncalfe Date: Thu, 1 Aug 2019 17:54:52 +1200 Subject: New wiki page redirects user to random slug Previously we asked a user to enter a new slug before taking them to the Create Page page. As a UX improvement, we now take them to a randomly generated URI so they can begin creating their new page. https://gitlab.com/gitlab-org/gitlab-ce/issues/46299 --- app/models/project_wiki.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/models') diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index c91add6439f..4a19e05bf76 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -85,6 +85,10 @@ class ProjectWiki list_pages(limit: 1).empty? end + def exists? + !empty? + end + # Lists wiki pages of the repository. # # limit - max number of pages returned by the method. -- cgit v1.2.1 From 37b17fa61a1fb5efe5942ab2cb27b15685bf905e Mon Sep 17 00:00:00 2001 From: Luke Duncalfe Date: Tue, 18 Jun 2019 13:44:43 +1200 Subject: Add service classes for mutating AwardEmoji Adding, destroying and toggling emoji previously lacked services and instead were performed through methods called on Awardable models. This led to inconsistencies where relevant todos would be marked as done only when emoji were awarded through our controllers, but not through the API. Todos could also be marked as done when an emoji was being removed. Behaviour changes - Awarding emoji through the API will now mark a relevant Todo as done - Toggling an emoji off (destroying it) through our controllers will no longer mark a relevant Todo as done Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/63372 --- app/models/award_emoji.rb | 6 ++++-- app/models/concerns/awardable.rb | 26 +------------------------- 2 files changed, 5 insertions(+), 27 deletions(-) (limited to 'app/models') diff --git a/app/models/award_emoji.rb b/app/models/award_emoji.rb index e26162f6151..0ab302a0f3e 100644 --- a/app/models/award_emoji.rb +++ b/app/models/award_emoji.rb @@ -16,8 +16,10 @@ class AwardEmoji < ApplicationRecord participant :user - scope :downvotes, -> { where(name: DOWNVOTE_NAME) } - scope :upvotes, -> { where(name: UPVOTE_NAME) } + scope :downvotes, -> { named(DOWNVOTE_NAME) } + scope :upvotes, -> { named(UPVOTE_NAME) } + scope :named, -> (names) { where(name: names) } + scope :awarded_by, -> (users) { where(user: users) } after_save :expire_etag_cache after_destroy :expire_etag_cache diff --git a/app/models/concerns/awardable.rb b/app/models/concerns/awardable.rb index 14bc56f0eee..f229b42ade6 100644 --- a/app/models/concerns/awardable.rb +++ b/app/models/concerns/awardable.rb @@ -106,30 +106,6 @@ module Awardable end def awarded_emoji?(emoji_name, current_user) - award_emoji.where(name: emoji_name, user: current_user).exists? - end - - def create_award_emoji(name, current_user) - return unless emoji_awardable? - - award_emoji.create(name: normalize_name(name), user: current_user) - end - - def remove_award_emoji(name, current_user) - award_emoji.where(name: name, user: current_user).destroy_all # rubocop: disable DestroyAll - end - - def toggle_award_emoji(emoji_name, current_user) - if awarded_emoji?(emoji_name, current_user) - remove_award_emoji(emoji_name, current_user) - else - create_award_emoji(emoji_name, current_user) - end - end - - private - - def normalize_name(name) - Gitlab::Emoji.normalize_emoji_name(name) + award_emoji.named(emoji_name).awarded_by(current_user).exists? end end -- cgit v1.2.1 From 45c5144e36e73c80e34282dda7b7c1c32a1fc0ea Mon Sep 17 00:00:00 2001 From: Fabio Pitino Date: Mon, 19 Aug 2019 16:29:53 +0200 Subject: Add active_jobs_limit to plans table This is a port from EE changes where we introduce a new limit for Plan model. https://dev.gitlab.org/gitlab/gitlab-ee/merge_requests/1182 --- app/models/ci/pipeline.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/models') diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 0a943a33bbb..64e372878e6 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -203,6 +203,7 @@ module Ci scope :for_sha, -> (sha) { where(sha: sha) } scope :for_source_sha, -> (source_sha) { where(source_sha: source_sha) } scope :for_sha_or_source_sha, -> (sha) { for_sha(sha).or(for_source_sha(sha)) } + scope :created_after, -> (time) { where('ci_pipelines.created_at > ?', time) } scope :triggered_by_merge_request, -> (merge_request) do where(source: :merge_request_event, merge_request: merge_request) -- cgit v1.2.1 From 8bcc47ac02e69eb4564238b454ca8286a4126765 Mon Sep 17 00:00:00 2001 From: George Koltsov Date: Wed, 21 Aug 2019 10:13:45 +0000 Subject: Add SortingPreference concern Sorting preference functionality has been extracted from `IssuableCollections` to a new `SortingPreference` concern in order to reuse this functionality in projects (and groups in the future). --- app/models/project.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/models') diff --git a/app/models/project.rb b/app/models/project.rb index 8efe4b06f87..10679fb1f85 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -55,6 +55,8 @@ class Project < ApplicationRecord VALID_MIRROR_PORTS = [22, 80, 443].freeze VALID_MIRROR_PROTOCOLS = %w(http https ssh git).freeze + SORTING_PREFERENCE_FIELD = :projects_sort + cache_markdown_field :description, pipeline: :description delegate :feature_available?, :builds_enabled?, :wiki_enabled?, -- cgit v1.2.1 From 5012c622405e63655256735d266168450ad1d159 Mon Sep 17 00:00:00 2001 From: Sebastian Arcila Valenzuela Date: Mon, 12 Aug 2019 15:41:05 +0200 Subject: Add User#will_save_change_to_login? to clear reset_password_tokens Devise checks before updating any of the authentication_keys if it needs to clear the reset_password_tokens. This should fix: https://gitlab.com/gitlab-org/gitlab-ce/issues/42733 (Weak authentication and session management) --- app/models/user.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'app/models') diff --git a/app/models/user.rb b/app/models/user.rb index 6131a8dc710..909f5f3873d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -643,6 +643,13 @@ class User < ApplicationRecord end end + # will_save_change_to_attribute? is used by Devise to check if it is necessary + # to clear any existing reset_password_tokens before updating an authentication_key + # and login in our case is a virtual attribute to allow login by username or email. + def will_save_change_to_login? + will_save_change_to_username? || will_save_change_to_email? + end + def unique_email if !emails.exists?(email: email) && Email.exists?(email: email) errors.add(:email, _('has already been taken')) -- cgit v1.2.1 From d78f0724d9cc3dd7c1f22cef54ad59f8d2b579c4 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Thu, 1 Aug 2019 19:05:02 +0700 Subject: Avoid conflicts between ArchiveTraceWorkers This commits avoiding conflicts between ArchiveTraceWorker and ArchiveTracesCronWorker by changing the target of the latter worker. --- app/models/ci/build.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/models') diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 3c0efca31db..7930bef5cf2 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -121,6 +121,8 @@ module Ci scope :scheduled_actions, ->() { where(when: :delayed, status: COMPLETED_STATUSES + %i[scheduled]) } scope :ref_protected, -> { where(protected: true) } scope :with_live_trace, -> { where('EXISTS (?)', Ci::BuildTraceChunk.where('ci_builds.id = ci_build_trace_chunks.build_id').select(1)) } + scope :with_stale_live_trace, -> { with_live_trace.finished_before(12.hours.ago) } + scope :finished_before, -> (date) { finished.where('finished_at < ?', date) } scope :matches_tag_ids, -> (tag_ids) do matcher = ::ActsAsTaggableOn::Tagging -- cgit v1.2.1 From 5af535d919c50951513f5859730afd924a01c29b Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Wed, 17 Jul 2019 12:54:40 +0300 Subject: Limit the size of issuable description and comments Limiting the size of issuable description and comments to 1_000_000, which is close to ~1MB of ASCII characters, which represents 99.9% of all descriptions and comments we have in DB at the moment. This should help prevent DoS attacks when comments contain refference strings. Also this change updates regexp matching the namespaces paths by limiting the namespaces paths to Namespace::NUMBER_OF_ANCESTORS_ALLOWED, as we allow 20 levels deep groups. see https://gitlab.com/gitlab-org/gitlab-ce/issues/61974#note_191274234 --- app/models/concerns/issuable.rb | 1 + app/models/note.rb | 1 + 2 files changed, 2 insertions(+) (limited to 'app/models') diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index e60b6497cb7..a9e2f2be980 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -73,6 +73,7 @@ module Issuable validates :author, presence: true validates :title, presence: true, length: { maximum: 255 } + validates :description, length: { maximum: Gitlab::Database::MAX_TEXT_SIZE_LIMIT }, allow_blank: true validate :milestone_is_valid scope :authored, ->(user) { where(author_id: user) } diff --git a/app/models/note.rb b/app/models/note.rb index a12d1eb7243..79aad5cbff9 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -89,6 +89,7 @@ class Note < ApplicationRecord delegate :title, to: :noteable, allow_nil: true validates :note, presence: true + validates :note, length: { maximum: Gitlab::Database::MAX_TEXT_SIZE_LIMIT } validates :project, presence: true, if: :for_project_noteable? # Attachments are deprecated and are handled by Markdown uploader -- cgit v1.2.1 From a5f6182753502a5e74b06836c9bb70d287bf6fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Trzci=C5=84ski?= Date: Thu, 22 Aug 2019 13:08:46 +0200 Subject: Optimise build queue service This makes BuildQueueService to force refresh runners that are considered to have recent queue. Such runners are the ones that connected within online interval + time to expire runner cache. --- app/models/ci/runner.rb | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'app/models') diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 43ff874ac23..1c1c7a5ae7a 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -23,13 +23,17 @@ module Ci project_type: 3 } - RUNNER_QUEUE_EXPIRY_TIME = 60.minutes ONLINE_CONTACT_TIMEOUT = 1.hour - UPDATE_DB_RUNNER_INFO_EVERY = 40.minutes + RUNNER_QUEUE_EXPIRY_TIME = 1.hour + + # This needs to be less than `ONLINE_CONTACT_TIMEOUT` + UPDATE_CONTACT_COLUMN_EVERY = (40.minutes..55.minutes).freeze + AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze AVAILABLE_TYPES = runner_types.keys.freeze AVAILABLE_STATUSES = %w[active paused online offline].freeze AVAILABLE_SCOPES = (AVAILABLE_TYPES_LEGACY + AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze + FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze ignore_column :is_shared @@ -46,7 +50,7 @@ module Ci scope :active, -> { where(active: true) } scope :paused, -> { where(active: false) } - scope :online, -> { where('contacted_at > ?', contact_time_deadline) } + scope :online, -> { where('contacted_at > ?', online_contact_time_deadline) } # The following query using negation is cheaper than using `contacted_at <= ?` # because there are less runners online than have been created. The # resulting query is quickly finding online ones and then uses the regular @@ -56,6 +60,8 @@ module Ci scope :offline, -> { where.not(id: online) } scope :ordered, -> { order(id: :desc) } + scope :with_recent_runner_queue, -> { where('contacted_at > ?', recent_queue_deadline) } + # BACKWARD COMPATIBILITY: There are needed to maintain compatibility with `AVAILABLE_SCOPES` used by `lib/api/runners.rb` scope :deprecated_shared, -> { instance_type } scope :deprecated_specific, -> { project_type.or(group_type) } @@ -137,10 +143,18 @@ module Ci fuzzy_search(query, [:token, :description]) end - def self.contact_time_deadline + def self.online_contact_time_deadline ONLINE_CONTACT_TIMEOUT.ago end + def self.recent_queue_deadline + # we add queue expiry + online + # - contacted_at can be updated at any time within this interval + # we have always accurate `contacted_at` but it is stored in Redis + # and not persisted in database + (ONLINE_CONTACT_TIMEOUT + RUNNER_QUEUE_EXPIRY_TIME).ago + end + def self.order_by(order) if order == 'contacted_asc' order_contacted_at_asc @@ -174,7 +188,7 @@ module Ci end def online? - contacted_at && contacted_at > self.class.contact_time_deadline + contacted_at && contacted_at > self.class.online_contact_time_deadline end def status @@ -275,9 +289,7 @@ module Ci def persist_cached_data? # Use a random threshold to prevent beating DB updates. - # It generates a distribution between [40m, 80m]. - - contacted_at_max_age = UPDATE_DB_RUNNER_INFO_EVERY + Random.rand(UPDATE_DB_RUNNER_INFO_EVERY) + contacted_at_max_age = Random.rand(UPDATE_CONTACT_COLUMN_EVERY) real_contacted_at = read_attribute(:contacted_at) real_contacted_at.nil? || -- cgit v1.2.1 From d86b77bf20474702631d5fd89177c54a9f928760 Mon Sep 17 00:00:00 2001 From: Krasimir Angelov Date: Tue, 20 Aug 2019 13:29:16 +0300 Subject: Extract logic who created deployment into Deployment#deployed_by Prefer the deployable user over the deployment user. Related to https://gitlab.com/gitlab-org/gitlab-ce/issues/66037. --- app/models/deployment.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'app/models') diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 68586e7a1fd..bff5d348ca0 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -162,6 +162,14 @@ class Deployment < ApplicationRecord deployed_at&.to_time&.in_time_zone&.to_s(:medium) end + def deployed_by + # We use deployable's user if available because Ci::PlayBuildService + # does not update the deployment's user, just the one for the deployable. + # TODO: use deployment's user once https://gitlab.com/gitlab-org/gitlab-ce/issues/66442 + # is completed. + deployable&.user || user + end + private def ref_path -- cgit v1.2.1 From 606a1d2d31aff69ddabe7e3794f61f3e778da3e8 Mon Sep 17 00:00:00 2001 From: Alessio Caiazza Date: Thu, 22 Aug 2019 22:08:28 +0000 Subject: Expose namespace storage statistics with GraphQL Root namespaces have storage statistics. This commit allows namespace owners to get those stats via GraphQL queries like the following one { namespace(fullPath: "a_namespace_path") { rootStorageStatistics { storageSize repositorySize lfsObjectsSize buildArtifactsSize packagesSize wikiSize } } } --- app/models/namespace/root_storage_statistics.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/models') diff --git a/app/models/namespace/root_storage_statistics.rb b/app/models/namespace/root_storage_statistics.rb index 56c430013ee..ae9b2f14343 100644 --- a/app/models/namespace/root_storage_statistics.rb +++ b/app/models/namespace/root_storage_statistics.rb @@ -8,6 +8,8 @@ class Namespace::RootStorageStatistics < ApplicationRecord belongs_to :namespace has_one :route, through: :namespace + scope :for_namespace_ids, ->(namespace_ids) { where(namespace_id: namespace_ids) } + delegate :all_projects, to: :namespace def recalculate! -- cgit v1.2.1 From f5b855546ed9b2c304b72e349af3f23c4eca549d Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 15 Aug 2019 13:56:33 +0300 Subject: Update sort options for issues list Increase sort options for issues list from updated_at and create_at, to include more options close to what is required in actual issue list UI. This helps us to use REST API for issues list with sorting capabilities https://gitlab.com/gitlab-org/gitlab-ce/issues/57402 --- app/models/concerns/issuable.rb | 19 +++++++++---------- app/models/concerns/sortable.rb | 6 +++++- app/models/issue.rb | 9 ++++----- 3 files changed, 18 insertions(+), 16 deletions(-) (limited to 'app/models') diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index e60b6497cb7..db46d7afbb9 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -186,16 +186,15 @@ module Issuable def sort_by_attribute(method, excluded_labels: []) sorted = case method.to_s - when 'downvotes_desc' then order_downvotes_desc - when 'label_priority' then order_labels_priority(excluded_labels: excluded_labels) - when 'label_priority_desc' then order_labels_priority('DESC', excluded_labels: excluded_labels) - when 'milestone', 'milestone_due_asc' then order_milestone_due_asc - when 'milestone_due_desc' then order_milestone_due_desc - when 'popularity', 'popularity_desc' then order_upvotes_desc - when 'popularity_asc' then order_upvotes_asc - when 'priority', 'priority_asc' then order_due_date_and_labels_priority(excluded_labels: excluded_labels) - when 'priority_desc' then order_due_date_and_labels_priority('DESC', excluded_labels: excluded_labels) - when 'upvotes_desc' then order_upvotes_desc + when 'downvotes_desc' then order_downvotes_desc + when 'label_priority', 'label_priority_asc' then order_labels_priority(excluded_labels: excluded_labels) + when 'label_priority_desc' then order_labels_priority('DESC', excluded_labels: excluded_labels) + when 'milestone', 'milestone_due_asc' then order_milestone_due_asc + when 'milestone_due_desc' then order_milestone_due_desc + when 'popularity_asc' then order_upvotes_asc + when 'popularity', 'popularity_desc', 'upvotes_desc' then order_upvotes_desc + when 'priority', 'priority_asc' then order_due_date_and_labels_priority(excluded_labels: excluded_labels) + when 'priority_desc' then order_due_date_and_labels_priority('DESC', excluded_labels: excluded_labels) else order_by(method) end diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb index df1a9e3fe6e..c4af1b1fab2 100644 --- a/app/models/concerns/sortable.rb +++ b/app/models/concerns/sortable.rb @@ -27,14 +27,18 @@ module Sortable def simple_sorts { 'created_asc' => -> { order_created_asc }, + 'created_at_asc' => -> { order_created_asc }, 'created_date' => -> { order_created_desc }, 'created_desc' => -> { order_created_desc }, + 'created_at_desc' => -> { order_created_desc }, 'id_asc' => -> { order_id_asc }, 'id_desc' => -> { order_id_desc }, 'name_asc' => -> { order_name_asc }, 'name_desc' => -> { order_name_desc }, 'updated_asc' => -> { order_updated_asc }, - 'updated_desc' => -> { order_updated_desc } + 'updated_at_asc' => -> { order_updated_asc }, + 'updated_desc' => -> { order_updated_desc }, + 'updated_at_desc' => -> { order_updated_desc } } end diff --git a/app/models/issue.rb b/app/models/issue.rb index c5a18f0af0f..caea8eadd18 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -128,11 +128,10 @@ class Issue < ApplicationRecord def self.sort_by_attribute(method, excluded_labels: []) case method.to_s - when 'closest_future_date' then order_closest_future_date - when 'due_date' then order_due_date_asc - when 'due_date_asc' then order_due_date_asc - when 'due_date_desc' then order_due_date_desc - when 'relative_position' then order_relative_position_asc.with_order_id_desc + when 'closest_future_date', 'closest_future_date_asc' then order_closest_future_date + when 'due_date', 'due_date_asc' then order_due_date_asc + when 'due_date_desc' then order_due_date_desc + when 'relative_position', 'relative_position_asc' then order_relative_position_asc.with_order_id_desc else super end -- cgit v1.2.1 From 60e33885269bdae71e9710b17f199708b9b7c9e0 Mon Sep 17 00:00:00 2001 From: Adam Hegyi Date: Fri, 23 Aug 2019 20:28:11 +0000 Subject: Implement validation logic to ProjectStage - Introducting StageEvents to define the available events - Define the event pairing rules, since some events are not compatible - Express default Cycle Analytics stages with the event structure --- .../analytics/cycle_analytics/project_stage.rb | 5 ++ .../concerns/analytics/cycle_analytics/stage.rb | 68 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 app/models/concerns/analytics/cycle_analytics/stage.rb (limited to 'app/models') diff --git a/app/models/analytics/cycle_analytics/project_stage.rb b/app/models/analytics/cycle_analytics/project_stage.rb index 88c8cb40ccb..a312bd24e78 100644 --- a/app/models/analytics/cycle_analytics/project_stage.rb +++ b/app/models/analytics/cycle_analytics/project_stage.rb @@ -3,7 +3,12 @@ module Analytics module CycleAnalytics class ProjectStage < ApplicationRecord + include Analytics::CycleAnalytics::Stage + + validates :project, presence: true belongs_to :project + + alias_attribute :parent, :project end end end diff --git a/app/models/concerns/analytics/cycle_analytics/stage.rb b/app/models/concerns/analytics/cycle_analytics/stage.rb new file mode 100644 index 00000000000..0c603c2d5e6 --- /dev/null +++ b/app/models/concerns/analytics/cycle_analytics/stage.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Analytics + module CycleAnalytics + module Stage + extend ActiveSupport::Concern + + included do + validates :name, presence: true + validates :start_event_identifier, presence: true + validates :end_event_identifier, presence: true + validate :validate_stage_event_pairs + + enum start_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :start_event_identifier + enum end_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :end_event_identifier + + alias_attribute :custom_stage?, :custom + end + + def parent=(_) + raise NotImplementedError + end + + def parent + raise NotImplementedError + end + + def start_event + Gitlab::Analytics::CycleAnalytics::StageEvents[start_event_identifier].new(params_for_start_event) + end + + def end_event + Gitlab::Analytics::CycleAnalytics::StageEvents[end_event_identifier].new(params_for_end_event) + end + + def params_for_start_event + {} + end + + def params_for_end_event + {} + end + + def default_stage? + !custom + end + + # The model that is going to be queried, Issue or MergeRequest + def subject_model + start_event.object_type + end + + private + + def validate_stage_event_pairs + return if start_event_identifier.nil? || end_event_identifier.nil? + + unless pairing_rules.fetch(start_event.class, []).include?(end_event.class) + errors.add(:end_event, :not_allowed_for_the_given_start_event) + end + end + + def pairing_rules + Gitlab::Analytics::CycleAnalytics::StageEvents.pairing_rules + end + end + end +end -- cgit v1.2.1 From ad05e488636ebe05b4985dbf3c7d912fd8d56f49 Mon Sep 17 00:00:00 2001 From: Brett Walker Date: Wed, 20 Feb 2019 17:51:55 -0600 Subject: Add support for using a Camo proxy server User images and videos will get proxied through the Camo server in order to keep malicious sites from collecting the IP address of users. --- app/models/application_setting.rb | 18 ++++++++++++++++ app/models/application_setting_implementation.rb | 27 +++++++++++++++++------- 2 files changed, 37 insertions(+), 8 deletions(-) (limited to 'app/models') diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 2a99c6e5c59..92004b92647 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -18,12 +18,19 @@ class ApplicationSetting < ApplicationRecord # fix a lot of tests using allow_any_instance_of include ApplicationSettingImplementation + attr_encrypted :asset_proxy_secret_key, + mode: :per_attribute_iv, + insecure_mode: true, + key: Settings.attr_encrypted_db_key_base_truncated, + algorithm: 'aes-256-cbc' + serialize :restricted_visibility_levels # rubocop:disable Cop/ActiveRecordSerialize serialize :import_sources # rubocop:disable Cop/ActiveRecordSerialize serialize :disabled_oauth_sign_in_sources, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :domain_whitelist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize + serialize :asset_proxy_whitelist, Array # rubocop:disable Cop/ActiveRecordSerialize ignore_column :koding_url ignore_column :koding_enabled @@ -192,6 +199,17 @@ class ApplicationSetting < ApplicationRecord allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than: 65536 } + validates :asset_proxy_url, + presence: true, + allow_blank: false, + url: true, + if: :asset_proxy_enabled? + + validates :asset_proxy_secret_key, + presence: true, + allow_blank: false, + if: :asset_proxy_enabled? + SUPPORTED_KEY_TYPES.each do |type| validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type } end diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index 55ac1e129cf..a6dd9986e23 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -23,8 +23,9 @@ module ApplicationSettingImplementation akismet_enabled: false, allow_local_requests_from_web_hooks_and_services: false, allow_local_requests_from_system_hooks: true, - dns_rebinding_protection_enabled: true, + asset_proxy_enabled: false, authorized_keys_enabled: true, # TODO default to false if the instance is configured to use AuthorizedKeysCommand + commit_email_hostname: default_commit_email_hostname, container_registry_token_expire_delay: 5, default_artifacts_expire_in: '30 days', default_branch_protection: Settings.gitlab['default_branch_protection'], @@ -33,7 +34,9 @@ module ApplicationSettingImplementation default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'], default_projects_limit: Settings.gitlab['default_projects_limit'], default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'], + diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES, disabled_oauth_sign_in_sources: [], + dns_rebinding_protection_enabled: true, domain_whitelist: Settings.gitlab['domain_whitelist'], dsa_key_restriction: 0, ecdsa_key_restriction: 0, @@ -52,9 +55,11 @@ module ApplicationSettingImplementation housekeeping_gc_period: 200, housekeeping_incremental_repack_period: 10, import_sources: Settings.gitlab['import_sources'], + local_markdown_version: 0, max_artifacts_size: Settings.artifacts['max_size'], max_attachment_size: Settings.gitlab['max_attachment_size'], mirror_available: true, + outbound_local_requests_whitelist: [], password_authentication_enabled_for_git: true, password_authentication_enabled_for_web: Settings.gitlab['signin_enabled'], performance_bar_allowed_group_id: nil, @@ -63,6 +68,8 @@ module ApplicationSettingImplementation plantuml_url: nil, polling_interval_multiplier: 1, project_export_enabled: true, + protected_ci_variables: false, + raw_blob_request_limit: 300, recaptcha_enabled: false, repository_checks_enabled: true, repository_storages: ['default'], @@ -95,16 +102,10 @@ module ApplicationSettingImplementation user_default_internal_regex: nil, user_show_add_ssh_key_message: true, usage_stats_set_by_user_id: nil, - diff_max_patch_bytes: Gitlab::Git::Diff::DEFAULT_MAX_PATCH_BYTES, - commit_email_hostname: default_commit_email_hostname, snowplow_collector_hostname: nil, snowplow_cookie_domain: nil, snowplow_enabled: false, - snowplow_site_id: nil, - protected_ci_variables: false, - local_markdown_version: 0, - outbound_local_requests_whitelist: [], - raw_blob_request_limit: 300 + snowplow_site_id: nil } end @@ -198,6 +199,15 @@ module ApplicationSettingImplementation end end + def asset_proxy_whitelist=(values) + values = domain_strings_to_array(values) if values.is_a?(String) + + # make sure we always whitelist the running host + values << Gitlab.config.gitlab.host unless values.include?(Gitlab.config.gitlab.host) + + self[:asset_proxy_whitelist] = values + end + def repository_storages Array(read_attribute(:repository_storages)) end @@ -306,6 +316,7 @@ module ApplicationSettingImplementation values .split(DOMAIN_LIST_SEPARATOR) + .map(&:strip) .reject(&:empty?) .uniq end -- cgit v1.2.1 From a844a958ea875b548b572faaca8e2fd523464735 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Mon, 26 Aug 2019 12:31:25 +0200 Subject: Remove the object pools feature flag The flag defaulted to true, so there's no change unless users turned it off. Given there's a lack of issues regarding object pools, this should be OK. --- app/models/project.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/project.rb b/app/models/project.rb index 10679fb1f85..66d5286196e 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -2175,8 +2175,7 @@ class Project < ApplicationRecord hashed_storage?(:repository) && public? && repository_exists? && - Gitlab::CurrentSettings.hashed_storage_enabled && - Feature.enabled?(:object_pools, self, default_enabled: true) + Gitlab::CurrentSettings.hashed_storage_enabled end def leave_pool_repository -- cgit v1.2.1 From a06410d995e1200c7734b2d50e68506320d13dd0 Mon Sep 17 00:00:00 2001 From: Aishwarya Subramanian Date: Mon, 26 Aug 2019 18:20:18 +0000 Subject: Using before_save method instead of setter Removed unused method for name setter method --- app/models/user.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/user.rb b/app/models/user.rb index 6131a8dc710..6107aaa7fca 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -161,6 +161,8 @@ class User < ApplicationRecord # # Note: devise :validatable above adds validations for :email and :password validates :name, presence: true, length: { maximum: 128 } + validates :first_name, length: { maximum: 255 } + validates :last_name, length: { maximum: 255 } validates :email, confirmation: true validates :notification_email, presence: true validates :notification_email, devise_email: true, if: ->(user) { user.notification_email != user.email } @@ -881,7 +883,15 @@ class User < ApplicationRecord end def first_name - name.split.first unless name.blank? + read_attribute(:first_name) || begin + name.split(' ').first unless name.blank? + end + end + + def last_name + read_attribute(:last_name) || begin + name.split(' ').drop(1).join(' ') unless name.blank? + end end def projects_limit_left -- cgit v1.2.1 From 93cf4124737b20e3f810f0c0ad366271a9a0c251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Etienne=20Baqu=C3=A9?= Date: Fri, 12 Jul 2019 16:49:47 -0400 Subject: Add encrypted optional option to DeployToken authentication field --- app/models/deploy_token.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/deploy_token.rb b/app/models/deploy_token.rb index 33f0be91632..85f5a2040c0 100644 --- a/app/models/deploy_token.rb +++ b/app/models/deploy_token.rb @@ -5,7 +5,7 @@ class DeployToken < ApplicationRecord include TokenAuthenticatable include PolicyActor include Gitlab::Utils::StrongMemoize - add_authentication_token_field :token + add_authentication_token_field :token, encrypted: :optional AVAILABLE_SCOPES = %i(read_repository read_registry).freeze GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'.freeze -- cgit v1.2.1 From 5270e7e5af9fdcc8853b541686b6dea48da9c4ac Mon Sep 17 00:00:00 2001 From: Tomasz Maczukin Date: Tue, 27 Aug 2019 20:39:17 +0200 Subject: Update GitLab Runner Helm Chart to 0.8.0 --- app/models/clusters/applications/runner.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/clusters/applications/runner.rb b/app/models/clusters/applications/runner.rb index 6533b7a186e..329250255fd 100644 --- a/app/models/clusters/applications/runner.rb +++ b/app/models/clusters/applications/runner.rb @@ -3,7 +3,7 @@ module Clusters module Applications class Runner < ApplicationRecord - VERSION = '0.7.0'.freeze + VERSION = '0.8.0'.freeze self.table_name = 'clusters_applications_runners' -- cgit v1.2.1 From 2022e6799bcbf119ea80145e4993ffdb7bb108e3 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 27 Aug 2019 06:07:38 -0700 Subject: Makes LFS object linker process OIDs in batches During a project import, `LfsLinkService` attempts to link `LfsObjects` that have not already been associated with a project. It's possible for a large repo to have thousands of OIDs, which can cause long database query and parsing times. By processing a batch of 1000 at a time, we can reduce that time at the expense of a few more SQL queries. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/66274 --- app/models/lfs_object.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/models') diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb index 79a376ff0fd..40695a97d97 100644 --- a/app/models/lfs_object.rb +++ b/app/models/lfs_object.rb @@ -2,6 +2,7 @@ class LfsObject < ApplicationRecord include AfterCommitQueue + include EachBatch include ObjectStorage::BackgroundMove has_many :lfs_objects_projects, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent -- cgit v1.2.1 From 4ca32c2b55519aa2b7852c879ad700e8fa290f80 Mon Sep 17 00:00:00 2001 From: Arun Kumar Mohan Date: Thu, 27 Jun 2019 00:56:08 -0500 Subject: Add Issue and Merge Request titles to Todo items Only displays the todo body if the todo has a note. This is to avoid redundant Issue or Merge Request titles displayed both in the Todo title and body. --- app/models/todo.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/todo.rb b/app/models/todo.rb index 240c91da5b6..1ec04189482 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -186,9 +186,9 @@ class Todo < ApplicationRecord def target_reference if for_commit? - target.reference_link_text(full: true) + target.reference_link_text else - target.to_reference(full: true) + target.to_reference end end -- cgit v1.2.1 From 72544449cfb8e35b8c044f5bfd08a2fae2253408 Mon Sep 17 00:00:00 2001 From: Igor Drozdov Date: Mon, 26 Aug 2019 02:55:00 +0300 Subject: Change the way totalNotes is calculated totalNotes is only used to prerender a number of skeleton containers until real notes are loaded issuable.discussions makes multiple requests, so too expensive for this This commit uses mere notes for this and sends actual totalNotes number if it's less than 10; otherwise it sends 10 - it allows us to avoid bunch of skeleton prerenderings, which are not necessary since they doesn't fit into the whole screen and disappear quite fast --- app/models/concerns/noteable.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/models') diff --git a/app/models/concerns/noteable.rb b/app/models/concerns/noteable.rb index 4b428b0af83..6a44bc7c401 100644 --- a/app/models/concerns/noteable.rb +++ b/app/models/concerns/noteable.rb @@ -73,6 +73,10 @@ module Noteable .discussions(self) end + def capped_notes_count(max) + notes.limit(max).count + end + def grouped_diff_discussions(*args) # Doesn't use `discussion_notes`, because this may include commit diff notes # besides MR diff notes, that we do not want to display on the MR Changes tab. -- cgit v1.2.1 From 29ce13e9992c296fbb2c4ad2706f53e491143d3e Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Tue, 27 Aug 2019 22:48:24 -0700 Subject: Fix moving issues API failing when text includes commit URLs When a issue is moved from one project to another, all associated Markdown text is rewritten in the context of the new project. If the note contained a link to a commit URL, `CommitRewriter#rewrite` would fail because `Commit#link_reference_pattern` would match `nil` `commit` values in the HTML generated from the Markdown. These `nil` values were passed along to `Project#commits_by` because `Commit#reference_valid?` was always returning `true`. To prevent this issue from happening, we tighten up the check for `Commit#reference_valid?` to look for valid SHA values. Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/66666 --- app/models/commit.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/commit.rb b/app/models/commit.rb index 0889ce7e287..1470b50f396 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -35,6 +35,7 @@ class Commit MIN_SHA_LENGTH = Gitlab::Git::Commit::MIN_SHA_LENGTH COMMIT_SHA_PATTERN = /\h{#{MIN_SHA_LENGTH},40}/.freeze + EXACT_COMMIT_SHA_PATTERN = /\A#{COMMIT_SHA_PATTERN}\z/.freeze # Used by GFM to match and present link extensions on node texts and hrefs. LINK_EXTENSION_PATTERN = /(patch)/.freeze @@ -90,7 +91,7 @@ class Commit end def valid_hash?(key) - !!(/\A#{COMMIT_SHA_PATTERN}\z/ =~ key) + !!(EXACT_COMMIT_SHA_PATTERN =~ key) end def lazy(project, oid) @@ -139,6 +140,10 @@ class Commit '@' end + def self.reference_valid?(reference) + !!(reference =~ EXACT_COMMIT_SHA_PATTERN) + end + # Pattern used to extract commit references from text # # This pattern supports cross-project references. -- cgit v1.2.1 From c9b4dc677abdebc02ecac4dca65a759d3f07b2a0 Mon Sep 17 00:00:00 2001 From: Patrick Derichs Date: Fri, 9 Aug 2019 14:54:57 +0200 Subject: Filter out old system notes for epics --- app/models/note.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/models') diff --git a/app/models/note.rb b/app/models/note.rb index a12d1eb7243..fae66ce7e4a 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -331,6 +331,10 @@ class Note < ApplicationRecord cross_reference? && !all_referenced_mentionables_allowed?(user) end + def visible_for?(user) + !cross_reference_not_visible_for?(user) + end + def award_emoji? can_be_award_emoji? && contains_emoji_only? end -- cgit v1.2.1 From 59995d15886b831f2483dfaa8e0c46372aa76eb0 Mon Sep 17 00:00:00 2001 From: Patrick Derichs Date: Wed, 28 Aug 2019 12:09:45 +0200 Subject: Return NO_ACCESS if user is nil --- app/models/group.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/models') diff --git a/app/models/group.rb b/app/models/group.rb index 6c868b1d1f0..61a4802a6ee 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -365,6 +365,8 @@ class Group < Namespace end def max_member_access_for_user(user) + return GroupMember::NO_ACCESS unless user + return GroupMember::OWNER if user.admin? members_with_parents -- cgit v1.2.1 From e4fbd94cf5eba0b103bd97627d822f2014dfe474 Mon Sep 17 00:00:00 2001 From: Victor Zagorodny Date: Wed, 28 Aug 2019 14:26:42 +0000 Subject: Update CE files for GSD projects filter A new param with_security_reports was added to GET /groups/:id/projects API and the code to support this logic in GroupProjectsFinder and Project model. Also, a DB index was added to ci_job_artifacts table to speed up the search of security reports artifacts for projects --- app/models/ci/job_artifact.rb | 2 ++ app/models/project.rb | 1 + 2 files changed, 3 insertions(+) (limited to 'app/models') diff --git a/app/models/ci/job_artifact.rb b/app/models/ci/job_artifact.rb index e132cb045e2..b4497d8af09 100644 --- a/app/models/ci/job_artifact.rb +++ b/app/models/ci/job_artifact.rb @@ -87,6 +87,8 @@ module Ci scope :expired, -> (limit) { where('expire_at < ?', Time.now).limit(limit) } + scope :scoped_project, -> { where('ci_job_artifacts.project_id = projects.id') } + delegate :filename, :exists?, :open, to: :file enum file_type: { diff --git a/app/models/project.rb b/app/models/project.rb index 66d5286196e..c67c5c7bc8c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -497,6 +497,7 @@ class Project < ApplicationRecord # We require an alias to the project_mirror_data_table in order to use import_state in our queries scope :joins_import_state, -> { joins("INNER JOIN project_mirror_data import_state ON import_state.project_id = projects.id") } scope :for_group, -> (group) { where(group: group) } + scope :for_group_and_its_subgroups, ->(group) { where(namespace_id: group.self_and_descendants.select(:id)) } class << self # Searches for a list of projects based on the query given in `query`. -- cgit v1.2.1 From 8f6a433c416f8fb052468f4ecf1141afd5e5ef6b Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Wed, 28 Aug 2019 20:18:40 +0000 Subject: Save board lists collapsed setting Persists if a board list is collapsed for each user. --- app/models/list.rb | 54 ++++++++++++++++++++++++++++++++++++-- app/models/list_user_preference.rb | 10 +++++++ 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 app/models/list_user_preference.rb (limited to 'app/models') diff --git a/app/models/list.rb b/app/models/list.rb index ccadd39bda2..ae7085f05a7 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -1,9 +1,11 @@ # frozen_string_literal: true class List < ApplicationRecord + include Importable + belongs_to :board belongs_to :label - include Importable + has_many :list_user_preferences enum list_type: { backlog: 0, label: 1, closed: 2, assignee: 3, milestone: 4 } @@ -16,9 +18,24 @@ class List < ApplicationRecord scope :destroyable, -> { where(list_type: list_types.slice(*destroyable_types).values) } scope :movable, -> { where(list_type: list_types.slice(*movable_types).values) } - scope :preload_associations, -> { preload(:board, :label) } + + scope :preload_associations, -> (user) do + preload(:board, label: :priorities) + .with_preferences_for(user) + end + scope :ordered, -> { order(:list_type, :position) } + # Loads list with preferences for given user + # if preferences exists for user or not + scope :with_preferences_for, -> (user) do + return unless user + + includes(:list_user_preferences).where(list_user_preferences: { user_id: [user.id, nil] }) + end + + alias_method :preferences, :list_user_preferences + class << self def destroyable_types [:label] @@ -29,6 +46,31 @@ class List < ApplicationRecord end end + def preferences_for(user) + return preferences.build unless user + + if preferences.loaded? + preloaded_preferences_for(user) + else + preferences.find_or_initialize_by(user: user) + end + end + + def preloaded_preferences_for(user) + user_preferences = + preferences.find do |preference| + preference.user_id == user.id + end + + user_preferences || preferences.build(user: user) + end + + def update_preferences_for(user, preferences = {}) + return unless user + + preferences_for(user).update(preferences) + end + def destroyable? self.class.destroyable_types.include?(list_type&.to_sym) end @@ -43,6 +85,14 @@ class List < ApplicationRecord def as_json(options = {}) super(options).tap do |json| + json[:collapsed] = false + + if options.key?(:collapsed) + preferences = preferences_for(options[:current_user]) + + json[:collapsed] = preferences.collapsed? + end + if options.key?(:label) json[:label] = label.as_json( project: board.project, diff --git a/app/models/list_user_preference.rb b/app/models/list_user_preference.rb new file mode 100644 index 00000000000..fe1cc7d5425 --- /dev/null +++ b/app/models/list_user_preference.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class ListUserPreference < ApplicationRecord + belongs_to :user + belongs_to :list + + validates :user, presence: true + validates :list, presence: true + validates :user_id, uniqueness: { scope: :list_id, message: "should have only one list preference per user" } +end -- cgit v1.2.1 From 72390953da802311180f53b6a646d80bc1da2849 Mon Sep 17 00:00:00 2001 From: Lee Tickett Date: Thu, 29 Aug 2019 16:19:07 +0000 Subject: Handle invalid mirror url --- app/models/remote_mirror.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/models') diff --git a/app/models/remote_mirror.rb b/app/models/remote_mirror.rb index c9ee0653d86..41e63986286 100644 --- a/app/models/remote_mirror.rb +++ b/app/models/remote_mirror.rb @@ -200,6 +200,7 @@ class RemoteMirror < ApplicationRecord result.password = '*****' if result.password result.user = '*****' if result.user && result.user != 'git' # tokens or other data may be saved as user result.to_s + rescue URI::Error end def ensure_remote! -- cgit v1.2.1 From 34d142e593827df932651aaacebcd3914ba7d923 Mon Sep 17 00:00:00 2001 From: George Koltsov Date: Thu, 29 Aug 2019 16:49:22 +0000 Subject: Allow project feature permissions to be overridden during import --- app/models/project.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/models') diff --git a/app/models/project.rb b/app/models/project.rb index c67c5c7bc8c..8f568a5b840 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -61,6 +61,8 @@ class Project < ApplicationRecord delegate :feature_available?, :builds_enabled?, :wiki_enabled?, :merge_requests_enabled?, :issues_enabled?, :pages_enabled?, :public_pages?, + :merge_requests_access_level, :issues_access_level, :wiki_access_level, + :snippets_access_level, :builds_access_level, :repository_access_level, to: :project_feature, allow_nil: true delegate :base_dir, :disk_path, :ensure_storage_path_exists, to: :storage -- cgit v1.2.1 From c6ccc07f48c7c1f9da43ecd82015500a4340544d Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 29 Aug 2019 18:04:52 +0100 Subject: Revert "Cache branch and tag names as Redis sets" This reverts commit 0eff75fa2b6691b6fba31fcc2842f51debd249a9. --- app/models/repository.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'app/models') diff --git a/app/models/repository.rb b/app/models/repository.rb index b957b9b0bdd..6f63cd32da4 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -239,13 +239,13 @@ class Repository def branch_exists?(branch_name) return false unless raw_repository - branch_names_include?(branch_name) + branch_names.include?(branch_name) end def tag_exists?(tag_name) return false unless raw_repository - tag_names_include?(tag_name) + tag_names.include?(tag_name) end def ref_exists?(ref) @@ -565,10 +565,10 @@ class Repository end delegate :branch_names, to: :raw_repository - cache_method_as_redis_set :branch_names, fallback: [] + cache_method :branch_names, fallback: [] delegate :tag_names, to: :raw_repository - cache_method_as_redis_set :tag_names, fallback: [] + cache_method :tag_names, fallback: [] delegate :branch_count, :tag_count, :has_visible_content?, to: :raw_repository cache_method :branch_count, fallback: 0 @@ -1130,10 +1130,6 @@ class Repository @cache ||= Gitlab::RepositoryCache.new(self) end - def redis_set_cache - @redis_set_cache ||= Gitlab::RepositorySetCache.new(self) - end - def request_store_cache @request_store_cache ||= Gitlab::RepositoryCache.new(self, backend: Gitlab::SafeRequestStore) end -- cgit v1.2.1 From fa6f19d1f83b68f2bb729be889ab7d66adbbedb8 Mon Sep 17 00:00:00 2001 From: dineshpanda Date: Fri, 30 Aug 2019 02:09:13 +0530 Subject: Remove dependency on IgnorableColumn concern --- app/models/application_setting.rb | 15 ++++++++------- app/models/ci/build.rb | 15 ++++++++------- app/models/ci/runner.rb | 3 +-- app/models/concerns/ignorable_column.rb | 30 ------------------------------ app/models/deploy_key.rb | 3 +-- app/models/event.rb | 1 - app/models/merge_request_diff.rb | 1 - app/models/note.rb | 3 +-- app/models/notification_setting.rb | 3 +-- app/models/user.rb | 9 +++++---- 10 files changed, 25 insertions(+), 58 deletions(-) delete mode 100644 app/models/concerns/ignorable_column.rb (limited to 'app/models') diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 2a99c6e5c59..8ff4cba2adb 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -4,7 +4,6 @@ class ApplicationSetting < ApplicationRecord include CacheableAttributes include CacheMarkdownField include TokenAuthenticatable - include IgnorableColumn include ChronicDurationAttribute add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption, default_enabled: true) ? :optional : :required } @@ -25,12 +24,14 @@ class ApplicationSetting < ApplicationRecord serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize - ignore_column :koding_url - ignore_column :koding_enabled - ignore_column :sentry_enabled - ignore_column :sentry_dsn - ignore_column :clientside_sentry_enabled - ignore_column :clientside_sentry_dsn + self.ignored_columns = %i[ + clientside_sentry_dsn + clientside_sentry_enabled + koding_enabled + koding_url + sentry_dsn + sentry_enabled + ] cache_markdown_field :sign_in_text cache_markdown_field :help_page_text diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 7930bef5cf2..6ff89666e53 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -11,19 +11,20 @@ module Ci include ObjectStorage::BackgroundMove include Presentable include Importable - include IgnorableColumn include Gitlab::Utils::StrongMemoize include Deployable include HasRef BuildArchivedError = Class.new(StandardError) - ignore_column :commands - ignore_column :artifacts_file - ignore_column :artifacts_metadata - ignore_column :artifacts_file_store - ignore_column :artifacts_metadata_store - ignore_column :artifacts_size + self.ignored_columns = %i[ + artifacts_file + artifacts_file_store + artifacts_metadata + artifacts_metadata_store + artifacts_size + commands + ] belongs_to :project, inverse_of: :builds belongs_to :runner diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index 1c1c7a5ae7a..e0e905ebfa8 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -4,7 +4,6 @@ module Ci class Runner < ApplicationRecord extend Gitlab::Ci::Model include Gitlab::SQL::Pattern - include IgnorableColumn include RedisCacheable include ChronicDurationAttribute include FromUnion @@ -36,7 +35,7 @@ module Ci FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze - ignore_column :is_shared + self.ignored_columns = %i[is_shared] has_many :builds has_many :runner_projects, inverse_of: :runner, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent diff --git a/app/models/concerns/ignorable_column.rb b/app/models/concerns/ignorable_column.rb deleted file mode 100644 index 3bec44dc79b..00000000000 --- a/app/models/concerns/ignorable_column.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -# Module that can be included into a model to make it easier to ignore database -# columns. -# -# Example: -# -# class User < ApplicationRecord -# include IgnorableColumn -# -# ignore_column :updated_at -# end -# -module IgnorableColumn - extend ActiveSupport::Concern - - class_methods do - def columns - super.reject { |column| ignored_columns.include?(column.name) } - end - - def ignored_columns - @ignored_columns ||= Set.new - end - - def ignore_column(*names) - ignored_columns.merge(names.map(&:to_s)) - end - end -end diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb index 0bd90bd28e3..06f8f31b8cc 100644 --- a/app/models/deploy_key.rb +++ b/app/models/deploy_key.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class DeployKey < Key - include IgnorableColumn include FromUnion has_many :deploy_keys_projects, inverse_of: :deploy_key, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent @@ -11,7 +10,7 @@ class DeployKey < Key scope :are_public, -> { where(public: true) } scope :with_projects, -> { includes(deploy_keys_projects: { project: [:route, :namespace] }) } - ignore_column :can_push + self.ignored_columns = %i[can_push] accepts_nested_attributes_for :deploy_keys_projects diff --git a/app/models/event.rb b/app/models/event.rb index 738080eb584..392d7368033 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -2,7 +2,6 @@ class Event < ApplicationRecord include Sortable - include IgnorableColumn include FromUnion default_scope { reorder(nil) } diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb index 2c9dbf2585c..2402fa8e38f 100644 --- a/app/models/merge_request_diff.rb +++ b/app/models/merge_request_diff.rb @@ -4,7 +4,6 @@ class MergeRequestDiff < ApplicationRecord include Sortable include Importable include ManualInverseAssociation - include IgnorableColumn include EachBatch include Gitlab::Utils::StrongMemoize include ObjectStorage::BackgroundMove diff --git a/app/models/note.rb b/app/models/note.rb index a12d1eb7243..c6ef91a27ad 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -14,7 +14,6 @@ class Note < ApplicationRecord include CacheMarkdownField include AfterCommitQueue include ResolvableNote - include IgnorableColumn include Editable include Gitlab::SQL::Pattern include ThrottledTouch @@ -34,7 +33,7 @@ class Note < ApplicationRecord end end - ignore_column :original_discussion_id + self.ignored_columns = %i[original_discussion_id] cache_markdown_field :note, pipeline: :note, issuable_state_filter_enabled: true diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index 8306b11a7b6..9882f1dc8b3 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -1,9 +1,8 @@ # frozen_string_literal: true class NotificationSetting < ApplicationRecord - include IgnorableColumn - ignore_column :events + self.ignored_columns = %i[events] enum level: { global: 3, watch: 2, participating: 1, mention: 4, disabled: 0, custom: 5 } diff --git a/app/models/user.rb b/app/models/user.rb index 6107aaa7fca..79c89461806 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -13,7 +13,6 @@ class User < ApplicationRecord include Sortable include CaseSensitivity include TokenAuthenticatable - include IgnorableColumn include FeatureGate include CreatedAtFilterable include BulkMemberAccessLoad @@ -24,9 +23,11 @@ class User < ApplicationRecord DEFAULT_NOTIFICATION_LEVEL = :participating - ignore_column :external_email - ignore_column :email_provider - ignore_column :authentication_token + self.ignored_columns = %i[ + authentication_token + email_provider + external_email + ] add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) } add_authentication_token_field :feed_token -- cgit v1.2.1 From 739d6a5ad3ac3756d89d6d07fec5fb876aa333d6 Mon Sep 17 00:00:00 2001 From: Andreas Brandl Date: Tue, 27 Aug 2019 15:29:53 +0200 Subject: Perform two-step Routable lookup by path In order to lookup a Project or Namespace by path, we prefer an exact match (case-sensitive) but in absence of that, we'd also take a case-insensitive match. The case-insensitive matching with preference for the exact match is a bit more involved in SQL as the exact lookup. Yet, the majority of cases will be an exact match. The thinking here is that we can optimize the lookup by performing an exact match first and only if there is no result, we perform the case-insensitive lookup. Data for GitLab.com: * We have about 15M records in routes table * About 2,500 routes exist where there's more than one record with the same `lower(path)` It is possible for a user to craft requests that would always trigger the 2-step search (e.g. we have a route for `/foo/bar`, the request is always for `/FOO/bar`). In this case, the change at hand is not beneficial as it would run an additional query. However, based on the data, it is highly likely that the vast majority of requests can be satisfied with an exact match only. The context for this change is https://gitlab.com/gitlab-org/gitlab-ce/issues/64590#note_208156463. --- app/models/concerns/routable.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'app/models') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 116e8967651..115c3ce2f91 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -33,8 +33,15 @@ module Routable # # Returns a single object, or nil. def find_by_full_path(path, follow_redirects: false) - order_sql = Arel.sql("(CASE WHEN routes.path = #{connection.quote(path)} THEN 0 ELSE 1 END)") - found = where_full_path_in([path]).reorder(order_sql).take + if Feature.enabled?(:routable_two_step_lookup) + # Case sensitive match first (it's cheaper and the usual case) + # If we didn't have an exact match, we perform a case insensitive search + found = joins(:route).find_by(routes: { path: path }) || where_full_path_in([path]).take + else + order_sql = Arel.sql("(CASE WHEN routes.path = #{connection.quote(path)} THEN 0 ELSE 1 END)") + found = where_full_path_in([path]).reorder(order_sql).take + end + return found if found if follow_redirects -- cgit v1.2.1 From 1003cd92cbaf9df12bf01b85c16c8dabdb1a8b72 Mon Sep 17 00:00:00 2001 From: Andreas Brandl Date: Thu, 29 Aug 2019 13:51:00 +0200 Subject: Add method call count instrumentation --- app/models/concerns/routable.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'app/models') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 115c3ce2f91..01b853d413c 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -59,12 +59,23 @@ module Routable def where_full_path_in(paths) return none if paths.empty? + increment_full_path_in_counter + wheres = paths.map do |path| "(LOWER(routes.path) = LOWER(#{connection.quote(path)}))" end joins(:route).where(wheres.join(' OR ')) end + + # Temporary instrumentation of method calls for .where_full_path_in + def increment_full_path_in_counter + @counter ||= Gitlab::Metrics.counter(:routable_caseinsensitive_lookup_calls, 'Number of calls to Routable.where_full_path_in') + + @counter.increment + rescue + # ignore the error + end end def full_name -- cgit v1.2.1 From 8501e13bbc5f423b90c0ebbf20da90801a6fa410 Mon Sep 17 00:00:00 2001 From: Juliette de Rancourt Date: Fri, 30 Aug 2019 06:16:01 +0000 Subject: Resolve "Use "moved" instead of "closed" in issue references" --- app/models/issue.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/models') diff --git a/app/models/issue.rb b/app/models/issue.rb index caea8eadd18..75d4fc8c1c5 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -178,7 +178,7 @@ class Issue < ApplicationRecord end def moved? - !moved_to.nil? + !moved_to_id.nil? end def can_move?(user, to_project = nil) -- cgit v1.2.1 From edde1b708a6a605185a6dde73550b9f45e673371 Mon Sep 17 00:00:00 2001 From: Andreas Brandl Date: Fri, 30 Aug 2019 11:50:26 +0200 Subject: Add another counter to calculate method call ratio We should see the ratio drop down when enabling the Feature. Recommendation by @andrewn --- app/models/concerns/routable.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'app/models') diff --git a/app/models/concerns/routable.rb b/app/models/concerns/routable.rb index 01b853d413c..3a486632800 100644 --- a/app/models/concerns/routable.rb +++ b/app/models/concerns/routable.rb @@ -33,6 +33,8 @@ module Routable # # Returns a single object, or nil. def find_by_full_path(path, follow_redirects: false) + increment_counter(:routable_find_by_full_path, 'Number of calls to Routable.find_by_full_path') + if Feature.enabled?(:routable_two_step_lookup) # Case sensitive match first (it's cheaper and the usual case) # If we didn't have an exact match, we perform a case insensitive search @@ -59,7 +61,7 @@ module Routable def where_full_path_in(paths) return none if paths.empty? - increment_full_path_in_counter + increment_counter(:routable_where_full_path_in, 'Number of calls to Routable.where_full_path_in') wheres = paths.map do |path| "(LOWER(routes.path) = LOWER(#{connection.quote(path)}))" @@ -68,11 +70,11 @@ module Routable joins(:route).where(wheres.join(' OR ')) end - # Temporary instrumentation of method calls for .where_full_path_in - def increment_full_path_in_counter - @counter ||= Gitlab::Metrics.counter(:routable_caseinsensitive_lookup_calls, 'Number of calls to Routable.where_full_path_in') + # Temporary instrumentation of method calls + def increment_counter(counter, description) + @counters[counter] ||= Gitlab::Metrics.counter(counter, description) - @counter.increment + @counters[counter].increment rescue # ignore the error end -- cgit v1.2.1 From 5142bd738e7de37991ab8c43a3096ef232363110 Mon Sep 17 00:00:00 2001 From: James Fargher Date: Fri, 30 Aug 2019 11:47:13 +0000 Subject: Install cert-manager v0.9.1 This does not support upgrading from earlier versions --- app/models/clusters/applications/cert_manager.rb | 33 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'app/models') diff --git a/app/models/clusters/applications/cert_manager.rb b/app/models/clusters/applications/cert_manager.rb index 6bd7473c8ff..27d4180e5b9 100644 --- a/app/models/clusters/applications/cert_manager.rb +++ b/app/models/clusters/applications/cert_manager.rb @@ -3,7 +3,8 @@ module Clusters module Applications class CertManager < ApplicationRecord - VERSION = 'v0.5.2'.freeze + VERSION = 'v0.9.1' + CRD_VERSION = '0.9' self.table_name = 'clusters_applications_cert_managers' @@ -21,16 +22,22 @@ module Clusters validates :email, presence: true def chart - 'stable/cert-manager' + 'certmanager/cert-manager' + end + + def repository + 'https://charts.jetstack.io' end def install_command Gitlab::Kubernetes::Helm::InstallCommand.new( name: 'certmanager', + repository: repository, version: VERSION, rbac: cluster.platform_kubernetes_rbac?, chart: chart, files: files.merge(cluster_issuer_file), + preinstall: pre_install_script, postinstall: post_install_script ) end @@ -46,16 +53,30 @@ module Clusters private + def pre_install_script + [ + apply_file("https://raw.githubusercontent.com/jetstack/cert-manager/release-#{CRD_VERSION}/deploy/manifests/00-crds.yaml"), + "kubectl label --overwrite namespace #{Gitlab::Kubernetes::Helm::NAMESPACE} certmanager.k8s.io/disable-validation=true" + ] + end + def post_install_script - ["kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml"] + [retry_command(apply_file('/data/helm/certmanager/config/cluster_issuer.yaml'))] + end + + def retry_command(command) + "for i in $(seq 1 30); do #{command} && break; sleep 1s; echo \"Retrying ($i)...\"; done" end def post_delete_script [ delete_private_key, delete_crd('certificates.certmanager.k8s.io'), + delete_crd('certificaterequests.certmanager.k8s.io'), + delete_crd('challenges.certmanager.k8s.io'), delete_crd('clusterissuers.certmanager.k8s.io'), - delete_crd('issuers.certmanager.k8s.io') + delete_crd('issuers.certmanager.k8s.io'), + delete_crd('orders.certmanager.k8s.io') ].compact end @@ -75,6 +96,10 @@ module Clusters Gitlab::Kubernetes::KubectlCmd.delete("crd", definition, "--ignore-not-found") end + def apply_file(filename) + Gitlab::Kubernetes::KubectlCmd.apply_file(filename) + end + def cluster_issuer_file { 'cluster_issuer.yaml': cluster_issuer_yaml_content -- cgit v1.2.1 From d93b985df07ccf07541efef709edb8467e0f2955 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 29 Aug 2019 16:10:49 -0700 Subject: Use self.ignored_columns += instead of = This is to accomodate prepended modules. --- app/models/application_setting.rb | 16 ++++++++-------- app/models/ci/build.rb | 16 ++++++++-------- app/models/deploy_key.rb | 2 +- app/models/note.rb | 2 +- app/models/notification_setting.rb | 3 +-- app/models/user.rb | 10 +++++----- 6 files changed, 24 insertions(+), 25 deletions(-) (limited to 'app/models') diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 8ff4cba2adb..46259abf1b6 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -24,14 +24,14 @@ class ApplicationSetting < ApplicationRecord serialize :domain_blacklist, Array # rubocop:disable Cop/ActiveRecordSerialize serialize :repository_storages # rubocop:disable Cop/ActiveRecordSerialize - self.ignored_columns = %i[ - clientside_sentry_dsn - clientside_sentry_enabled - koding_enabled - koding_url - sentry_dsn - sentry_enabled - ] + self.ignored_columns += %i[ + clientside_sentry_dsn + clientside_sentry_enabled + koding_enabled + koding_url + sentry_dsn + sentry_enabled + ] cache_markdown_field :sign_in_text cache_markdown_field :help_page_text diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 6ff89666e53..79a2d5e6e9d 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -17,14 +17,14 @@ module Ci BuildArchivedError = Class.new(StandardError) - self.ignored_columns = %i[ - artifacts_file - artifacts_file_store - artifacts_metadata - artifacts_metadata_store - artifacts_size - commands - ] + self.ignored_columns += %i[ + artifacts_file + artifacts_file_store + artifacts_metadata + artifacts_metadata_store + artifacts_size + commands + ] belongs_to :project, inverse_of: :builds belongs_to :runner diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb index 06f8f31b8cc..22ab326a0ab 100644 --- a/app/models/deploy_key.rb +++ b/app/models/deploy_key.rb @@ -10,7 +10,7 @@ class DeployKey < Key scope :are_public, -> { where(public: true) } scope :with_projects, -> { includes(deploy_keys_projects: { project: [:route, :namespace] }) } - self.ignored_columns = %i[can_push] + self.ignored_columns += %i[can_push] accepts_nested_attributes_for :deploy_keys_projects diff --git a/app/models/note.rb b/app/models/note.rb index c6ef91a27ad..2a0063c76b0 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -33,7 +33,7 @@ class Note < ApplicationRecord end end - self.ignored_columns = %i[original_discussion_id] + self.ignored_columns += %i[original_discussion_id] cache_markdown_field :note, pipeline: :note, issuable_state_filter_enabled: true diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index 9882f1dc8b3..637c017a342 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true class NotificationSetting < ApplicationRecord - - self.ignored_columns = %i[events] + self.ignored_columns += %i[events] enum level: { global: 3, watch: 2, participating: 1, mention: 4, disabled: 0, custom: 5 } diff --git a/app/models/user.rb b/app/models/user.rb index 79c89461806..cb222b87d88 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -23,11 +23,11 @@ class User < ApplicationRecord DEFAULT_NOTIFICATION_LEVEL = :participating - self.ignored_columns = %i[ - authentication_token - email_provider - external_email - ] + self.ignored_columns += %i[ + authentication_token + email_provider + external_email + ] add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) } add_authentication_token_field :feed_token -- cgit v1.2.1 From b943baa42a5365bd6377022223f66db9af58da33 Mon Sep 17 00:00:00 2001 From: Manoj MJ Date: Fri, 30 Aug 2019 21:30:51 +0000 Subject: Limit access request email to 10 most recently active owners/maintainers This change limits the number of emails for new access requests notifications to 10 most recently active owners/maintainers --- app/models/group.rb | 6 ++++++ app/models/project.rb | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'app/models') diff --git a/app/models/group.rb b/app/models/group.rb index 61a4802a6ee..abe93cf3c84 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -15,6 +15,8 @@ class Group < Namespace include WithUploads include Gitlab::Utils::StrongMemoize + ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10 + has_many :group_members, -> { where(requested_at: nil) }, dependent: :destroy, as: :source # rubocop:disable Cop/ActiveRecordDependent alias_method :members, :group_members has_many :users, through: :group_members @@ -429,6 +431,10 @@ class Group < Namespace super || ::Gitlab::Access::OWNER_SUBGROUP_ACCESS end + def access_request_approvers_to_be_notified + members.owners.order_recent_sign_in.limit(ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT) + end + private def update_two_factor_requirement diff --git a/app/models/project.rb b/app/models/project.rb index 8f568a5b840..a6d203f1e72 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -55,6 +55,8 @@ class Project < ApplicationRecord VALID_MIRROR_PORTS = [22, 80, 443].freeze VALID_MIRROR_PROTOCOLS = %w(http https ssh git).freeze + ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10 + SORTING_PREFERENCE_FIELD = :projects_sort cache_markdown_field :description, pipeline: :description @@ -2193,6 +2195,10 @@ class Project < ApplicationRecord pool_repository.present? end + def access_request_approvers_to_be_notified + members.maintainers.order_recent_sign_in.limit(ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT) + end + private def merge_requests_allowing_collaboration(source_branch = nil) -- cgit v1.2.1