From 01728421d641ffac98a85b408167db478b253458 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. Pick-to: 6.4 6.5 Change-Id: Id73d8fc6e9bd518692362133f3dafa472f0e97a1 Reviewed-by: Allan Sandfeld Jensen --- .../file_system_access_permission_context_qt.cpp | 62 ++++++++++++++++++++-- .../file_system_access_permission_context_qt.h | 3 ++ 2 files changed, 61 insertions(+), 4 deletions(-) (limited to 'src') 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 a8406c8ae..bc88f7898 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; } @@ -394,6 +428,26 @@ void FileSystemAccessPermissionContextQt::DidConfirmSensitiveDirectoryAccess( std::move(callback).Run(SensitiveEntryResult::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; +} + std::u16string FileSystemAccessPermissionContextQt::GetPickerTitle(const blink::mojom::FilePickerOptionsPtr &) { return {}; 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 713239525..29fefee24 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 @@ -63,6 +63,9 @@ private: const url::Origin &origin, const base::FilePath &path, HandleType handle_type, UserAction user_action, 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.3