Skip to content

Commit

Permalink
Merge pull request #14345 from opf/feature/50437-ensuring-connection-…
Browse files Browse the repository at this point in the history
…and-permissions-on-project-folder-while-redirecting-users-to-nextcloudonedrive-from-project-menu

[#50437] Handle cases when project_folder_id is empty.
  • Loading branch information
ba1ash authored Dec 7, 2023
2 parents fcbaad2 + 420f4c7 commit 0705994
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,27 @@ def open
if @object.project_folder_automatic?
storage = @object.storage
# check if user "see" project_folder
::Storages::Peripherals::Registry
.resolve("queries.#{storage.short_provider_type}.file_info")
.call(storage:,
user: current_user,
file_id: @object.project_folder_id)
.match(
on_success: user_can_read_project_folder(storage_open_url:),
on_failure: user_can_not_read_project_folder(storage:, storage_open_url:)
)
if @object.project_folder_id.present?
::Storages::Peripherals::Registry
.resolve("queries.#{storage.short_provider_type}.file_info")
.call(storage:,
user: current_user,
file_id: @object.project_folder_id)
.match(
on_success: user_can_read_project_folder(storage_open_url:),
on_failure: user_can_not_read_project_folder(storage:, storage_open_url:)
)
else
respond_to do |format|
format.turbo_stream { head :no_content }
format.html do
redirect_to_project_overview_with_modal(
project_identifier: @project.identifier,
storage_open_url:
)
end
end
end
else
redirect_to storage_open_url
end
Expand Down Expand Up @@ -93,22 +105,29 @@ def user_can_not_read_project_folder(storage_open_url:, storage:)
)
)
when :forbidden
redirect_to(
project_overview_path(project_id: @project.identifier),
flash: {
modal: {
type: 'Storages::OpenProjectStorageModalComponent',
parameters: {
project_storage_open_url: request.path,
redirect_url: storage_open_url,
state: :waiting
}
}
}
redirect_to_project_overview_with_modal(
project_identifier: @project.identifier,
storage_open_url:
)
end
end
end
end
end

def redirect_to_project_overview_with_modal(project_identifier:, storage_open_url:)
redirect_to(
project_overview_path(project_id: project_identifier),
flash: {
modal: {
type: 'Storages::OpenProjectStorageModalComponent',
parameters: {
project_storage_open_url: request.path,
redirect_url: storage_open_url,
state: :waiting
}
}
}
)
end
end
136 changes: 84 additions & 52 deletions modules/storages/spec/requests/project_storages_open_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,77 +44,109 @@
context 'when project_folder is automatic' do
let(:project_storage) { create(:project_storage, :as_automatically_managed, project:, storage:) }

context 'when user is able to read project_folder' do
before do
Storages::Peripherals::Registry.stub(
'queries.nextcloud.file_info', ->(_) { ServiceResult.success }
)
end
context 'when project_folder_id has been set by background job already' do
before { project_storage.update_attribute(:project_folder_id, '123') }

context 'when user is able to read project_folder' do
before do
Storages::Peripherals::Registry.stub(
'queries.nextcloud.file_info', ->(_) { ServiceResult.success }
)
end

context 'html' do
it 'redirects to storage_open_url' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }
context 'html' do
it 'redirects to storage_open_url' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }

expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq ("#{storage.host}/index.php/apps/files")
expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq ("#{storage.host}/index.php/apps/files")
end
end
end

context 'turbo_stream' do
it 'renders an appropirate turbo_stream' do
get route, {}, { 'HTTP_ACCEPT' => 'text/vnd.turbo-stream.html' }
context 'turbo_stream' do
it 'renders an appropirate turbo_stream' do
get route, {}, { 'HTTP_ACCEPT' => 'text/vnd.turbo-stream.html' }

expect(last_response.status).to eq (200)
expect(last_response.body).to eq ("<turbo-stream action=\"update\" target=\"open-project-storage-modal-body-component\">\n <template>\n <div data-view-component=\"true\" class=\"flex-items-center d-flex flex-column\">\n <div data-view-component=\"true\"> <svg aria-hidden=\"true\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" width=\"24\" data-view-component=\"true\" class=\"octicon octicon-check-circle color-fg-success\">\n <path d=\"M17.28 9.28a.75.75 0 0 0-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l6.5-6.5Z\"></path><path d=\"M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z\"></path>\n</svg>\n</div>\n <div data-view-component=\"true\"> <span data-view-component=\"true\">Integration setup completed</span>\n</div>\n <div data-view-component=\"true\"> <span data-view-component=\"true\">You are being redirected</span>\n</div>\n</div>\n\n\n </template>\n</turbo-stream>\n\n")
expect(last_response.status).to eq (200)
expect(last_response.body).to eq ("<turbo-stream action=\"update\" target=\"open-project-storage-modal-body-component\">\n <template>\n <div data-view-component=\"true\" class=\"flex-items-center d-flex flex-column\">\n <div data-view-component=\"true\"> <svg aria-hidden=\"true\" height=\"24\" viewBox=\"0 0 24 24\" version=\"1.1\" width=\"24\" data-view-component=\"true\" class=\"octicon octicon-check-circle color-fg-success\">\n <path d=\"M17.28 9.28a.75.75 0 0 0-1.06-1.06l-5.97 5.97-2.47-2.47a.75.75 0 0 0-1.06 1.06l3 3a.75.75 0 0 0 1.06 0l6.5-6.5Z\"></path><path d=\"M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z\"></path>\n</svg>\n</div>\n <div data-view-component=\"true\"> <span data-view-component=\"true\">Integration setup completed</span>\n</div>\n <div data-view-component=\"true\"> <span data-view-component=\"true\">You are being redirected</span>\n</div>\n</div>\n\n\n </template>\n</turbo-stream>\n\n")
end
end
end
end

context 'when user is not able to read project_folder' do
let(:code) { :forbidden }
context 'when user is not able to read project_folder' do
let(:code) { :forbidden }

before do
Storages::Peripherals::Registry.stub(
'queries.nextcloud.file_info', ->(_) do
ServiceResult.failure(result: code,
errors: Storages::StorageError.new(code:))
end
)
end
before do
Storages::Peripherals::Registry.stub(
'queries.nextcloud.file_info', ->(_) do
ServiceResult.failure(result: code,
errors: Storages::StorageError.new(code:))
end
)
end

context 'html' do
context 'when error code is unauthorized' do
let(:code) { :unauthorized }
context 'html' do
context 'when error code is unauthorized' do
let(:code) { :unauthorized }

it 'redirects to ensure_connection url with current request url as a destination_url' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }
it 'redirects to ensure_connection url with current request url as a destination_url' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }

expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq (
"http://example.org/oauth_clients/#{storage.oauth_client.client_id}/ensure_connection?destination_url=http%3A%2F%2Fexample.org%2Fprojects%2F#{project.identifier}%2Fproject_storages%2F#{project_storage.id}%2Fopen&storage_id=#{storage.id}"
)
expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq (
"http://example.org/oauth_clients/#{storage.oauth_client.client_id}/ensure_connection?destination_url=http%3A%2F%2Fexample.org%2Fprojects%2F#{project.identifier}%2Fproject_storages%2F#{project_storage.id}%2Fopen&storage_id=#{storage.id}"
)
end
end

context 'when error code is forbidden' do
it 'redirects to project overview page with modal flash set up' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }

expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq ("http://example.org/projects/#{project.identifier}")
expect(last_request.session['flash']['flashes'])
.to eq({
"modal" => {
type: "Storages::OpenProjectStorageModalComponent",
parameters: { project_storage_open_url: "/projects/#{project.identifier}/project_storages/#{project_storage.id}/open",
redirect_url: "#{storage.host}/index.php/apps/files",
state: :waiting }
}
})
end
end
end

context 'when error code is forbidden' do
it 'redirects to project overview page with modal flash set up' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }
context 'turbo_stream' do
it 'responds with 204 no content' do
get route, {}, { 'HTTP_ACCEPT' => 'text/vnd.turbo-stream.html' }

expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq ("http://example.org/projects/#{project.identifier}")
expect(last_response.headers["Location"]).to eq ("http://example.org/projects/#{project.identifier}")
expect(last_request.session['flash']['flashes'])
.to eq({
"modal" => {
type: "Storages::OpenProjectStorageModalComponent",
parameters: { project_storage_open_url: "/projects/#{project.identifier}/project_storages/#{project_storage.id}/open",
redirect_url: "#{storage.host}/index.php/apps/files",
state: :waiting }
}
})
expect(last_response.status).to eq (204)
expect(last_response.body).to eq ("")
end
end
end
end

context 'when project_folder_id has not been set by background job yet' do
context 'html' do
it 'redirects to project overview page with modal flash set up' do
get route, {}, { 'HTTP_ACCEPT' => 'text/html' }

expect(last_response.status).to eq (302)
expect(last_response.headers["Location"]).to eq ("http://example.org/projects/#{project.identifier}")
expect(last_request.session['flash']['flashes'])
.to eq({
"modal" => {
type: "Storages::OpenProjectStorageModalComponent",
parameters: { project_storage_open_url: "/projects/#{project.identifier}/project_storages/#{project_storage.id}/open",
redirect_url: "#{storage.host}/index.php/apps/files",
state: :waiting }
}
})
end
end

context 'turbo_stream' do
it 'responds with 204 no content' do
Expand Down

0 comments on commit 0705994

Please sign in to comment.