From 801a336a9e017e9d09df1493eb21d2c46d1934b3 Mon Sep 17 00:00:00 2001 From: Szabolcs David Date: Mon, 19 Dec 2022 16:36:29 +0100 Subject: Fix opening files with File System Access API Chrome interprets accepting file picker dialog as a user consent and grants access permission to the selected files automatically. We have to do the same since we don't get any permission request in this case anymore. This issue did not affect directory picker and file saver modes. Also add AncestorHasActivePermission() check, it seems to be effective to not request permission again for the same file if the parent dir was already pulled in by this API. Change-Id: Id73d8fc6e9bd518692362133f3dafa472f0e97a1 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 01728421d641ffac98a85b408167db478b253458) Reviewed-by: Peter Varga --- .../file_system_access_permission_context_qt.cpp | 62 ++++++++++++++++++++-- .../file_system_access_permission_context_qt.h | 3 ++ 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.cpp b/src/core/file_system_access/file_system_access_permission_context_qt.cpp index 3a9c80288..0eb57adde 100644 --- a/src/core/file_system_access/file_system_access_permission_context_qt.cpp +++ b/src/core/file_system_access/file_system_access_permission_context_qt.cpp @@ -204,8 +204,6 @@ FileSystemAccessPermissionContextQt::GetReadPermissionGrant(const url::Origin &o HandleType handle_type, UserAction user_action) { - Q_UNUSED(user_action); - auto &origin_state = m_origins[origin]; auto *&existing_grant = origin_state.read_grants[path]; scoped_refptr new_grant; @@ -224,6 +222,27 @@ FileSystemAccessPermissionContextQt::GetReadPermissionGrant(const url::Origin &o existing_grant = new_grant.get(); } + // If a parent directory is already readable this new grant should also be readable. + if (new_grant && AncestorHasActivePermission(origin, path, GrantType::kRead)) { + existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED); + return existing_grant; + } + + switch (user_action) { + case UserAction::kOpen: + case UserAction::kSave: + // Open and Save dialog only grant read access for individual files. + if (handle_type == HandleType::kDirectory) + break; + Q_FALLTHROUGH(); + case UserAction::kDragAndDrop: + // Drag&drop grants read access for all handles. + existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED); + break; + case UserAction::kLoadFromStorage: + break; + } + return existing_grant; } @@ -233,8 +252,6 @@ FileSystemAccessPermissionContextQt::GetWritePermissionGrant(const url::Origin & HandleType handle_type, UserAction user_action) { - Q_UNUSED(user_action); - auto &origin_state = m_origins[origin]; auto *&existing_grant = origin_state.write_grants[path]; scoped_refptr new_grant; @@ -253,6 +270,23 @@ FileSystemAccessPermissionContextQt::GetWritePermissionGrant(const url::Origin & existing_grant = new_grant.get(); } + // If a parent directory is already writable this new grant should also be writable. + if (new_grant && AncestorHasActivePermission(origin, path, GrantType::kWrite)) { + existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED); + return existing_grant; + } + + switch (user_action) { + case UserAction::kSave: + // Only automatically grant write access for save dialogs. + existing_grant->SetStatus(blink::mojom::PermissionStatus::GRANTED); + break; + case UserAction::kOpen: + case UserAction::kDragAndDrop: + case UserAction::kLoadFromStorage: + break; + } + return existing_grant; } @@ -392,4 +426,24 @@ void FileSystemAccessPermissionContextQt::DidConfirmSensitiveDirectoryAccess( std::move(callback).Run(SensitiveDirectoryResult::kAllowed); } +bool FileSystemAccessPermissionContextQt::AncestorHasActivePermission( + const url::Origin &origin, const base::FilePath &path, GrantType grant_type) const +{ + auto it = m_origins.find(origin); + if (it == m_origins.end()) + return false; + + const auto &relevant_grants = grant_type == GrantType::kWrite ? it->second.write_grants : it->second.read_grants; + if (relevant_grants.empty()) + return false; + + // Permissions are inherited from the closest ancestor. + for (base::FilePath parent = path.DirName(); parent != parent.DirName(); parent = parent.DirName()) { + auto i = relevant_grants.find(parent); + if (i != relevant_grants.end() && i->second && i->second->GetStatus() == blink::mojom::PermissionStatus::GRANTED) + return true; + } + return false; +} + } // namespace QtWebEngineCore diff --git a/src/core/file_system_access/file_system_access_permission_context_qt.h b/src/core/file_system_access/file_system_access_permission_context_qt.h index 722e44d14..3c6ffeb40 100644 --- a/src/core/file_system_access/file_system_access_permission_context_qt.h +++ b/src/core/file_system_access/file_system_access_permission_context_qt.h @@ -61,6 +61,9 @@ private: const url::Origin &origin, const base::FilePath &path, HandleType handle_type, content::GlobalRenderFrameHostId frame_id, base::OnceCallback callback, bool should_block); + bool AncestorHasActivePermission(const url::Origin &origin, + const base::FilePath &path, + GrantType grant_type) const; content::BrowserContext *m_profile; -- cgit v1.2.1