diff options
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/application_setting.rb | 26 | ||||
-rw-r--r-- | app/models/application_setting_implementation.rb | 28 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 1 | ||||
-rw-r--r-- | app/models/concerns/issuable.rb | 1 | ||||
-rw-r--r-- | app/models/group.rb | 2 | ||||
-rw-r--r-- | app/models/issue.rb | 2 | ||||
-rw-r--r-- | app/models/label.rb | 8 | ||||
-rw-r--r-- | app/models/note.rb | 5 | ||||
-rw-r--r-- | app/models/project.rb | 2 | ||||
-rw-r--r-- | app/models/project_services/jira_service.rb | 7 | ||||
-rw-r--r-- | app/models/remote_mirror.rb | 1 | ||||
-rw-r--r-- | app/models/repository.rb | 12 | ||||
-rw-r--r-- | app/models/system_note_metadata.rb | 2 | ||||
-rw-r--r-- | app/models/user.rb | 7 |
14 files changed, 81 insertions, 23 deletions
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 2a99c6e5c59..d6caf092ed0 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 @@ -75,11 +82,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, @@ -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 @@ -292,4 +310,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 55ac1e129cf..f402c0e2775 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,7 +68,10 @@ 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, + login_recaptcha_protection_enabled: false, repository_checks_enabled: true, repository_storages: ['default'], require_two_factor_authentication: false, @@ -95,16 +103,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 +200,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 +317,7 @@ module ApplicationSettingImplementation values .split(DOMAIN_LIST_SEPARATOR) + .map(&:strip) .reject(&:empty?) .uniq end 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) diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index db46d7afbb9..eefe9f00836 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/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 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) diff --git a/app/models/label.rb b/app/models/label.rb index d9455b36242..dc9f0a3d1a9 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -199,7 +199,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 ## @@ -260,7 +264,7 @@ class Label < ApplicationRecord end end - def sanitize_title(value) + def sanitize_value(value) CGI.unescapeHTML(Sanitize.clean(value.to_s)) end diff --git a/app/models/note.rb b/app/models/note.rb index a12d1eb7243..3956ec192b1 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 @@ -331,6 +332,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 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 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 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! 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 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[ diff --git a/app/models/user.rb b/app/models/user.rb index 6107aaa7fca..9952bc7e1ad 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -645,6 +645,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')) |