diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index e06a5ceced045c0612723daad369a7875dd74312..55a20d1eec2cdbfd788c714ebea6fae395c8f4ba 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -186,6 +186,7 @@ ohos_shared_library("fs") { external_deps = [ "hilog:libhilog", "napi:ace_napi", + "access_token:libtokenid_sdk", ] if (!use_mingw_win && !use_mac) { diff --git a/interfaces/kits/js/src/mod_fs/common_func.cpp b/interfaces/kits/js/src/mod_fs/common_func.cpp index 7e225d298c998b2735422f813e8eec738bae3afc..fe20a82fbdcfc7b40600d629f816f2a4fbeacba0 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.cpp +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -34,6 +34,8 @@ #include "filemgmt_libhilog.h" #include "filemgmt_libn.h" #include "file_utils.h" +#include "ipc_skeleton.h" +#include "tokenid_kit.h" namespace OHOS { namespace FileManagement { @@ -345,6 +347,62 @@ string CommonFunc::Decode(const std::string &uri) return outPutStream.str(); } +bool IsNumeric(const std::string &str) +{ + if (str.empty()) { + return false; + } + for (char const &c : str) { + if (!isdigest(c)) { + retrun false; + } + return true; + } +} + +void SetQueryMap(Uri* uri, std::unordered_map &queryMap) +{ + // file://media/image/12?networkid=xxxx&api_version=xxxx + string query = uri->GetQuery(); + string pairString; + stringstream queryStream(query); + + while (getline(queryStream, pairString, '&')) { + size_t splitIndex = pairString.find('='); + if (splitIndex == string::npos || splitIndex == (pairString.length() - 1)) { + HILOGE("failed to parse query, query field is %{private}s!", pairString.c_str()); + continue; + } + queryMap[pairString.substr(0, splitIndex)] = pairString.substr(splitIndex + 1); + } + return; +} + +bool CommonFunc::GetAndCheckUserId(Uri* uri, string &userId) +{ + std::unordered_map queryMap; + SetQueryMap(uri, queryMap); + auto it = queryMap.find("user"); + if (it != queryMap.end()) { + userId = it->second; + if (!IsNumeric(userId)) { + HILOGE("IsNumeric check fail, userId = %{public}s", userId.c_str()); + return false; + } + return true; + } else { + HILOGE("GetAndCheckUserId no match userId"); + } + return false; +} + +bool IsSystemApp() +{ + uint64_t fullTokenId = OHOS::IPCSkeleton::GetCallingFullTokenID(); + return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId); +} + tuple, unique_ptr> CommonFunc::GetCopyPathArg(napi_env env, napi_value srcPath, napi_value dstPath) diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h index 1fa132f271190f4d1ffa88e7f0fd5de8fb71b3a6..e0e8c1fdbf80533a2ee6f305ab799b8c40fc7e73 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -21,6 +21,7 @@ #include "uv.h" #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) #include "iremote_broker.h" +#include "file_uri.h" #endif namespace OHOS { @@ -101,6 +102,8 @@ struct CommonFunc { static std::string GetModeFromFlags(unsigned int flags); static bool CheckPublicDirPath(const std::string &sandboxPath); static std::string Decode(const std::string &uri); + static bool GetAndCheckUserId(Uri* uri, std:string &userId); + static bool IsSystemApp(); }; } // namespace ModuleFileIO } // namespace FileManagement diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 9c0f766ff2dd90bbfc3daaea6e98abb753309a96..b2b63cb1252aea222ce512bd5d5e61b807d96fe0 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -41,6 +41,7 @@ #include "system_ability_definition.h" #include "trans_listener.h" #include "utils_log.h" +#include "common_func.h" namespace OHOS { namespace FileManagement { @@ -71,7 +72,12 @@ static int OpenSrcFile(const string &srcPth, std::shared_ptr infos, i HILOGE("Failed to get remote object"); return ENOMEM; } - dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + if (CommonFunc::GetAndCheckUserId(&uri, userId) && CommonFunc::IsSystemApp()) { + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), + MEDIALIBRARY_DATA_URI + "?user=" + userId); + } else { + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), MEDIALIBRARY_DATA_URI); + } if (!dataShareHelper) { HILOGE("Failed to connect to datashare"); return E_PERMISSION; diff --git a/interfaces/kits/js/src/mod_fs/properties/open.cpp b/interfaces/kits/js/src/mod_fs/properties/open.cpp index 922467cd76def3dff8536d732a0e7b6bfd9dcb61..7b5280059ddbd6bea3b4cdcd5608e45565439d64 100644 --- a/interfaces/kits/js/src/mod_fs/properties/open.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/open.cpp @@ -148,6 +148,26 @@ static int OpenFileByPath(const string &path, unsigned int mode) #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +static int OpenFileByDatashareHasUserId(const string &path, unsigned int flags, const string &userId) +{ + std::shared_ptr dataShareHelper = nullptr; + sptr remote = new (std::nothrow) IRemoteStub(); + if (!remote) { + HILOGE("Failed to get remote object"); + return -ENOMEM; + } + + dataShareHelper = DataShare::DataShareHelper::Creator(remote->AsObject(), + MEDIALIBRARY_DATA_URI + "?user=" + userId); + if (!dataShareHelper) { + HILOGE("Failed to connect to datashare"); + return -E_PERMISSION; + } + Uri uri(path); + int fd = dataShareHelper->OpenFile(uri, CommonFunc::GetModeFromFlags(flags)); + return fd; +} + static int OpenFileByDatashare(const string &path, unsigned int flags) { std::shared_ptr dataShareHelper = nullptr; @@ -173,11 +193,20 @@ static tuple OpenByFileDataUri(Uri &uri, const string &uriStr, unsi AppFileService::ModuleFileUri::FileUri fileUri(uriStr); string realPath = fileUri.GetRealPath(); if (bundleName == MEDIA) { - int res = OpenFileByDatashare(uri.ToString(), mode); - if (res < 0) { - HILOGE("Failed to open file by Datashare error %{public}d", res); + string userId; + if (CommonFunc::GetAndCheckUserId(&uri, userId) && CommonFunc::IsSystemApp()) { + int res = OpenFileByDatashareHasUserId(uri.ToString(), mode, userId); + if (res < 0) { + HILOGE("Failed to open file by DatashareHasUserId error %{public}d", res); + } + return { res, uri.ToString() }; + } else { + int res = OpenFileByDatashare(uri.ToString(), mode); + if (res < 0) { + HILOGE("Failed to open file by Datashare error %{public}d", res); + } + return { res, uri.ToString() }; } - return { res, uri.ToString() }; } else if (bundleName == DOCS && access(realPath.c_str(), F_OK) != 0) { int res = OpenFileByDatashare(uri.ToString(), mode); if (res < 0) {