diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-16 06:09:14 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-16 06:09:14 +0300 |
commit | 78fe72d153260c355fdfd533b125026cce310da7 (patch) | |
tree | 0d90106443bea87cc24e2834273ae6c8dcac0260 | |
parent | 88797b994a7dfd9bfab2a5d5431f088f17078b9f (diff) |
Add latest changes from gitlab-org/gitlab@master
88 files changed, 374 insertions, 395 deletions
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb index d1a919fc01a..5ad382d8670 100644 --- a/app/models/application_setting_implementation.rb +++ b/app/models/application_setting_implementation.rb @@ -361,18 +361,33 @@ module ApplicationSettingImplementation def separate_whitelists(string_array) string_array.reduce([[], []]) do |(ip_whitelist, domain_whitelist), string| - ip_obj = Gitlab::Utils.string_to_ip_object(string) + address, port = parse_addr_and_port(string) + + ip_obj = Gitlab::Utils.string_to_ip_object(address) if ip_obj - ip_whitelist << ip_obj + ip_whitelist << Gitlab::UrlBlockers::IpWhitelistEntry.new(ip_obj, port: port) else - domain_whitelist << string + domain_whitelist << Gitlab::UrlBlockers::DomainWhitelistEntry.new(address, port: port) end [ip_whitelist, domain_whitelist] end end + def parse_addr_and_port(str) + case str + when /\A\[(?<address> .* )\]:(?<port> \d+ )\z/x # string like "[::1]:80" + address, port = $~[:address], $~[:port] + when /\A(?<address> [^:]+ ):(?<port> \d+ )\z/x # string like "127.0.0.1:80" + address, port = $~[:address], $~[:port] + else # string with no port number + address, port = str, nil + end + + [address, port&.to_i] + end + def array_to_string(arr) arr&.join("\n") end diff --git a/app/uploaders/upload_type_check.rb b/app/uploaders/upload_type_check.rb deleted file mode 100644 index 2837b001660..00000000000 --- a/app/uploaders/upload_type_check.rb +++ /dev/null @@ -1,98 +0,0 @@ -# frozen_string_literal: true - -# Ensure that uploaded files are what they say they are for security and -# handling purposes. The checks are not 100% reliable so we err on the side of -# caution and allow by default, and deny when we're confident of a fail state. -# -# Include this concern, then call `check_upload_type` to check all -# uploads. Attach a `mime_type` or `extensions` parameter to only check -# specific upload types. Both parameters will be normalized to a MIME type and -# checked against the inferred MIME type of the upload content and filename -# extension. -# -# class YourUploader -# include UploadTypeCheck::Concern -# check_upload_type mime_types: ['image/png', /image\/jpe?g/] -# -# # or... -# -# check_upload_type extensions: ['png', 'jpg', 'jpeg'] -# end -# -# The mime_types parameter can accept `NilClass`, `String`, `Regexp`, -# `Array[String, Regexp]`. This matches the CarrierWave `extension_whitelist` -# and `content_type_whitelist` family of behavior. -# -# The extensions parameter can accept `NilClass`, `String`, `Array[String]`. -module UploadTypeCheck - module Concern - extend ActiveSupport::Concern - - class_methods do - def check_upload_type(mime_types: nil, extensions: nil) - define_method :check_upload_type_callback do |file| - magic_file = MagicFile.new(file.to_file) - - # Map file extensions back to mime types. - if extensions - mime_types = Array(mime_types) + - Array(extensions).map { |e| MimeMagic::EXTENSIONS[e] } - end - - if mime_types.nil? || magic_file.matches_mime_types?(mime_types) - check_content_matches_extension!(magic_file) - end - end - before :cache, :check_upload_type_callback - end - end - - def check_content_matches_extension!(magic_file) - return if magic_file.ambiguous_type? - - if magic_file.magic_type != magic_file.ext_type - raise CarrierWave::IntegrityError, 'Content type does not match file extension' - end - end - end - - # Convenience class to wrap MagicMime objects. - class MagicFile - attr_reader :file - - def initialize(file) - @file = file - end - - def magic_type - @magic_type ||= MimeMagic.by_magic(file) - end - - def ext_type - @ext_type ||= MimeMagic.by_path(file.path) - end - - def magic_type_type - magic_type&.type - end - - def ext_type_type - ext_type&.type - end - - def matches_mime_types?(mime_types) - Array(mime_types).any? do |mt| - magic_type_type =~ /\A#{mt}\z/ || ext_type_type =~ /\A#{mt}\z/ - end - end - - # - Both types unknown or text/plain. - # - Ambiguous magic type with text extension. Plain text file. - # - Text magic type with ambiguous extension. TeX file missing extension. - def ambiguous_type? - (ext_type.to_s.blank? && magic_type.to_s.blank?) || - (magic_type.to_s.blank? && ext_type_type == 'text/plain') || - (ext_type.to_s.blank? && magic_type_type == 'text/plain') - end - end -end diff --git a/changelogs/unreleased/199220-snippet-search.yml b/changelogs/unreleased/199220-snippet-search.yml index d9ba1c6a626..d0b17fd3135 100644 --- a/changelogs/unreleased/199220-snippet-search.yml +++ b/changelogs/unreleased/199220-snippet-search.yml @@ -1,5 +1,5 @@ --- -title: Include snippet description as part of snippet title search (when Elasticsearch is not enabled) +title: Include snippet description as part of snippet title search (basic search). merge_request: 25961 author: type: added diff --git a/changelogs/unreleased/rc-whitelist_ports.yml b/changelogs/unreleased/rc-whitelist_ports.yml new file mode 100644 index 00000000000..d3e3bdc1b7a --- /dev/null +++ b/changelogs/unreleased/rc-whitelist_ports.yml @@ -0,0 +1,5 @@ +--- +title: Add ability to whitelist ports +merge_request: 27025 +author: +type: added diff --git a/doc/administration/gitaly/img/praefect_architecture_v12_9.png b/doc/administration/gitaly/img/praefect_architecture_v12_9.png Binary files differindex 3937789094c..b68e495cb17 100644 --- a/doc/administration/gitaly/img/praefect_architecture_v12_9.png +++ b/doc/administration/gitaly/img/praefect_architecture_v12_9.png diff --git a/doc/administration/operations/unicorn.md b/doc/administration/operations/unicorn.md index 561cd7ac1ce..bab20a76546 100644 --- a/doc/administration/operations/unicorn.md +++ b/doc/administration/operations/unicorn.md @@ -65,7 +65,7 @@ maximum memory threshold (in bytes) for the Unicorn worker killer by setting the following values `/etc/gitlab/gitlab.rb`: - For GitLab **12.7** and newer: - + ```ruby unicorn['worker_memory_limit_min'] = "1024 * 1 << 20" unicorn['worker_memory_limit_max'] = "1280 * 1 << 20" diff --git a/doc/administration/packages/index.md b/doc/administration/packages/index.md index a12aec3c7b3..40867fc15b6 100644 --- a/doc/administration/packages/index.md +++ b/doc/administration/packages/index.md @@ -118,10 +118,10 @@ upload packages: #'path_style' => false # If true, use 'host/bucket_name/object' instead of 'bucket_name.host/object'. } ``` - + NOTE: **Note:** Some build tools, like Gradle, must make `HEAD` requests to Amazon S3 to pull a dependency’s metadata. The `gitlab_rails['packages_object_store_proxy_download']` property must be set to `true`. Without this setting, GitLab won't act as a proxy to the Amazon S3 service, and will instead return the signed URL. This will cause a `HTTP 403 Forbidden` response, since Amazon S3 expects a signed URL. - + 1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. diff --git a/doc/administration/troubleshooting/gdb-stuck-ruby.txt b/doc/administration/troubleshooting/gdb-stuck-ruby.txt index 13d5dfcffa4..de8d704f9e3 100644 --- a/doc/administration/troubleshooting/gdb-stuck-ruby.txt +++ b/doc/administration/troubleshooting/gdb-stuck-ruby.txt @@ -1,6 +1,6 @@ # Here's the script I'll use to demonstrate - it just loops forever: -$ cat test.rb +$ cat test.rb #!/usr/bin/env ruby loop do @@ -75,7 +75,7 @@ Thread 1 (Thread 0xb74d76c0 (LWP 1343)): at eval.c:5778 #5 rb_call0 (klass=3075304600, recv=3075299660, id=9393, oid=9393, argc=1, argv=0xbf85f490, body=0xb74c85a8, flags=2) at eval.c:5928 -#6 0x0805e35d in rb_call (klass=3075304600, recv=3075299660, mid=9393, argc=1, argv=0xbf85f490, scope=1, +#6 0x0805e35d in rb_call (klass=3075304600, recv=3075299660, mid=9393, argc=1, argv=0xbf85f490, scope=1, self=<optimized out>) at eval.c:6176 #7 0x080651ec in rb_eval (self=3075299660, n=0xb74c4e1c) at eval.c:3521 #8 0x0805c31c in rb_yield_0 (val=6, self=3075299660, klass=<optimized out>, flags=0, avalue=0) at eval.c:5095 @@ -139,4 +139,4 @@ A debugging session is active. Quit anyway? (y or n) y Detaching from program: /opt/vagrant_ruby/bin/ruby, process 1343 -$ +$ diff --git a/doc/administration/troubleshooting/img/AzureAD-basic_SAML.png b/doc/administration/troubleshooting/img/AzureAD-basic_SAML.png Binary files differindex a553dc182ce..e86ad7572e8 100644 --- a/doc/administration/troubleshooting/img/AzureAD-basic_SAML.png +++ b/doc/administration/troubleshooting/img/AzureAD-basic_SAML.png diff --git a/doc/administration/troubleshooting/img/AzureAD-claims.png b/doc/administration/troubleshooting/img/AzureAD-claims.png Binary files differindex ef594390ce0..aab92288704 100644 --- a/doc/administration/troubleshooting/img/AzureAD-claims.png +++ b/doc/administration/troubleshooting/img/AzureAD-claims.png diff --git a/doc/administration/troubleshooting/img/OneLogin-SSOsettings.png b/doc/administration/troubleshooting/img/OneLogin-SSOsettings.png Binary files differindex 72737b9a017..58f936d8567 100644 --- a/doc/administration/troubleshooting/img/OneLogin-SSOsettings.png +++ b/doc/administration/troubleshooting/img/OneLogin-SSOsettings.png diff --git a/doc/administration/troubleshooting/img/OneLogin-app_details.png b/doc/administration/troubleshooting/img/OneLogin-app_details.png Binary files differindex 3e36a001d1b..77618960897 100644 --- a/doc/administration/troubleshooting/img/OneLogin-app_details.png +++ b/doc/administration/troubleshooting/img/OneLogin-app_details.png diff --git a/doc/administration/troubleshooting/img/OneLogin-encryption.png b/doc/administration/troubleshooting/img/OneLogin-encryption.png Binary files differindex a1b90873a5a..2b811409bd0 100644 --- a/doc/administration/troubleshooting/img/OneLogin-encryption.png +++ b/doc/administration/troubleshooting/img/OneLogin-encryption.png diff --git a/doc/administration/troubleshooting/img/OneLogin-parameters.png b/doc/administration/troubleshooting/img/OneLogin-parameters.png Binary files differindex c9ff4f8f018..a2fa734152c 100644 --- a/doc/administration/troubleshooting/img/OneLogin-parameters.png +++ b/doc/administration/troubleshooting/img/OneLogin-parameters.png diff --git a/doc/administration/troubleshooting/img/OneLogin-userAdd.png b/doc/administration/troubleshooting/img/OneLogin-userAdd.png Binary files differindex c7187fe5dd6..54c1ecd2e68 100644 --- a/doc/administration/troubleshooting/img/OneLogin-userAdd.png +++ b/doc/administration/troubleshooting/img/OneLogin-userAdd.png diff --git a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md index 38c0661da06..ec59705ca99 100644 --- a/doc/administration/troubleshooting/kubernetes_cheat_sheet.md +++ b/doc/administration/troubleshooting/kubernetes_cheat_sheet.md @@ -77,11 +77,11 @@ and they will assist you with any issues you are having. ```shell kubectl get cronjobs ``` - + When one configures [cron-based backups](https://docs.gitlab.com/charts/backup-restore/backup.html#cron-based-backup), you will be able to see the new schedule here. Some details about the schedules can be found in [Running Automated Tasks with a CronJob](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#creating-a-cron-job) - + ## GitLab-specific Kubernetes information - Minimal config that can be used to test a Kubernetes Helm chart can be found @@ -167,7 +167,7 @@ and they will assist you with any issues you are having. ```shell kubectl exec -it <task-runner-pod-name> -- /srv/gitlab/bin/rails dbconsole -p ``` - + - How to get info about Helm installation status: ```shell diff --git a/doc/ci/environments/img/incremental_rollouts_play_v12_7.png b/doc/ci/environments/img/incremental_rollouts_play_v12_7.png Binary files differindex 314c4a07af0..9d3ca258b08 100644 --- a/doc/ci/environments/img/incremental_rollouts_play_v12_7.png +++ b/doc/ci/environments/img/incremental_rollouts_play_v12_7.png diff --git a/doc/ci/environments/img/timed_rollout_v12_7.png b/doc/ci/environments/img/timed_rollout_v12_7.png Binary files differindex 6b83bfc574e..94f5d50020f 100644 --- a/doc/ci/environments/img/timed_rollout_v12_7.png +++ b/doc/ci/environments/img/timed_rollout_v12_7.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select_template_v12_6.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select_template_v12_6.png Binary files differindex 97887db4486..c8c5e152a13 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select_template_v12_6.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/select_template_v12_6.png diff --git a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/set_up_ci_v12_6.png b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/set_up_ci_v12_6.png Binary files differindex 85fb58d4458..fafabb27bac 100644 --- a/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/set_up_ci_v12_6.png +++ b/doc/ci/examples/test_phoenix_app_with_gitlab_ci_cd/img/set_up_ci_v12_6.png diff --git a/doc/ci/img/environment_auto_stop_v12_8.png b/doc/ci/img/environment_auto_stop_v12_8.png Binary files differindex 3a3c54ab62d..f098938ef04 100644 --- a/doc/ci/img/environment_auto_stop_v12_8.png +++ b/doc/ci/img/environment_auto_stop_v12_8.png diff --git a/doc/ci/img/environments_deployment_cluster_v12_8.png b/doc/ci/img/environments_deployment_cluster_v12_8.png Binary files differindex dfda1deb649..7fa6d3515a8 100644 --- a/doc/ci/img/environments_deployment_cluster_v12_8.png +++ b/doc/ci/img/environments_deployment_cluster_v12_8.png diff --git a/doc/ci/img/parent_pipeline_graph_expanded_v12_6.png b/doc/ci/img/parent_pipeline_graph_expanded_v12_6.png Binary files differindex 5c493109a54..db18cc201fc 100644 --- a/doc/ci/img/parent_pipeline_graph_expanded_v12_6.png +++ b/doc/ci/img/parent_pipeline_graph_expanded_v12_6.png diff --git a/doc/ci/pipelines/img/collapsible_log_v12_6.png b/doc/ci/pipelines/img/collapsible_log_v12_6.png Binary files differindex 24b2c83f7c1..a1e9aeb244a 100644 --- a/doc/ci/pipelines/img/collapsible_log_v12_6.png +++ b/doc/ci/pipelines/img/collapsible_log_v12_6.png diff --git a/doc/ci/pipelines/img/pipelines_duration_chart.png b/doc/ci/pipelines/img/pipelines_duration_chart.png Binary files differindex 0be7539ba0a..12ec262dadb 100644 --- a/doc/ci/pipelines/img/pipelines_duration_chart.png +++ b/doc/ci/pipelines/img/pipelines_duration_chart.png diff --git a/doc/ci/pipelines/img/pipelines_success_chart.png b/doc/ci/pipelines/img/pipelines_success_chart.png Binary files differindex 10602b75eeb..f44dc25ff1c 100644 --- a/doc/ci/pipelines/img/pipelines_success_chart.png +++ b/doc/ci/pipelines/img/pipelines_success_chart.png diff --git a/doc/ci/review_apps/img/enable_review_app_v12_8.png b/doc/ci/review_apps/img/enable_review_app_v12_8.png Binary files differindex 364fe402787..7d40f49725f 100644 --- a/doc/ci/review_apps/img/enable_review_app_v12_8.png +++ b/doc/ci/review_apps/img/enable_review_app_v12_8.png diff --git a/doc/development/event_tracking/frontend.md b/doc/development/event_tracking/frontend.md index 42c82a745db..fcd394500ec 100644 --- a/doc/development/event_tracking/frontend.md +++ b/doc/development/event_tracking/frontend.md @@ -149,12 +149,12 @@ import { mockTracking, triggerEvent } from 'spec/helpers/tracking_helper'; describe('my component', () => { let trackingSpy; - + beforeEach(() => { const vm = mountComponent(MyComponent); trackingSpy = mockTracking('_category_', vm.$el, spyOn); }); - + it('tracks an event when toggled', () => { triggerEvent('a.toggle'); diff --git a/doc/development/img/reference_architecture.png b/doc/development/img/reference_architecture.png Binary files differindex 1414200d076..107135b626e 100644 --- a/doc/development/img/reference_architecture.png +++ b/doc/development/img/reference_architecture.png diff --git a/doc/development/import_export.md b/doc/development/import_export.md index 252a57ce857..68f7b78337d 100644 --- a/doc/development/import_export.md +++ b/doc/development/import_export.md @@ -195,17 +195,17 @@ module Gitlab The [current version history](../user/project/settings/import_export.md) also displays the equivalent GitLab version and it is useful for knowing which versions won't be compatible between them. -| Exporting GitLab version | Importing GitLab version | -| -------------------------- | -------------------------- | -| 11.7 to current | 11.7 to current | -| 11.1 to 11.6 | 11.1 to 11.6 | -| 10.8 to 11.0 | 10.8 to 11.0 | -| 10.4 to 10.7 | 10.4 to 10.7 | -| ... | ... | -| 8.10.3 to 8.11 | 8.10.3 to 8.11 | -| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 | -| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 | -| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 | +| Exporting GitLab version | Importing GitLab version | +| -------------------------- | -------------------------- | +| 11.7 to current | 11.7 to current | +| 11.1 to 11.6 | 11.1 to 11.6 | +| 10.8 to 11.0 | 10.8 to 11.0 | +| 10.4 to 10.7 | 10.4 to 10.7 | +| ... | ... | +| 8.10.3 to 8.11 | 8.10.3 to 8.11 | +| 8.10.0 to 8.10.2 | 8.10.0 to 8.10.2 | +| 8.9.5 to 8.9.11 | 8.9.5 to 8.9.11 | +| 8.9.0 to 8.9.4 | 8.9.0 to 8.9.4 | ### When to bump the version up diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md index 74e16751b31..5792ce303e1 100644 --- a/doc/development/integrations/secure.md +++ b/doc/development/integrations/secure.md @@ -278,7 +278,7 @@ and where the `message` repeats the `location` field: It takes around 50k characters to block for 2 seconds making this a low severity issue." } ``` - + The `description` might explain how the vulnerability works or give context about the exploit. It should not repeat the other fields of the vulnerability object. In particular, the `description` should not repeat the `location` (what is affected) diff --git a/doc/development/reference_processing.md b/doc/development/reference_processing.md index c6c629f3314..ef1f2f5269c 100644 --- a/doc/development/reference_processing.md +++ b/doc/development/reference_processing.md @@ -43,7 +43,7 @@ Subclasses of `AbstractReferenceFilter` generally do not override `#call`; inste a minimum implementation of `AbstractReferenceFilter` should define: - `.reference_type`: The type of domain object. - + This is usually a keyword, and is used to set the `data-reference-type` attribute on the generated link, and is an important part of the interaction with the corresponding `ReferenceParser` (see below). diff --git a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md index abc7c88b4f2..4f0e506a964 100644 --- a/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md +++ b/doc/development/testing_guide/end_to_end/rspec_metadata_tests.md @@ -6,8 +6,10 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec <!-- Please keep the tags in alphabetical order --> | Tag | Description | -|-|-| -| `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. | -| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify GitLab's configuration (for example, Staging). | -| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), will run in a separate job that only includes quarantined tests, and is allowed to fail. The test will be skipped in its regular job so that if it fails it will not hold up the pipeline. | +|-----|-------------| +| `:elasticsearch` | The test requires an Elasticsearch service. It is used by the [instance-level scenario](https://gitlab.com/gitlab-org/gitlab-qa#definitions) [`Test::Integration::Elasticsearch`](https://gitlab.com/gitlab-org/gitlab/-/blob/72b62b51bdf513e2936301cb6c7c91ec27c35b4d/qa/qa/ee/scenario/test/integration/elasticsearch.rb) to include only tests that require Elasticsearch. | +| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test will also include provisioning of at least one Kubernetes cluster to test against. *This tag is often be paired with `:orchestrated`.* | +| `:orchestrated` | The GitLab instance under test may be [configured by `gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/what_tests_can_be_run.md#orchestrated-tests) to be different to the default GitLab configuration, or `gitlab-qa` may launch additional services in separate docker containers, or both. Tests tagged with `:orchestrated` are excluded when testing environments where we can't dynamically modify GitLab's configuration (for example, Staging). | +| `:quarantine` | The test has been [quarantined](https://about.gitlab.com/handbook/engineering/quality/guidelines/debugging-qa-test-failures/#quarantining-tests), will run in a separate job that only includes quarantined tests, and is allowed to fail. The test will be skipped in its regular job so that if it fails it will not hold up the pipeline. | +| `:reliable` | The test has been [promoted to a reliable test](https://about.gitlab.com/handbook/engineering/quality/guidelines/reliable-tests/#promoting-an-existing-test-to-reliable) meaning it passes consistently in all pipelines, including merge requests. | | `:requires_admin` | The test requires an admin account. Tests with the tag are excluded when run against Canary and Production environments. | diff --git a/doc/install/aws/img/aws_ha_architecture_diagram.png b/doc/install/aws/img/aws_ha_architecture_diagram.png Binary files differindex 4011150a358..2064b0f49ae 100644 --- a/doc/install/aws/img/aws_ha_architecture_diagram.png +++ b/doc/install/aws/img/aws_ha_architecture_diagram.png diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md index c05d8b4b0da..061030765a3 100644 --- a/doc/install/aws/index.md +++ b/doc/install/aws/index.md @@ -543,7 +543,7 @@ If everything looks good, you should be able to reach GitLab in your browser. ### Setting up Gitaly -CAUTION: **Caution:** In this architecture, having a single Gitaly server creates a single point of failure. This limitation will be removed once [Gitaly HA](https://gitlab.com/groups/gitlab-org/-/epics/842) is released. +CAUTION: **Caution:** In this architecture, having a single Gitaly server creates a single point of failure. This limitation will be removed once [Gitaly HA](https://gitlab.com/groups/gitlab-org/-/epics/842) is released. Gitaly is a service that provides high-level RPC access to Git repositories. It should be enabled and configured on a separate EC2 instance in one of the diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md index c2f4fff0ce3..e7667ea8080 100644 --- a/doc/integration/elasticsearch.md +++ b/doc/integration/elasticsearch.md @@ -54,7 +54,7 @@ The way you install the Go indexer depends on your version of GitLab: ### GitLab Omnibus -Since GitLab 11.8 the Go indexer is included in GitLab Omnibus. +Since GitLab 11.8 the Go indexer is included in GitLab Omnibus. The former Ruby-based indexer was removed in [GitLab 12.3](https://gitlab.com/gitlab-org/gitlab/issues/6481). ### From source diff --git a/doc/integration/img/jira_dev_panel_jira_setup_1-1.png b/doc/integration/img/jira_dev_panel_jira_setup_1-1.png Binary files differindex e3c6c01c153..cef903ac9b4 100644 --- a/doc/integration/img/jira_dev_panel_jira_setup_1-1.png +++ b/doc/integration/img/jira_dev_panel_jira_setup_1-1.png diff --git a/doc/integration/img/jira_dev_panel_setup_com_1.png b/doc/integration/img/jira_dev_panel_setup_com_1.png Binary files differindex 906e4aa16cb..18f0d5da043 100644 --- a/doc/integration/img/jira_dev_panel_setup_com_1.png +++ b/doc/integration/img/jira_dev_panel_setup_com_1.png diff --git a/doc/integration/img/jira_dev_panel_setup_com_2.png b/doc/integration/img/jira_dev_panel_setup_com_2.png Binary files differindex 002a9140968..31dc13e1271 100644 --- a/doc/integration/img/jira_dev_panel_setup_com_2.png +++ b/doc/integration/img/jira_dev_panel_setup_com_2.png diff --git a/doc/integration/img/jira_dev_panel_setup_com_3.png b/doc/integration/img/jira_dev_panel_setup_com_3.png Binary files differindex c4e748c38cf..eb3c573a4bb 100644 --- a/doc/integration/img/jira_dev_panel_setup_com_3.png +++ b/doc/integration/img/jira_dev_panel_setup_com_3.png diff --git a/doc/legal/corporate_contributor_license_agreement.md b/doc/legal/corporate_contributor_license_agreement.md index c8782a2cfc2..018c4b575b5 100644 --- a/doc/legal/corporate_contributor_license_agreement.md +++ b/doc/legal/corporate_contributor_license_agreement.md @@ -21,7 +21,7 @@ You accept and agree to the following terms and conditions for Your present and - **Contributions:** You represent that each of Your Contributions is Your original creation. - + Should You wish to submit work that is not Your original creation, You may submit it to GitLab B.V. separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: (named here)". You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/doc/security/webhooks.md b/doc/security/webhooks.md index 7313cffdd13..bd05cbff05e 100644 --- a/doc/security/webhooks.md +++ b/doc/security/webhooks.md @@ -71,16 +71,24 @@ use IDNA encoding. The whitelist can hold a maximum of 1000 entries. Each entry can be a maximum of 255 characters. +You can whitelist a particular port by specifying it in the whitelist entry. +For example `127.0.0.1:8080` will only allow connections to port 8080 on `127.0.0.1`. +If no port is mentioned, all ports on that IP/domain are whitelisted. An IP range +will whitelist all ports on all IPs in that range. + Example: ```text example.com;gitlab.example.com 127.0.0.1,1:0:0:0:0:0:0:1 127.0.0.0/8 1:0:0:0:0:0:0:0/124 +[1:0:0:0:0:0:0:1]:8080 +127.0.0.1:8080 +example.com:8080 ``` NOTE: **Note:** -Wildcards (`*.example.com`) and ports (`127.0.0.1:3000`) are not currently supported. +Wildcards (`*.example.com`) are not currently supported. <!-- ## Troubleshooting diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md index 0ca05fe0cda..925f162d0fe 100644 --- a/doc/subscriptions/index.md +++ b/doc/subscriptions/index.md @@ -389,7 +389,7 @@ To purchase additional minutes for your personal namespace: 1. Click your avatar, then go to **Settings > Pipeline quota**. 1. Locate the subscription card that's linked to your personal namespace on GitLab.com, click **Buy more CI minutes**, and complete the details about the transaction. Once we have processed your payment, the extra CI minutes will be synced to your Group. -1. To confirm the available CI minutes for your personal projects, click your avatar, then go to **Settings > Pipeline quota**. +1. To confirm the available CI minutes for your personal projects, click your avatar, then go to **Settings > Pipeline quota**. The **Additional minutes** displayed now includes the purchased additional CI minutes, plus any minutes rolled over from last month. Be aware that: diff --git a/doc/topics/git/numerous_undo_possibilities_in_git/index.md b/doc/topics/git/numerous_undo_possibilities_in_git/index.md index cea052f3a90..3b93c978931 100644 --- a/doc/topics/git/numerous_undo_possibilities_in_git/index.md +++ b/doc/topics/git/numerous_undo_possibilities_in_git/index.md @@ -253,7 +253,7 @@ In our example we will end up with commit `B`, that introduced bug/error. We hav - Undo changes on a single file or directory from commit `B`, but retain them in the unstaged state: ```shell - git reset commit-B-id <file> + git reset commit-B-id <file> ``` - There is one command we also must not forget: **creating a new branch** @@ -487,8 +487,8 @@ git filter-branch --tree-filter 'rm filename' HEAD Since `git filter-branch` command might be slow on big repositories, there are tools that can use some of Git specifics to enable faster execution of common tasks (which is exactly what removing sensitive information file is about). -An alternative is the open source community-maintained tool [BFG][bfg-repo-cleaner]. -Keep in mind that these tools are faster because they do not provide the same +An alternative is the open source community-maintained tool [BFG][bfg-repo-cleaner]. +Keep in mind that these tools are faster because they do not provide the same feature set as `git filter-branch` does, but focus on specific use cases. ## Conclusion diff --git a/doc/user/admin_area/settings/img/admin_package_registry_npm_package_requests_forward.png b/doc/user/admin_area/settings/img/admin_package_registry_npm_package_requests_forward.png Binary files differindex 3cd2e1adc29..b6068f5d19b 100644 --- a/doc/user/admin_area/settings/img/admin_package_registry_npm_package_requests_forward.png +++ b/doc/user/admin_area/settings/img/admin_package_registry_npm_package_requests_forward.png diff --git a/doc/user/admin_area/settings/img/gitaly_timeouts.png b/doc/user/admin_area/settings/img/gitaly_timeouts.png Binary files differindex 82b2889b0d5..28394d238f7 100644 --- a/doc/user/admin_area/settings/img/gitaly_timeouts.png +++ b/doc/user/admin_area/settings/img/gitaly_timeouts.png diff --git a/doc/user/analytics/img/code_review_analytics_v12_8.png b/doc/user/analytics/img/code_review_analytics_v12_8.png Binary files differindex 228e03e628a..3b23e74130a 100644 --- a/doc/user/analytics/img/code_review_analytics_v12_8.png +++ b/doc/user/analytics/img/code_review_analytics_v12_8.png diff --git a/doc/user/discussions/img/suggestion_code_block_output_v12_8.png b/doc/user/discussions/img/suggestion_code_block_output_v12_8.png Binary files differindex 74833253aa0..6f29107146d 100644 --- a/doc/user/discussions/img/suggestion_code_block_output_v12_8.png +++ b/doc/user/discussions/img/suggestion_code_block_output_v12_8.png diff --git a/doc/user/group/epics/img/epic_view_roadmap_v12_9.png b/doc/user/group/epics/img/epic_view_roadmap_v12_9.png Binary files differindex b85f1806123..035adc5e7ac 100644 --- a/doc/user/group/epics/img/epic_view_roadmap_v12_9.png +++ b/doc/user/group/epics/img/epic_view_roadmap_v12_9.png diff --git a/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png b/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png Binary files differindex b7dc2d3da8d..fccfa949779 100644 --- a/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png +++ b/doc/user/group/issues_analytics/img/issues_created_per_month_v12_8.png diff --git a/doc/user/group/roadmap/img/roadmap_view_v12_9.png b/doc/user/group/roadmap/img/roadmap_view_v12_9.png Binary files differindex 3aa8cbb8332..093e8af8702 100644 --- a/doc/user/group/roadmap/img/roadmap_view_v12_9.png +++ b/doc/user/group/roadmap/img/roadmap_view_v12_9.png diff --git a/doc/user/img/markdown_copy_from_spreadsheet_v12_7.png b/doc/user/img/markdown_copy_from_spreadsheet_v12_7.png Binary files differindex dccd6f10450..637ad49b6b5 100644 --- a/doc/user/img/markdown_copy_from_spreadsheet_v12_7.png +++ b/doc/user/img/markdown_copy_from_spreadsheet_v12_7.png diff --git a/doc/user/img/markdown_paste_table_v12_7.png b/doc/user/img/markdown_paste_table_v12_7.png Binary files differindex d3ba61da7d7..919599723dd 100644 --- a/doc/user/img/markdown_paste_table_v12_7.png +++ b/doc/user/img/markdown_paste_table_v12_7.png diff --git a/doc/user/packages/container_registry/img/expiration-policy-app.png b/doc/user/packages/container_registry/img/expiration-policy-app.png Binary files differindex e353fe27b2a..e2d3d668e38 100644 --- a/doc/user/packages/container_registry/img/expiration-policy-app.png +++ b/doc/user/packages/container_registry/img/expiration-policy-app.png diff --git a/doc/user/packages/nuget_repository/img/visual_studio_adding_nuget_source.png b/doc/user/packages/nuget_repository/img/visual_studio_adding_nuget_source.png Binary files differindex 94b037ced42..7397403f4bf 100644 --- a/doc/user/packages/nuget_repository/img/visual_studio_adding_nuget_source.png +++ b/doc/user/packages/nuget_repository/img/visual_studio_adding_nuget_source.png diff --git a/doc/user/packages/nuget_repository/img/visual_studio_nuget_source_added.png b/doc/user/packages/nuget_repository/img/visual_studio_nuget_source_added.png Binary files differindex d2f4791a25a..e4f6068f28c 100644 --- a/doc/user/packages/nuget_repository/img/visual_studio_nuget_source_added.png +++ b/doc/user/packages/nuget_repository/img/visual_studio_nuget_source_added.png diff --git a/doc/user/project/clusters/img/kubernetes_pod_logs_v12_9.png b/doc/user/project/clusters/img/kubernetes_pod_logs_v12_9.png Binary files differindex 6e5cf1af227..02b7cad1e3f 100644 --- a/doc/user/project/clusters/img/kubernetes_pod_logs_v12_9.png +++ b/doc/user/project/clusters/img/kubernetes_pod_logs_v12_9.png diff --git a/doc/user/project/clusters/serverless/img/function-list_v12_7.png b/doc/user/project/clusters/serverless/img/function-list_v12_7.png Binary files differindex e7bd3439643..f2a27ce7b0f 100644 --- a/doc/user/project/clusters/serverless/img/function-list_v12_7.png +++ b/doc/user/project/clusters/serverless/img/function-list_v12_7.png diff --git a/doc/user/project/clusters/serverless/img/sam-api-endpoint.png b/doc/user/project/clusters/serverless/img/sam-api-endpoint.png Binary files differindex 695d975387f..3407b2684fd 100644 --- a/doc/user/project/clusters/serverless/img/sam-api-endpoint.png +++ b/doc/user/project/clusters/serverless/img/sam-api-endpoint.png diff --git a/doc/user/project/clusters/serverless/img/sam-complete-raw.png b/doc/user/project/clusters/serverless/img/sam-complete-raw.png Binary files differindex 1098c1bb93f..1130cd29d56 100644 --- a/doc/user/project/clusters/serverless/img/sam-complete-raw.png +++ b/doc/user/project/clusters/serverless/img/sam-complete-raw.png diff --git a/doc/user/project/img/deploy_boards_landing_page.png b/doc/user/project/img/deploy_boards_landing_page.png Binary files differindex 73b3724d657..bed5f11018e 100644 --- a/doc/user/project/img/deploy_boards_landing_page.png +++ b/doc/user/project/img/deploy_boards_landing_page.png diff --git a/doc/user/project/img/issue_boards_blocked_icon_v12_8.png b/doc/user/project/img/issue_boards_blocked_icon_v12_8.png Binary files differindex ede57b760ed..779f643ba56 100644 --- a/doc/user/project/img/issue_boards_blocked_icon_v12_8.png +++ b/doc/user/project/img/issue_boards_blocked_icon_v12_8.png diff --git a/doc/user/project/img/issue_boards_multi_select.png b/doc/user/project/img/issue_boards_multi_select_v12_4.png Binary files differindex eebe06b04ae..eebe06b04ae 100644 --- a/doc/user/project/img/issue_boards_multi_select.png +++ b/doc/user/project/img/issue_boards_multi_select_v12_4.png diff --git a/doc/user/project/img/labels_key_value_v12_1.png b/doc/user/project/img/labels_key_value_v12_1.png Binary files differindex 82a6856bca7..ccda944a647 100644 --- a/doc/user/project/img/labels_key_value_v12_1.png +++ b/doc/user/project/img/labels_key_value_v12_1.png diff --git a/doc/user/project/integrations/img/grafana_embedded.png b/doc/user/project/integrations/img/grafana_embedded.png Binary files differindex bc9018c97af..c7946aa4b10 100644 --- a/doc/user/project/integrations/img/grafana_embedded.png +++ b/doc/user/project/integrations/img/grafana_embedded.png diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md index dd51d303294..464929a7e6c 100644 --- a/doc/user/project/issue_board.md +++ b/doc/user/project/issue_board.md @@ -180,18 +180,6 @@ These are shortcuts to your last 4 visited boards. When you're revisiting an issue board in a project or group with multiple boards, GitLab will automatically load the last board you visited. -### Multi-select Issue Cards - -As the name suggest, multi-select issue cards allows more than one issue card -to be dragged and dropped across different lists. This becomes helpful while -moving and grooming a lot of issues at once. - -You can multi-select an issue card by pressing `CTRL` + `Left mouse click` on -Windows or `CMD` + `Left mouse click` on MacOS. Once done, start by dragging one -of the issue card you have selected and drop it in the new list you want. - -![Multi-select Issue Cards](img/issue_boards_multi_select.png) - ### Configurable Issue Boards **(STARTER)** > Introduced in [GitLab Starter Edition 10.2](https://about.gitlab.com/releases/2017/11/22/gitlab-10-2-released/#issue-boards-configuration). @@ -467,6 +455,19 @@ When dragging issues between lists, different behavior occurs depending on the s | From label `A` list | `A` removed | Issue closed | `A` removed<br/>`B` added | `Bob` assigned | | From assignee `Alice` list | `Alice` unassigned | Issue closed | `B` added | `Alice` unassigned<br/>`Bob` assigned | +### Multi-select issue cards + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/18954) in GitLab 12.4. + +You can select multiple issue cards, then drag the group to another position within the list, or to another list. This makes it faster to reorder many issues at once. + +To select and move multiple cards: + +1. Select each card with <kbd>Ctrl</kbd>+`Click` on Windows or Linux, or <kbd>Cmd</kbd>+`Click` on MacOS. +1. Drag one of the selected cards to another position or list and all selected cards will be moved. + +![Multi-select Issue Cards](img/issue_boards_multi_select_v12_4.png) + ## Tips A few things to remember: diff --git a/doc/user/project/issues/img/related_issue_block_v12_8.png b/doc/user/project/issues/img/related_issue_block_v12_8.png Binary files differindex 02d70868abc..ce261f26ce6 100644 --- a/doc/user/project/issues/img/related_issue_block_v12_8.png +++ b/doc/user/project/issues/img/related_issue_block_v12_8.png diff --git a/doc/user/project/issues/img/related_issues_add_v12_8.png b/doc/user/project/issues/img/related_issues_add_v12_8.png Binary files differindex 5d6fa218426..8a06d005a5f 100644 --- a/doc/user/project/issues/img/related_issues_add_v12_8.png +++ b/doc/user/project/issues/img/related_issues_add_v12_8.png diff --git a/doc/user/project/issues/img/related_issues_remove_v12_8.png b/doc/user/project/issues/img/related_issues_remove_v12_8.png Binary files differindex bf35bec1bec..a8dff4c7052 100644 --- a/doc/user/project/issues/img/related_issues_remove_v12_8.png +++ b/doc/user/project/issues/img/related_issues_remove_v12_8.png diff --git a/doc/user/project/merge_requests/img/approvals_premium_mr_widget_v12_7.png b/doc/user/project/merge_requests/img/approvals_premium_mr_widget_v12_7.png Binary files differindex f9348b0eefc..164779a8450 100644 --- a/doc/user/project/merge_requests/img/approvals_premium_mr_widget_v12_7.png +++ b/doc/user/project/merge_requests/img/approvals_premium_mr_widget_v12_7.png diff --git a/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_7.png b/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_7.png Binary files differindex c2e5714e78d..669148a41d8 100644 --- a/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_7.png +++ b/doc/user/project/merge_requests/img/mr_approvals_by_code_owners_v12_7.png diff --git a/doc/user/project/merge_requests/img/scoped_to_protected_branch_v12_8.png b/doc/user/project/merge_requests/img/scoped_to_protected_branch_v12_8.png Binary files differindex 08a24e9f28e..9446ed66c38 100644 --- a/doc/user/project/merge_requests/img/scoped_to_protected_branch_v12_8.png +++ b/doc/user/project/merge_requests/img/scoped_to_protected_branch_v12_8.png diff --git a/doc/user/project/releases/img/releases_count_v12_8.png b/doc/user/project/releases/img/releases_count_v12_8.png Binary files differindex fae3b58d8e3..e70f623d508 100644 --- a/doc/user/project/releases/img/releases_count_v12_8.png +++ b/doc/user/project/releases/img/releases_count_v12_8.png diff --git a/doc/user/project/releases/img/upcoming_release_v12_7.png b/doc/user/project/releases/img/upcoming_release_v12_7.png Binary files differindex 4ff8fad98f9..458aa66f6fe 100644 --- a/doc/user/project/releases/img/upcoming_release_v12_7.png +++ b/doc/user/project/releases/img/upcoming_release_v12_7.png diff --git a/doc/user/project/repository/img/forking_workflow_fork_button.png b/doc/user/project/repository/img/forking_workflow_fork_button.png Binary files differindex 74b68a7e61c..eea62892232 100644 --- a/doc/user/project/repository/img/forking_workflow_fork_button.png +++ b/doc/user/project/repository/img/forking_workflow_fork_button.png diff --git a/doc/user/project/repository/reducing_the_repo_size_using_git.md b/doc/user/project/repository/reducing_the_repo_size_using_git.md index a024f8eff97..16bffe5417d 100644 --- a/doc/user/project/repository/reducing_the_repo_size_using_git.md +++ b/doc/user/project/repository/reducing_the_repo_size_using_git.md @@ -19,7 +19,7 @@ Unfortunately, it's not so easy and that workflow won't work. Deleting files in a commit doesn't actually reduce the size of the repo since the earlier commits and blobs are still around. What you need to do is rewrite history with Git's [`filter-branch` option](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#The-Nuclear-Option:-filter-branch), -or an open source community-maintained tool like the +or an open source community-maintained tool like the [BFG](https://rtyley.github.io/bfg-repo-cleaner/). Note that even with that method, until `git gc` runs on the GitLab side, the diff --git a/lib/gitlab/url_blocker.rb b/lib/gitlab/url_blocker.rb index 0adca34440c..88094839062 100644 --- a/lib/gitlab/url_blocker.rb +++ b/lib/gitlab/url_blocker.rb @@ -49,7 +49,7 @@ module Gitlab return [uri, nil] unless address_info ip_address = ip_address(address_info) - return [uri, nil] if domain_whitelisted?(uri) || ip_whitelisted?(ip_address) + return [uri, nil] if domain_whitelisted?(uri) || ip_whitelisted?(ip_address, port: get_port(uri)) protected_uri_with_hostname = enforce_uri_hostname(ip_address, uri, dns_rebind_protection) @@ -254,11 +254,11 @@ module Gitlab end def domain_whitelisted?(uri) - Gitlab::UrlBlockers::UrlWhitelist.domain_whitelisted?(uri.normalized_host) + Gitlab::UrlBlockers::UrlWhitelist.domain_whitelisted?(uri.normalized_host, port: get_port(uri)) end - def ip_whitelisted?(ip_address) - Gitlab::UrlBlockers::UrlWhitelist.ip_whitelisted?(ip_address) + def ip_whitelisted?(ip_address, port: nil) + Gitlab::UrlBlockers::UrlWhitelist.ip_whitelisted?(ip_address, port: port) end def config diff --git a/lib/gitlab/url_blockers/domain_whitelist_entry.rb b/lib/gitlab/url_blockers/domain_whitelist_entry.rb new file mode 100644 index 00000000000..b94e8ee3f69 --- /dev/null +++ b/lib/gitlab/url_blockers/domain_whitelist_entry.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Gitlab + module UrlBlockers + class DomainWhitelistEntry + attr_reader :domain, :port + + def initialize(domain, port: nil) + @domain = domain + @port = port + end + + def match?(requested_domain, requested_port = nil) + return false unless domain == requested_domain + return true if port.nil? + + port == requested_port + end + end + end +end diff --git a/lib/gitlab/url_blockers/ip_whitelist_entry.rb b/lib/gitlab/url_blockers/ip_whitelist_entry.rb new file mode 100644 index 00000000000..88c76574d3d --- /dev/null +++ b/lib/gitlab/url_blockers/ip_whitelist_entry.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Gitlab + module UrlBlockers + class IpWhitelistEntry + attr_reader :ip, :port + + # Argument ip should be an IPAddr object + def initialize(ip, port: nil) + @ip = ip + @port = port + end + + def match?(requested_ip, requested_port = nil) + return false unless ip.include?(requested_ip) + return true if port.nil? + + port == requested_port + end + end + end +end diff --git a/lib/gitlab/url_blockers/url_whitelist.rb b/lib/gitlab/url_blockers/url_whitelist.rb index 7622de4fdbe..59f74dde7fc 100644 --- a/lib/gitlab/url_blockers/url_whitelist.rb +++ b/lib/gitlab/url_blockers/url_whitelist.rb @@ -4,21 +4,25 @@ module Gitlab module UrlBlockers class UrlWhitelist class << self - def ip_whitelisted?(ip_string) + def ip_whitelisted?(ip_string, port: nil) return false if ip_string.blank? ip_whitelist, _ = outbound_local_requests_whitelist_arrays ip_obj = Gitlab::Utils.string_to_ip_object(ip_string) - ip_whitelist.any? { |ip| ip.include?(ip_obj) } + ip_whitelist.any? do |ip_whitelist_entry| + ip_whitelist_entry.match?(ip_obj, port) + end end - def domain_whitelisted?(domain_string) + def domain_whitelisted?(domain_string, port: nil) return false if domain_string.blank? _, domain_whitelist = outbound_local_requests_whitelist_arrays - domain_whitelist.include?(domain_string) + domain_whitelist.any? do |domain_whitelist_entry| + domain_whitelist_entry.match?(domain_string, port) + end end private diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb index f8bfcc6c99a..08678de87c9 100644 --- a/spec/lib/gitlab/url_blocker_spec.rb +++ b/spec/lib/gitlab/url_blocker_spec.rb @@ -501,6 +501,18 @@ describe Gitlab::UrlBlocker, :stub_invalid_dns_only do it_behaves_like 'dns rebinding checks' end end + + context 'with ports' do + let(:whitelist) do + ["127.0.0.1:2000"] + end + + it 'allows domain with port when resolved ip has port whitelisted' do + stub_domain_resolv("www.resolve-domain.com", '127.0.0.1') do + expect(described_class).not_to be_blocked_url("http://www.resolve-domain.com:2000", url_blocker_attributes) + end + end + end end end diff --git a/spec/lib/gitlab/url_blockers/domain_whitelist_entry_spec.rb b/spec/lib/gitlab/url_blockers/domain_whitelist_entry_spec.rb new file mode 100644 index 00000000000..34ea6c328e6 --- /dev/null +++ b/spec/lib/gitlab/url_blockers/domain_whitelist_entry_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::UrlBlockers::DomainWhitelistEntry do + let(:domain) { 'www.example.com' } + + describe '#initialize' do + it 'initializes without port' do + domain_whitelist_entry = described_class.new(domain) + + expect(domain_whitelist_entry.domain).to eq(domain) + expect(domain_whitelist_entry.port).to be(nil) + end + + it 'initializes with port' do + port = 8080 + domain_whitelist_entry = described_class.new(domain, port: port) + + expect(domain_whitelist_entry.domain).to eq(domain) + expect(domain_whitelist_entry.port).to eq(port) + end + end + + describe '#match?' do + it 'matches when domain and port are equal' do + port = 8080 + domain_whitelist_entry = described_class.new(domain, port: port) + + expect(domain_whitelist_entry).to be_match(domain, port) + end + + it 'matches any port when port is nil' do + domain_whitelist_entry = described_class.new(domain) + + expect(domain_whitelist_entry).to be_match(domain, 8080) + expect(domain_whitelist_entry).to be_match(domain, 9090) + end + + it 'does not match when port is present but requested_port is nil' do + domain_whitelist_entry = described_class.new(domain, port: 8080) + + expect(domain_whitelist_entry).not_to be_match(domain, nil) + end + + it 'matches when port and requested_port are nil' do + domain_whitelist_entry = described_class.new(domain) + + expect(domain_whitelist_entry).to be_match(domain) + end + + it 'does not match if domain is not equal' do + domain_whitelist_entry = described_class.new(domain) + + expect(domain_whitelist_entry).not_to be_match('www.gitlab.com', 8080) + end + end +end diff --git a/spec/lib/gitlab/url_blockers/ip_whitelist_entry_spec.rb b/spec/lib/gitlab/url_blockers/ip_whitelist_entry_spec.rb new file mode 100644 index 00000000000..042d135d265 --- /dev/null +++ b/spec/lib/gitlab/url_blockers/ip_whitelist_entry_spec.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::UrlBlockers::IpWhitelistEntry do + let(:ipv4) { IPAddr.new('192.168.1.1') } + + describe '#initialize' do + it 'initializes without port' do + ip_whitelist_entry = described_class.new(ipv4) + + expect(ip_whitelist_entry.ip).to eq(ipv4) + expect(ip_whitelist_entry.port).to be(nil) + end + + it 'initializes with port' do + port = 8080 + ip_whitelist_entry = described_class.new(ipv4, port: port) + + expect(ip_whitelist_entry.ip).to eq(ipv4) + expect(ip_whitelist_entry.port).to eq(port) + end + end + + describe '#match?' do + it 'matches with equivalent IP and port' do + port = 8080 + ip_whitelist_entry = described_class.new(ipv4, port: port) + + expect(ip_whitelist_entry).to be_match(ipv4.to_s, port) + end + + it 'matches any port when port is nil' do + ip_whitelist_entry = described_class.new(ipv4) + + expect(ip_whitelist_entry).to be_match(ipv4.to_s, 8080) + expect(ip_whitelist_entry).to be_match(ipv4.to_s, 9090) + end + + it 'does not match when port is present but requested_port is nil' do + ip_whitelist_entry = described_class.new(ipv4, port: 8080) + + expect(ip_whitelist_entry).not_to be_match(ipv4.to_s, nil) + end + + it 'matches when port and requested_port are nil' do + ip_whitelist_entry = described_class.new(ipv4) + + expect(ip_whitelist_entry).to be_match(ipv4.to_s) + end + + it 'works with ipv6' do + ipv6 = IPAddr.new('fe80::c800:eff:fe74:8') + ip_whitelist_entry = described_class.new(ipv6) + + expect(ip_whitelist_entry).to be_match(ipv6.to_s, 8080) + end + + it 'matches ipv4 within IPv4 range' do + ipv4_range = IPAddr.new('127.0.0.0/28') + ip_whitelist_entry = described_class.new(ipv4_range) + + expect(ip_whitelist_entry).to be_match(ipv4_range.to_range.last.to_s, 8080) + expect(ip_whitelist_entry).not_to be_match('127.0.1.1', 8080) + end + + it 'matches IPv6 within IPv6 range' do + ipv6_range = IPAddr.new('fd84:6d02:f6d8:c89e::/124') + ip_whitelist_entry = described_class.new(ipv6_range) + + expect(ip_whitelist_entry).to be_match(ipv6_range.to_range.last.to_s, 8080) + expect(ip_whitelist_entry).not_to be_match('fd84:6d02:f6d8:f::f', 8080) + end + end +end diff --git a/spec/lib/gitlab/url_blockers/url_whitelist_spec.rb b/spec/lib/gitlab/url_blockers/url_whitelist_spec.rb index 64d804e8541..e43cd819838 100644 --- a/spec/lib/gitlab/url_blockers/url_whitelist_spec.rb +++ b/spec/lib/gitlab/url_blockers/url_whitelist_spec.rb @@ -13,20 +13,17 @@ describe Gitlab::UrlBlockers::UrlWhitelist do end describe '#domain_whitelisted?' do - let(:whitelist) do - [ - 'www.example.com', - 'example.com' - ] - end + let(:whitelist) { ['www.example.com', 'example.com'] } it 'returns true if domains present in whitelist' do + not_whitelisted = ['subdomain.example.com', 'example.org'] + aggregate_failures do whitelist.each do |domain| expect(described_class).to be_domain_whitelisted(domain) end - ['subdomain.example.com', 'example.org'].each do |domain| + not_whitelisted.each do |domain| expect(described_class).not_to be_domain_whitelisted(domain) end end @@ -35,6 +32,28 @@ describe Gitlab::UrlBlockers::UrlWhitelist do it 'returns false when domain is blank' do expect(described_class).not_to be_domain_whitelisted(nil) end + + context 'with ports' do + let(:whitelist) { ['example.io:3000'] } + + it 'returns true if domain and ports present in whitelist' do + parsed_whitelist = [['example.io', { port: 3000 }]] + not_whitelisted = [ + 'example.io', + ['example.io', { port: 3001 }] + ] + + aggregate_failures do + parsed_whitelist.each do |domain_and_port| + expect(described_class).to be_domain_whitelisted(*domain_and_port) + end + + not_whitelisted.each do |domain_and_port| + expect(described_class).not_to be_domain_whitelisted(*domain_and_port) + end + end + end + end end describe '#ip_whitelisted?' do @@ -114,5 +133,32 @@ describe Gitlab::UrlBlockers::UrlWhitelist do expect(described_class).not_to be_ip_whitelisted("127.0.1.15") end end + + context 'with ports' do + let(:whitelist) { ['127.0.0.9:3000', '[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443'] } + + it 'returns true if ip and ports present in whitelist' do + parsed_whitelist = [ + ['127.0.0.9', { port: 3000 }], + ['[2001:db8:85a3:8d3:1319:8a2e:370:7348]', { port: 443 }] + ] + not_whitelisted = [ + '127.0.0.9', + ['127.0.0.9', { port: 3001 }], + '[2001:db8:85a3:8d3:1319:8a2e:370:7348]', + ['[2001:db8:85a3:8d3:1319:8a2e:370:7348]', { port: 3001 }] + ] + + aggregate_failures do + parsed_whitelist.each do |ip_and_port| + expect(described_class).to be_ip_whitelisted(*ip_and_port) + end + + not_whitelisted.each do |ip_and_port| + expect(described_class).not_to be_ip_whitelisted(*ip_and_port) + end + end + end + end end end diff --git a/spec/support/shared_contexts/upload_type_check_shared_context.rb b/spec/support/shared_contexts/upload_type_check_shared_context.rb index b0b569fe83f..f168cad961c 100644 --- a/spec/support/shared_contexts/upload_type_check_shared_context.rb +++ b/spec/support/shared_contexts/upload_type_check_shared_context.rb @@ -2,37 +2,6 @@ # Construct an `uploader` variable that is configured to `check_upload_type` # with `mime_types` and `extensions`. -RSpec.shared_context 'uploader with type check' do - let(:uploader_class) do - Class.new(GitlabUploader) do - include UploadTypeCheck::Concern - storage :file - end - end - - let(:mime_types) { nil } - let(:extensions) { nil } - let(:uploader) do - uploader_class.class_exec(mime_types, extensions) do |mime_types, extensions| - check_upload_type mime_types: mime_types, extensions: extensions - end - uploader_class.new(build_stubbed(:user)) - end -end - -# This works with the UploadTypeCheck::Concern -RSpec.shared_context 'stubbed MimeMagic mime type detection' do - let(:mime_type) { '' } - let(:magic_mime) { mime_type } - let(:ext_mime) { mime_type } - before do - magic_mime_obj = MimeMagic.new(magic_mime) - ext_mime_obj = MimeMagic.new(ext_mime) - allow(MimeMagic).to receive(:by_magic).with(anything).and_return(magic_mime_obj) - allow(MimeMagic).to receive(:by_path).with(anything).and_return(ext_mime_obj) - end -end - # @param uploader [CarrierWave::Uploader::Base] uploader with extension_whitelist method. RSpec.shared_context 'ignore extension whitelist check' do before do diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb index a43d2a75082..aed85a6630a 100644 --- a/spec/support/shared_examples/models/application_setting_shared_examples.rb +++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb @@ -68,12 +68,12 @@ RSpec.shared_examples 'application settings examples' do setting.outbound_local_requests_whitelist_raw = 'example.com' expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly( - [], ['example.com'] + [], [an_object_having_attributes(domain: 'example.com')] ) setting.outbound_local_requests_whitelist_raw = 'gitlab.com' expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly( - [], ['gitlab.com'] + [], [an_object_having_attributes(domain: 'gitlab.com')] ) end end @@ -81,15 +81,42 @@ RSpec.shared_examples 'application settings examples' do context 'outbound_local_requests_whitelist_arrays' do it 'separates the IPs and domains' do setting.outbound_local_requests_whitelist = [ - '192.168.1.1', '127.0.0.0/28', 'www.example.com', 'example.com', - '::ffff:a00:2', '1:0:0:0:0:0:0:0/124', 'subdomain.example.com' + '192.168.1.1', + '127.0.0.0/28', + '::ffff:a00:2', + '1:0:0:0:0:0:0:0/124', + 'example.com', + 'subdomain.example.com', + 'www.example.com', + '::', + '1::', + '::1', + '1:2:3:4:5::7:8', + '[1:2:3:4:5::7:8]', + '[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443', + 'www.example2.com:8080', + 'example.com:8080' ] ip_whitelist = [ - IPAddr.new('192.168.1.1'), IPAddr.new('127.0.0.0/8'), - IPAddr.new('::ffff:a00:2'), IPAddr.new('1:0:0:0:0:0:0:0/124') + an_object_having_attributes(ip: IPAddr.new('192.168.1.1')), + an_object_having_attributes(ip: IPAddr.new('127.0.0.0/8')), + an_object_having_attributes(ip: IPAddr.new('::ffff:a00:2')), + an_object_having_attributes(ip: IPAddr.new('1:0:0:0:0:0:0:0/124')), + an_object_having_attributes(ip: IPAddr.new('::')), + an_object_having_attributes(ip: IPAddr.new('1::')), + an_object_having_attributes(ip: IPAddr.new('::1')), + an_object_having_attributes(ip: IPAddr.new('1:2:3:4:5::7:8')), + an_object_having_attributes(ip: IPAddr.new('[1:2:3:4:5::7:8]')), + an_object_having_attributes(ip: IPAddr.new('[2001:db8:85a3:8d3:1319:8a2e:370:7348]'), port: 443) + ] + domain_whitelist = [ + an_object_having_attributes(domain: 'example.com'), + an_object_having_attributes(domain: 'subdomain.example.com'), + an_object_having_attributes(domain: 'www.example.com'), + an_object_having_attributes(domain: 'www.example2.com', port: 8080), + an_object_having_attributes(domain: 'example.com', port: 8080) ] - domain_whitelist = ['www.example.com', 'example.com', 'subdomain.example.com'] expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly( ip_whitelist, domain_whitelist @@ -117,7 +144,7 @@ RSpec.shared_examples 'application settings examples' do expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly( [], - ['example.com'] + [an_object_having_attributes(domain: 'example.com')] ) setting.add_to_outbound_local_requests_whitelist( @@ -126,7 +153,7 @@ RSpec.shared_examples 'application settings examples' do expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly( [], - ['example.com', 'gitlab.com'] + [an_object_having_attributes(domain: 'example.com'), an_object_having_attributes(domain: 'gitlab.com')] ) end @@ -137,7 +164,7 @@ RSpec.shared_examples 'application settings examples' do expect(setting.outbound_local_requests_whitelist).to contain_exactly('gitlab.com') expect(setting.outbound_local_requests_whitelist_arrays).to contain_exactly( - [], ['gitlab.com'] + [], [an_object_having_attributes(domain: 'gitlab.com')] ) end diff --git a/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb b/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb index 99da2a14bb6..81ac6bd94db 100644 --- a/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb +++ b/spec/support/shared_examples/uploaders/upload_type_shared_examples.rb @@ -26,67 +26,3 @@ shared_examples 'accepted carrierwave upload' do expect { uploader.cache!(fixture_file) }.to change { uploader.file }.from(nil).to(kind_of(CarrierWave::SanitizedFile)) end end - -def check_content_matches_extension!(file = double(read: nil, path: '')) - magic_file = UploadTypeCheck::MagicFile.new(file) - uploader.check_content_matches_extension!(magic_file) -end - -RSpec.shared_examples 'upload passes content type check' do - it 'does not raise error' do - expect { check_content_matches_extension! }.not_to raise_error - end -end - -RSpec.shared_examples 'upload fails content type check' do - it 'raises error' do - expect { check_content_matches_extension! }.to raise_error(CarrierWave::IntegrityError) - end -end - -def upload_type_checked_filenames(filenames) - Array(filenames).each do |filename| - # Feed the uploader "some" content. - path = File.join('spec', 'fixtures', 'dk.png') - file = File.new(path, 'r') - # Rename the file with what we want. - allow(file).to receive(:path).and_return(filename) - - # Force the content type to match the extension type. - mime_type = MimeMagic.by_path(filename) - allow(MimeMagic).to receive(:by_magic).and_return(mime_type) - - uploaded_file = Rack::Test::UploadedFile.new(file, original_filename: filename) - uploader.cache!(uploaded_file) - end -end - -def upload_type_checked_fixtures(upload_fixtures) - upload_fixtures = Array(upload_fixtures) - upload_fixtures.each do |upload_fixture| - path = File.join('spec', 'fixtures', upload_fixture) - uploader.cache!(fixture_file_upload(path)) - end -end - -RSpec.shared_examples 'type checked uploads' do |upload_fixtures = nil, filenames: nil| - it 'check type' do - upload_fixtures = Array(upload_fixtures) - filenames = Array(filenames) - - times = upload_fixtures.length + filenames.length - expect(uploader).to receive(:check_content_matches_extension!).exactly(times).times - - upload_type_checked_fixtures(upload_fixtures) unless upload_fixtures.empty? - upload_type_checked_filenames(filenames) unless filenames.empty? - end -end - -RSpec.shared_examples 'skipped type checked uploads' do |upload_fixtures = nil, filenames: nil| - it 'skip type check' do - expect(uploader).not_to receive(:check_content_matches_extension!) - - upload_type_checked_fixtures(upload_fixtures) if upload_fixtures - upload_type_checked_filenames(filenames) if filenames - end -end diff --git a/spec/uploaders/upload_type_check_spec.rb b/spec/uploaders/upload_type_check_spec.rb deleted file mode 100644 index a4895f6a956..00000000000 --- a/spec/uploaders/upload_type_check_spec.rb +++ /dev/null @@ -1,124 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe UploadTypeCheck do - include_context 'uploader with type check' - - def upload_fixture(filename) - fixture_file_upload(File.join('spec', 'fixtures', filename)) - end - - describe '#check_content_matches_extension! callback using file upload' do - context 'when extension matches contents' do - it 'not raise error on upload' do - expect { uploader.cache!(upload_fixture('banana_sample.gif')) }.not_to raise_error - end - end - - context 'when extension does not match contents' do - it 'raise error' do - expect { uploader.cache!(upload_fixture('not_a_png.png')) }.to raise_error(CarrierWave::IntegrityError) - end - end - end - - describe '#check_content_matches_extension! callback using stubs' do - include_context 'stubbed MimeMagic mime type detection' - - context 'when no extension and with ambiguous/text content' do - let(:magic_mime) { '' } - let(:ext_mime) { '' } - - it_behaves_like 'upload passes content type check' - end - - context 'when no extension and with non-text content' do - let(:magic_mime) { 'image/gif' } - let(:ext_mime) { '' } - - it_behaves_like 'upload fails content type check' - end - - # Most text files will exhibit this behaviour. - context 'when ambiguous content with text extension' do - let(:magic_mime) { '' } - let(:ext_mime) { 'text/plain' } - - it_behaves_like 'upload passes content type check' - end - - context 'when text content with text extension' do - let(:magic_mime) { 'text/plain' } - let(:ext_mime) { 'text/plain' } - - it_behaves_like 'upload passes content type check' - end - - context 'when ambiguous content with non-text extension' do - let(:magic_mime) { '' } - let(:ext_mime) { 'application/zip' } - - it_behaves_like 'upload fails content type check' - end - - # These are the types when uploading a .dmg - context 'when content and extension do not match' do - let(:magic_mime) { 'application/x-bzip' } - let(:ext_mime) { 'application/x-apple-diskimage' } - - it_behaves_like 'upload fails content type check' - end - end - - describe '#check_content_matches_extension! mime_type filtering' do - context 'without mime types' do - let(:mime_types) { nil } - - it_behaves_like 'type checked uploads', %w[doc_sample.txt rails_sample.jpg] - end - - context 'with mime types string' do - let(:mime_types) { 'text/plain' } - - it_behaves_like 'type checked uploads', %w[doc_sample.txt] - it_behaves_like 'skipped type checked uploads', %w[dk.png] - end - - context 'with mime types regex' do - let(:mime_types) { [/image\/(gif|png)/] } - - it_behaves_like 'type checked uploads', %w[banana_sample.gif dk.png] - it_behaves_like 'skipped type checked uploads', %w[doc_sample.txt] - end - - context 'with mime types array' do - let(:mime_types) { ['text/plain', /image\/png/] } - - it_behaves_like 'type checked uploads', %w[doc_sample.txt dk.png] - it_behaves_like 'skipped type checked uploads', %w[audio_sample.wav] - end - end - - describe '#check_content_matches_extension! extensions filtering' do - context 'without extensions' do - let(:extensions) { nil } - - it_behaves_like 'type checked uploads', %w[doc_sample.txt dk.png] - end - - context 'with extensions string' do - let(:extensions) { 'txt' } - - it_behaves_like 'type checked uploads', %w[doc_sample.txt] - it_behaves_like 'skipped type checked uploads', %w[rails_sample.jpg] - end - - context 'with extensions array of strings' do - let(:extensions) { %w[txt png] } - - it_behaves_like 'type checked uploads', %w[doc_sample.txt dk.png] - it_behaves_like 'skipped type checked uploads', %w[audio_sample.wav] - end - end -end |