Skip to content

Commit

Permalink
Merge pull request #14405 from opf/task/51538-use-ensure_connection-t…
Browse files Browse the repository at this point in the history
…o-open-storage-from-files-tab

[#51538] Use ensure_connection to open storage from files tab
  • Loading branch information
ba1ash authored Dec 18, 2023
2 parents 2223865 + e6f4381 commit 9495dc5
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 31 deletions.
21 changes: 19 additions & 2 deletions docs/api/apiv3/components/schemas/project_storage_model.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,27 @@ properties:
allOf:
- $ref: './link.yml'
- description: |-
The directory on the storage that is used as a manual project folder.
The directory on the storage that is used as a project folder.
**Resource**: StorageFile
# Conditions
Only provided, if the `projectFolderMode` is set to `manual`.
Only provided, if the `projectFolderMode` is `manual` or `automatic`.
open:
allOf:
- $ref: './link.yml'
- description: |-
A link to open project strorage.
openWithConnectionEnsured:
allOf:
- $ref: './link.yml'
- description: |-
A link to open project storage with making sure user has access to it.
# Conditions
If the storage has not been configured(oauth client is missing, for instance), then the link is null.
example:
_type: 'ProjectStorage'
id: 1337
Expand All @@ -97,3 +110,7 @@ example:
storage:
title: "Palpatine's Data Vault"
href: '/api/v3/storages/81'
open:
href: '/api/v3/storages/81/open'
openWithConnectionEnsured:
href: '/oauth_clients/123/ensure_connection?destination_url=https%3A%2F%2Fopenproject.local%2Fprojects%2Fdeath-star%2Fproject_storages%2F23%2Fopen&storage_id=81'
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class="op-tab-content--header-action spot-link"
aria-label="{{text.openStorage(storageType | async)}}"
[title]="text.openStorage(storageType | async)"
[href]="(storage | async)?._links.open.href"
[href]="projectStorage._links.openWithConnectionEnsured.href || (storage | async)?._links.open.href"
target="_blank"
>
<span class="spot-icon spot-icon_external-link"></span>
Expand Down
17 changes: 17 additions & 0 deletions modules/storages/app/models/storages/project_storage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ def open(user)
end
end

def open_with_connection_ensured
return unless storage.configured?

url_helpers = Rails.application.routes.url_helpers
open_project_storage_url = url_helpers.open_project_storage_url(
host: Setting.host_name,
protocol: 'https',
project_id: project.identifier,
id:
)
url_helpers.oauth_clients_ensure_connection_path(
oauth_client_id: storage.oauth_client.client_id,
storage_id: storage.id,
destination_url: open_project_storage_url
)
end

private

def escape_path(path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class ProjectStorageRepresenter < ::API::Decorators::Single
{ href: api_v3_paths.project_storage_open(represented.id) }
end

link :openWithConnectionEnsured do
{ href: represented.open_with_connection_ensured }
end

associated_resource :storage, skip_render: ->(*) { true }, skip_link: ->(*) { false }
associated_resource :project, skip_render: ->(*) { true }, skip_link: ->(*) { false }
associated_resource :creator,
Expand Down
15 changes: 1 addition & 14 deletions modules/storages/lib/open_project/storages/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,23 +160,10 @@ def self.permissions
storage = project_storage.storage
next unless storage.configured?

url_helpers = Rails.application.routes.url_helpers
open_project_storage_url = url_helpers.open_project_storage_url(
host: Setting.host_name,
protocol: 'https',
project_id: project_storage.project.identifier,
id: project_storage.id
)
href = url_helpers.oauth_clients_ensure_connection_path(
oauth_client_id: storage.oauth_client.client_id,
storage_id: storage.id,
destination_url: open_project_storage_url
)
icon = storage.provider_type_nextcloud? ? 'nextcloud-circle' : 'hosting'

menu.push(
:"storage_#{storage.id}",
href,
project_storage.open_with_connection_ensured,
caption: storage.name,
before: :members,
icon:,
Expand Down
18 changes: 4 additions & 14 deletions modules/storages/spec/features/storages_menu_links_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
require_module_spec_helper

RSpec.describe 'Storage links in project menu', :js do
include EnsureConnectionPathHelper

let!(:storage_configured_linked1) { create(:nextcloud_storage_configured, name: "Storage 1") }
let!(:project_storage1) { create(:project_storage, project:, storage: storage_configured_linked1) }
let!(:storage_configured_linked2) { create(:nextcloud_storage_configured, name: "Storage 2") }
Expand All @@ -48,24 +50,12 @@
visit(project_path(project))
end

def href(project_storage)
oauth_clients_ensure_connection_path(
oauth_client_id: project_storage.storage.oauth_client.client_id,
storage_id: project_storage.storage.id,
destination_url: open_project_storage_url(
protocol: 'https',
project_id: project_storage.project.identifier,
id: project_storage.id
)
)
end

context 'if user has permission to see storage links' do
it 'has links to enabled storages' do
visit(project_path(id: project.id))

expect(page).to have_link(storage_configured_linked1.name, href: href(project_storage1))
expect(page).to have_link(storage_configured_linked2.name, href: href(project_storage2))
expect(page).to have_link(storage_configured_linked1.name, href: ensure_connection_path(project_storage1))
expect(page).to have_link(storage_configured_linked2.name, href: ensure_connection_path(project_storage2))
expect(page).not_to have_link(storage_configured_unlinked.name)
expect(page).not_to have_link(storage_unconfigured_linked.name)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

RSpec.describe API::V3::ProjectStorages::ProjectStorageRepresenter do
include API::V3::Utilities::PathHelper
include EnsureConnectionPathHelper

let(:user) { build_stubbed(:user) }

Expand Down Expand Up @@ -85,5 +86,26 @@
let(:link) { 'projectFolder' }
let(:href) { api_v3_paths.storage_file(project_storage.storage.id, project_storage.project_folder_id) }
end

it_behaves_like 'has an untitled link' do
let(:link) { 'open' }
let(:href) { api_v3_paths.project_storage_open(project_storage.id) }
end

context 'when storage is not configured' do
it_behaves_like 'has an untitled link' do
let(:link) { 'openWithConnectionEnsured' }
let(:href) { nil }
end
end

context 'when storage is not configured' do
before { project_storage.storage = create(:nextcloud_storage_configured) }

it_behaves_like 'has an untitled link' do
let(:link) { 'openWithConnectionEnsured' }
let(:href) { ensure_connection_path(project_storage) }
end
end
end
end
43 changes: 43 additions & 0 deletions modules/storages/spec/support/ensure_connection_path_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module EnsureConnectionPathHelper
def ensure_connection_path(project_storage)
oauth_clients_ensure_connection_path(
oauth_client_id: project_storage.storage.oauth_client.client_id,
storage_id: project_storage.storage.id,
destination_url: open_project_storage_url(
protocol: 'https',
project_id: project_storage.project.identifier,
id: project_storage.id
)
)
end
end

0 comments on commit 9495dc5

Please sign in to comment.