diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-16 18:34:14 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-16 18:34:14 +0000 |
commit | faafdaeef2688b0ea66abcb3cc69648212c0c67c (patch) | |
tree | f538040ccbfafe2ec0e8ea490fa46c7b6691c2c3 | |
parent | 29721853e727f39890194d973b457124da6a4746 (diff) | |
download | gitlab-ce-faafdaeef2688b0ea66abcb3cc69648212c0c67c.tar.gz |
Add latest changes from gitlab-org/gitlab@12-9-stable-ee
23 files changed, 315 insertions, 93 deletions
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js index 370f3c6e7a2..6ae10c98058 100644 --- a/app/assets/javascripts/pages/projects/show/index.js +++ b/app/assets/javascripts/pages/projects/show/index.js @@ -48,6 +48,7 @@ document.addEventListener('DOMContentLoaded', () => { leaveByUrl('project'); if (document.getElementById('js-tree-list')) { + initBlob(); import('ee_else_ce/repository') .then(m => m.default()) .catch(e => { diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index c319d2fed87..7e9a14ff1c6 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -137,8 +137,8 @@ class ProjectsFinder < UnionFinder # rubocop: disable CodeReuse/ActiveRecord def by_ids(items) items = items.where(id: project_ids_relation) if project_ids_relation - items = items.where('id > ?', params[:id_after]) if params[:id_after] - items = items.where('id < ?', params[:id_before]) if params[:id_before] + items = items.where('projects.id > ?', params[:id_after]) if params[:id_after] + items = items.where('projects.id < ?', params[:id_before]) if params[:id_before] items end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb index 7bd011101dd..1ec983223f3 100644 --- a/app/models/project_services/chat_notification_service.rb +++ b/app/models/project_services/chat_notification_service.rb @@ -84,10 +84,11 @@ class ChatNotificationService < Service event_type = data[:event_type] || object_kind - channel_names = get_channel_field(event_type).presence || channel + channel_names = get_channel_field(event_type).presence || channel.presence + channels = channel_names&.split(',')&.map(&:strip) opts = {} - opts[:channel] = channel_names.split(',').map(&:strip) if channel_names + opts[:channel] = channels if channels.present? opts[:username] = username if username return false unless notify(message, opts) diff --git a/app/services/projects/hashed_storage/base_repository_service.rb b/app/services/projects/hashed_storage/base_repository_service.rb index 09de8d9f0da..d81aa4de9f1 100644 --- a/app/services/projects/hashed_storage/base_repository_service.rb +++ b/app/services/projects/hashed_storage/base_repository_service.rb @@ -40,7 +40,13 @@ module Projects return true end - gitlab_shell.mv_repository(project.repository_storage, from_name, to_name) + gitlab_shell.mv_repository(project.repository_storage, from_name, to_name).tap do |moved| + if moved + logger.info("Repository moved from '#{from_name}' to '#{to_name}' (PROJECT_ID=#{project.id})") + else + logger.error("Repository cannot be moved from '#{from_name}' to '#{to_name}' (PROJECT_ID=#{project.id})") + end + end end def move_repositories diff --git a/app/services/projects/hashed_storage/rollback_service.rb b/app/services/projects/hashed_storage/rollback_service.rb index c437001c440..01b343a12d1 100644 --- a/app/services/projects/hashed_storage/rollback_service.rb +++ b/app/services/projects/hashed_storage/rollback_service.rb @@ -5,6 +5,12 @@ module Projects class RollbackService < BaseService attr_reader :logger, :old_disk_path + def initialize(project, old_disk_path, logger: nil) + @project = project + @old_disk_path = old_disk_path + @logger = logger || Gitlab::AppLogger + end + def execute # Rollback attachments from Hashed Storage to Legacy if project.hashed_storage?(:attachments) diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb index 505b51c2006..517c22e2334 100644 --- a/app/uploaders/file_uploader.rb +++ b/app/uploaders/file_uploader.rb @@ -15,7 +15,7 @@ class FileUploader < GitlabUploader prepend ObjectStorage::Extension::RecordsUploads MARKDOWN_PATTERN = %r{\!?\[.*?\]\(/uploads/(?<secret>[0-9a-f]{32})/(?<file>.*?)\)}.freeze - DYNAMIC_PATH_PATTERN = %r{.*(?<secret>\h{32})/(?<identifier>.*)}.freeze + DYNAMIC_PATH_PATTERN = %r{.*/(?<secret>\h{10,32})/(?<identifier>.*)}.freeze VALID_SECRET_PATTERN = %r{\A\h{10,32}\z}.freeze InvalidSecret = Class.new(StandardError) diff --git a/changelogs/unreleased/209059-fix-project-show-file-upload-not-working.yml b/changelogs/unreleased/209059-fix-project-show-file-upload-not-working.yml new file mode 100644 index 00000000000..92675668950 --- /dev/null +++ b/changelogs/unreleased/209059-fix-project-show-file-upload-not-working.yml @@ -0,0 +1,5 @@ +--- +title: Fix not working File upload from Project overview page. +merge_request: 26828 +author: Gilang Gumilar +type: fixed diff --git a/changelogs/unreleased/209940-geo-fails-to-sync-file-uploads-with-improper-formatted-path.yml b/changelogs/unreleased/209940-geo-fails-to-sync-file-uploads-with-improper-formatted-path.yml new file mode 100644 index 00000000000..521fc9f83b7 --- /dev/null +++ b/changelogs/unreleased/209940-geo-fails-to-sync-file-uploads-with-improper-formatted-path.yml @@ -0,0 +1,5 @@ +--- +title: Fix incorrect regex used in FileUploader#extract_dynamic_path +merge_request: 28683 +author: +type: fixed diff --git a/changelogs/unreleased/211452-rollback_to_legacy-causes-repos-to-404.yml b/changelogs/unreleased/211452-rollback_to_legacy-causes-repos-to-404.yml new file mode 100644 index 00000000000..73955b4c2c3 --- /dev/null +++ b/changelogs/unreleased/211452-rollback_to_legacy-causes-repos-to-404.yml @@ -0,0 +1,5 @@ +--- +title: Fix storage rollback regression caused by previous refactor +merge_request: 28496 +author: +type: fixed diff --git a/changelogs/unreleased/212073-slack-notifications-stop-working-after-updating-gitlab.yml b/changelogs/unreleased/212073-slack-notifications-stop-working-after-updating-gitlab.yml new file mode 100644 index 00000000000..3814ed9476a --- /dev/null +++ b/changelogs/unreleased/212073-slack-notifications-stop-working-after-updating-gitlab.yml @@ -0,0 +1,5 @@ +--- +title: Fix Slack notifications when upgrading from old GitLab versions +merge_request: 29111 +author: +type: fixed diff --git a/changelogs/unreleased/ab-keyset-ambig-bug.yml b/changelogs/unreleased/ab-keyset-ambig-bug.yml new file mode 100644 index 00000000000..b4111794671 --- /dev/null +++ b/changelogs/unreleased/ab-keyset-ambig-bug.yml @@ -0,0 +1,5 @@ +--- +title: Fully qualify id columns for keyset pagination (Projects API) +merge_request: 29026 +author: +type: fixed diff --git a/doc/administration/geo/replication/version_specific_updates.md b/doc/administration/geo/replication/version_specific_updates.md index a697d07ded4..3c047c8374a 100644 --- a/doc/administration/geo/replication/version_specific_updates.md +++ b/doc/administration/geo/replication/version_specific_updates.md @@ -4,6 +4,13 @@ Check this document if it includes instructions for the version you are updating These steps go together with the [general steps](updating_the_geo_nodes.md#general-update-steps) for updating Geo nodes. +## Updating to GitLab 12.9 + +CAUTION: **Warning:** +GitLab 12.9.0 through GitLab 12.9.3 are affected by [a bug that stops +repository verification](https://gitlab.com/gitlab-org/gitlab/-/issues/213523). +The issue is fixed in GitLab 12.9.4. Please upgrade to GitLab 12.9.4 or later. + ## Updating to GitLab 12.7 DANGER: **Danger:** diff --git a/doc/install/installation.md b/doc/install/installation.md index fa708f6d5cf..c596c2e4e43 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -134,7 +134,7 @@ Make sure you have the right version of Git installed: # Install Git sudo apt-get install -y git-core -# Make sure Git is version 2.24.1 or higher (minimal supported version is 2.22.0) +# Make sure Git is version 2.24.2 or higher (minimal supported version is 2.22.0) git --version ``` @@ -171,9 +171,9 @@ sudo make install # Download and compile from source cd /tmp -curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.24.1.tar.gz -echo 'ad5334956301c86841eb1e5b1bb20884a6bad89a10a6762c958220c7cf64da02 git-2.24.1.tar.gz' | shasum -a256 -c - && tar -xzf git-2.24.1.tar.gz -cd git-2.24.1/ +curl --remote-name --location --progress https://www.kernel.org/pub/software/scm/git/git-2.24.2.tar.gz +echo 'ad5334956301c86841eb1e5b1bb20884a6bad89a10a6762c958220c7cf64da02 git-2.24.2.tar.gz' | shasum -a256 -c - && tar -xzf git-2.24.2.tar.gz +cd git-2.24.2/ ./configure --with-libpcre make prefix=/usr/local all diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb index 35a3835ff12..8a20c1387a3 100644 --- a/spec/features/projects/files/user_uploads_files_spec.rb +++ b/spec/features/projects/files/user_uploads_files_spec.rb @@ -5,103 +5,32 @@ require 'spec_helper' describe 'Projects > Files > User uploads files' do include DropzoneHelper - let(:fork_message) do - "You're not allowed to make changes to this project directly. "\ - "A fork of this project has been created that you can make changes in, so you can submit a merge request." - end let(:user) { create(:user) } let(:project) { create(:project, :repository, name: 'Shop', creator: user) } let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } - let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) } - let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) } before do project.add_maintainer(user) sign_in(user) end - context 'when an user has write access' do + context 'when a user has write access' do before do - visit(project_tree_path_root_ref) + visit(project_tree_path(project)) end - it 'uploads and commit a new text file', :js do - find('.add-to-tree').click - click_link('Upload file') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'New commit message') - end - - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Upload file') - - expect(page).to have_content('New commit message') - expect(current_path).to eq(project_new_merge_request_path(project)) + include_examples 'it uploads and commit a new text file' - click_link('Changes') - find("a[data-action='diffs']", text: 'Changes').click - - wait_for_requests - - expect(page).to have_content('Lorem ipsum dolor sit amet') - expect(page).to have_content('Sed ut perspiciatis unde omnis') - end - - it 'uploads and commit a new image file', :js do - find('.add-to-tree').click - click_link('Upload file') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'New commit message') - fill_in(:branch_name, with: 'new_branch_name', visible: true) - click_button('Upload file') - end - - wait_for_all_requests - - visit(project_blob_path(project, 'new_branch_name/logo_sample.svg')) - - expect(page).to have_css('.file-content img') - end + include_examples 'it uploads and commit a new image file' end - context 'when an user does not have write access' do + context 'when a user does not have write access' do before do project2.add_reporter(user) - visit(project2_tree_path_root_ref) - end - - it 'uploads and commit a new file to a forked project', :js, :sidekiq_might_not_need_inline do - find('.add-to-tree').click - click_link('Upload file') - - expect(page).to have_content(fork_message) - - find('.add-to-tree').click - click_link('Upload file') - drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) - - page.within('#modal-upload-blob') do - fill_in(:commit_message, with: 'New commit message') - end - - click_button('Upload file') - expect(page).to have_content('New commit message') - - fork = user.fork_of(project2.reload) - - expect(current_path).to eq(project_new_merge_request_path(fork)) - - find("a[data-action='diffs']", text: 'Changes').click - - wait_for_requests - - expect(page).to have_content('Lorem ipsum dolor sit amet') - expect(page).to have_content('Sed ut perspiciatis unde omnis') + visit(project_tree_path(project2)) end + + include_examples 'it uploads and commit a new file to a forked project' end end diff --git a/spec/features/projects/show/user_uploads_files_spec.rb b/spec/features/projects/show/user_uploads_files_spec.rb new file mode 100644 index 00000000000..e279cdf92da --- /dev/null +++ b/spec/features/projects/show/user_uploads_files_spec.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Projects > Show > User uploads files' do + include DropzoneHelper + + let(:user) { create(:user) } + let(:project) { create(:project, :repository, name: 'Shop', creator: user) } + let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') } + + before do + project.add_maintainer(user) + sign_in(user) + end + + context 'when a user has write access' do + before do + visit(project_path(project)) + end + + include_examples 'it uploads and commit a new text file' + + include_examples 'it uploads and commit a new image file' + end + + context 'when a user does not have write access' do + before do + project2.add_reporter(user) + + visit(project_path(project2)) + end + + include_examples 'it uploads and commit a new file to a forked project' + end +end diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb index 6a04ca0eb67..becaa519728 100644 --- a/spec/finders/projects_finder_spec.rb +++ b/spec/finders/projects_finder_spec.rb @@ -85,6 +85,24 @@ describe ProjectsFinder, :do_not_mock_admin_mode do end end + describe 'regression: Combination of id_before/id_after and joins requires fully qualified column names' do + context 'only returns projects with a project id less than given and matching search' do + subject { finder.execute.joins(:route) } + + let(:params) { { id_before: public_project.id }} + + it { is_expected.to eq([internal_project]) } + end + + context 'only returns projects with a project id greater than given and matching search' do + subject { finder.execute.joins(:route) } + + let(:params) { { id_after: internal_project.id }} + + it { is_expected.to eq([public_project]) } + end + end + describe 'filter by visibility_level' do before do private_project.add_maintainer(user) diff --git a/spec/models/project_services/chat_notification_service_spec.rb b/spec/models/project_services/chat_notification_service_spec.rb index 64c7a9b230d..1caec5c6eb7 100644 --- a/spec/models/project_services/chat_notification_service_spec.rb +++ b/spec/models/project_services/chat_notification_service_spec.rb @@ -75,6 +75,30 @@ describe ChatNotificationService do end end + context 'with "channel" property' do + before do + allow(chat_service).to receive(:channel).and_return(channel) + end + + context 'empty string' do + let(:channel) { '' } + + it 'does not include the channel' do + expect(chat_service).to receive(:notify).with(any_args, hash_excluding(:channel)).and_return(true) + expect(chat_service.execute(data)).to be(true) + end + end + + context 'empty spaces' do + let(:channel) { ' ' } + + it 'does not include the channel' do + expect(chat_service).to receive(:notify).with(any_args, hash_excluding(:channel)).and_return(true) + expect(chat_service.execute(data)).to be(true) + end + end + end + shared_examples 'with channel specified' do |channel, expected_channels| before do allow(chat_service).to receive(:push_channel).and_return(channel) diff --git a/spec/services/projects/hashed_storage/migration_service_spec.rb b/spec/services/projects/hashed_storage/migration_service_spec.rb index f3ac26e7761..0a7975305dc 100644 --- a/spec/services/projects/hashed_storage/migration_service_spec.rb +++ b/spec/services/projects/hashed_storage/migration_service_spec.rb @@ -5,6 +5,11 @@ require 'spec_helper' describe Projects::HashedStorage::MigrationService do let(:project) { create(:project, :empty_repo, :wiki_repo, :legacy_storage) } let(:logger) { double } + let!(:project_attachment) { build(:file_uploader, project: project) } + let(:project_hashed_path) { Storage::Hashed.new(project).disk_path } + let(:project_legacy_path) { Storage::LegacyProject.new(project).disk_path } + let(:wiki_hashed_path) { "#{project_hashed_path}.wiki" } + let(:wiki_legacy_path) { "#{project_legacy_path}.wiki" } subject(:service) { described_class.new(project, project.full_path, logger: logger) } @@ -29,9 +34,24 @@ describe Projects::HashedStorage::MigrationService do service.execute end + + it 'migrates legacy repositories to hashed storage' do + legacy_attachments_path = FileUploader.absolute_base_dir(project) + hashed_project = project.dup.tap { |p| p.id = project.id } + hashed_project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:attachments] + hashed_attachments_path = FileUploader.absolute_base_dir(hashed_project) + + expect(logger).to receive(:info).with(/Repository moved from '#{project_legacy_path}' to '#{project_hashed_path}'/) + expect(logger).to receive(:info).with(/Repository moved from '#{wiki_legacy_path}' to '#{wiki_hashed_path}'/) + expect(logger).to receive(:info).with(/Project attachments moved from '#{legacy_attachments_path}' to '#{hashed_attachments_path}'/) + + expect { service.execute }.to change { project.storage_version }.from(nil).to(2) + end end context 'attachments migration' do + let(:project) { create(:project, :empty_repo, :wiki_repo, storage_version: ::Project::HASHED_STORAGE_FEATURES[:repository]) } + let(:attachments_service) do Projects::HashedStorage::MigrateAttachmentsService.new(project: project, old_disk_path: project.full_path, @@ -51,6 +71,17 @@ describe Projects::HashedStorage::MigrationService do service.execute end + + it 'migrates legacy attachments to hashed storage' do + legacy_attachments_path = FileUploader.absolute_base_dir(project) + hashed_project = project.dup.tap { |p| p.id = project.id } + hashed_project.storage_version = ::Project::HASHED_STORAGE_FEATURES[:attachments] + hashed_attachments_path = FileUploader.absolute_base_dir(hashed_project) + + expect(logger).to receive(:info).with(/Project attachments moved from '#{legacy_attachments_path}' to '#{hashed_attachments_path}'/) + + expect { service.execute }.to change { project.storage_version }.from(1).to(2) + end end end end diff --git a/spec/services/projects/hashed_storage/rollback_service_spec.rb b/spec/services/projects/hashed_storage/rollback_service_spec.rb index 48d4eac9eb7..e6b7daba99e 100644 --- a/spec/services/projects/hashed_storage/rollback_service_spec.rb +++ b/spec/services/projects/hashed_storage/rollback_service_spec.rb @@ -5,6 +5,11 @@ require 'spec_helper' describe Projects::HashedStorage::RollbackService do let(:project) { create(:project, :empty_repo, :wiki_repo) } let(:logger) { double } + let!(:project_attachment) { build(:file_uploader, project: project) } + let(:project_hashed_path) { Storage::Hashed.new(project).disk_path } + let(:project_legacy_path) { Storage::LegacyProject.new(project).disk_path } + let(:wiki_hashed_path) { "#{project_hashed_path}.wiki" } + let(:wiki_legacy_path) { "#{project_legacy_path}.wiki" } subject(:service) { described_class.new(project, project.disk_path, logger: logger) } @@ -26,6 +31,20 @@ describe Projects::HashedStorage::RollbackService do service.execute end + + it 'rollbacks to legacy storage' do + hashed_attachments_path = FileUploader.absolute_base_dir(project) + legacy_project = project.dup + legacy_project.storage_version = nil + legacy_attachments_path = FileUploader.absolute_base_dir(legacy_project) + + expect(logger).to receive(:info).with(/Project attachments moved from '#{hashed_attachments_path}' to '#{legacy_attachments_path}'/) + + expect(logger).to receive(:info).with(/Repository moved from '#{project_hashed_path}' to '#{project_legacy_path}'/) + expect(logger).to receive(:info).with(/Repository moved from '#{wiki_hashed_path}' to '#{wiki_legacy_path}'/) + + expect { service.execute }.to change { project.storage_version }.from(2).to(nil) + end end context 'repository rollback' do @@ -47,6 +66,13 @@ describe Projects::HashedStorage::RollbackService do service.execute end + + it 'rollbacks to legacy storage' do + expect(logger).to receive(:info).with(/Repository moved from '#{project_hashed_path}' to '#{project_legacy_path}'/) + expect(logger).to receive(:info).with(/Repository moved from '#{wiki_hashed_path}' to '#{wiki_legacy_path}'/) + + expect { service.execute }.to change { project.storage_version }.from(1).to(nil) + end end end end diff --git a/spec/support/shared_examples/features/project_upload_files_shared_examples.rb b/spec/support/shared_examples/features/project_upload_files_shared_examples.rb new file mode 100644 index 00000000000..25203fa3182 --- /dev/null +++ b/spec/support/shared_examples/features/project_upload_files_shared_examples.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +RSpec.shared_examples 'it uploads and commit a new text file' do + it 'uploads and commit a new text file', :js do + find('.add-to-tree').click + click_link('Upload file') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'New commit message') + end + + fill_in(:branch_name, with: 'upload_text', visible: true) + click_button('Upload file') + + expect(page).to have_content('New commit message') + expect(current_path).to eq(project_new_merge_request_path(project)) + + click_link('Changes') + find("a[data-action='diffs']", text: 'Changes').click + + wait_for_requests + + expect(page).to have_content('Lorem ipsum dolor sit amet') + expect(page).to have_content('Sed ut perspiciatis unde omnis') + end +end + +RSpec.shared_examples 'it uploads and commit a new image file' do + it 'uploads and commit a new image file', :js do + find('.add-to-tree').click + click_link('Upload file') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'logo_sample.svg')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'New commit message') + fill_in(:branch_name, with: 'upload_image', visible: true) + click_button('Upload file') + end + + wait_for_all_requests + + visit(project_blob_path(project, 'upload_image/logo_sample.svg')) + + expect(page).to have_css('.file-content img') + end +end + +RSpec.shared_examples 'it uploads and commit a new file to a forked project' do + let(:fork_message) do + "You're not allowed to make changes to this project directly. "\ + "A fork of this project has been created that you can make changes in, so you can submit a merge request." + end + + it 'uploads and commit a new file to a forked project', :js, :sidekiq_might_not_need_inline do + find('.add-to-tree').click + click_link('Upload file') + + expect(page).to have_content(fork_message) + + find('.add-to-tree').click + click_link('Upload file') + drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt')) + + page.within('#modal-upload-blob') do + fill_in(:commit_message, with: 'New commit message') + end + + click_button('Upload file') + + expect(page).to have_content('New commit message') + + fork = user.fork_of(project2.reload) + + expect(current_path).to eq(project_new_merge_request_path(fork)) + + find("a[data-action='diffs']", text: 'Changes').click + + wait_for_requests + + expect(page).to have_content('Lorem ipsum dolor sit amet') + expect(page).to have_content('Sed ut perspiciatis unde omnis') + end +end diff --git a/spec/uploaders/file_uploader_spec.rb b/spec/uploaders/file_uploader_spec.rb index efdbea85d4a..5fd64da6328 100644 --- a/spec/uploaders/file_uploader_spec.rb +++ b/spec/uploaders/file_uploader_spec.rb @@ -145,11 +145,39 @@ describe FileUploader do end describe '.extract_dynamic_path' do - it 'works with hashed storage' do - path = 'export/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/test/uploads/72a497a02fe3ee09edae2ed06d390038/dummy.txt' + context 'with a 32-byte hexadecimal secret in the path' do + let(:secret) { SecureRandom.hex } + let(:path) { "export/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/test/uploads/#{secret}/dummy.txt" } - expect(described_class.extract_dynamic_path(path)[:identifier]).to eq('dummy.txt') - expect(described_class.extract_dynamic_path(path)[:secret]).to eq('72a497a02fe3ee09edae2ed06d390038') + it 'extracts the secret' do + expect(described_class.extract_dynamic_path(path)[:secret]).to eq(secret) + end + + it 'extracts the identifier' do + expect(described_class.extract_dynamic_path(path)[:identifier]).to eq('dummy.txt') + end + end + + context 'with a 10-byte hexadecimal secret in the path' do + let(:secret) { SecureRandom.hex(10) } + let(:path) { "export/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/test/uploads/#{secret}/dummy.txt" } + + it 'extracts the secret' do + expect(described_class.extract_dynamic_path(path)[:secret]).to eq(secret) + end + + it 'extracts the identifier' do + expect(described_class.extract_dynamic_path(path)[:identifier]).to eq('dummy.txt') + end + end + + context 'with an invalid secret in the path' do + let(:secret) { 'foo' } + let(:path) { "export/4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a/test/uploads/#{secret}/dummy.txt" } + + it 'returns nil' do + expect(described_class.extract_dynamic_path(path)).to be_nil + end end end diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore index 259148fa18f..259148fa18f 100644..100755 --- a/vendor/gitignore/C++.gitignore +++ b/vendor/gitignore/C++.gitignore diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore index a1c2a238a96..a1c2a238a96 100644..100755 --- a/vendor/gitignore/Java.gitignore +++ b/vendor/gitignore/Java.gitignore |