1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "environment_n_exporter.h" 17 #include "accesstoken_kit.h" 18 #include "account_error_no.h" 19 #include "filemgmt_libhilog.h" 20 #include "ipc_skeleton.h" 21 #include "os_account_manager.h" 22 #include "parameter.h" 23 #include "tokenid_kit.h" 24 #include <string> 25 #include <unistd.h> 26 namespace OHOS { 27 namespace FileManagement { 28 namespace ModuleEnvironment { 29 using namespace OHOS::FileManagement::LibN; 30 namespace { 31 const std::string STORAGE_DATA_PATH = "/data"; 32 const std::string PC_STORAGE_PATH = "/storage/Users/"; 33 const std::string EXTERNAL_STORAGE_PATH = "/storage/External"; 34 const std::string USER_APP_DATA_PATH = "/appdata"; 35 const std::string READ_WRITE_DOWNLOAD_PERMISSION = "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY"; 36 const std::string READ_WRITE_DESKTOP_PERMISSION = "ohos.permission.READ_WRITE_DESKTOP_DIRECTORY"; 37 const std::string READ_WRITE_DOCUMENTS_PERMISSION = "ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY"; 38 const std::string FILE_ACCESS_MANAGER_PERMISSION = "ohos.permission.FILE_ACCESS_MANAGER"; 39 const std::string DOWNLOAD_PATH = "/Download"; 40 const std::string DESKTOP_PATH = "/Desktop"; 41 const std::string DOCUMENTS_PATH = "/Documents"; 42 const std::string DEFAULT_USERNAME = "currentUser"; 43 const char *g_fileManagerFullMountEnableParameter = "const.filemanager.full_mount.enable"; IsSystemApp()44 static bool IsSystemApp() 45 { 46 uint64_t fullTokenId = OHOS::IPCSkeleton::GetCallingFullTokenID(); 47 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId); 48 } 49 CheckCallingPermission(const std::string & permission)50 static bool CheckCallingPermission(const std::string &permission) 51 { 52 Security::AccessToken::AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID(); 53 int res = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenCaller, permission); 54 if (res != Security::AccessToken::PermissionState::PERMISSION_GRANTED) { 55 HILOGE("ModuleUserDirectory::CheckCallingPermission have no fileAccess permission"); 56 return false; 57 } 58 return true; 59 } 60 GetUserName()61 static std::string GetUserName() 62 { 63 std::string userName; 64 ErrCode errCode = OHOS::AccountSA::OsAccountManager::GetOsAccountShortName(userName); 65 if (errCode != ERR_OK || userName.empty()) { 66 HILOGE("Get userName Failed"); 67 } 68 userName = DEFAULT_USERNAME; 69 return userName; 70 } 71 GetPublicPath(const std::string & directoryName)72 static std::string GetPublicPath(const std::string &directoryName) 73 { 74 return PC_STORAGE_PATH + GetUserName() + directoryName; 75 } 76 CheckFileManagerFullMountEnable()77 static bool CheckFileManagerFullMountEnable() 78 { 79 char value[] = "false"; 80 int retSystem = GetParameter(g_fileManagerFullMountEnableParameter, "false", value, sizeof(value)); 81 if (retSystem > 0 && !std::strcmp(value, "true")) { 82 return true; 83 } 84 HILOGE("Not supporting all mounts"); 85 return false; 86 } 87 CheckInvalidAccess(const std::string & permission,napi_env env)88 static bool CheckInvalidAccess(const std::string &permission, napi_env env) 89 { 90 if (!CheckFileManagerFullMountEnable()) { 91 HILOGE("Capability not supported"); 92 NError(E_DEVICENOTSUPPORT).ThrowErr(env); 93 return true; 94 } 95 if (permission == FILE_ACCESS_MANAGER_PERMISSION) { 96 if (!IsSystemApp()) { 97 NError(E_PERMISSION_SYS).ThrowErr(env); 98 return true; 99 } 100 } 101 if (!CheckCallingPermission(permission)) { 102 HILOGE("No Permission"); 103 NError(E_PERMISSION).ThrowErr(env); 104 return true; 105 } 106 return false; 107 } 108 } 109 GetStorageDataDir(napi_env env,napi_callback_info info)110 napi_value GetStorageDataDir(napi_env env, napi_callback_info info) 111 { 112 if (!IsSystemApp()) { 113 NError(E_PERMISSION_SYS).ThrowErr(env); 114 return nullptr; 115 } 116 NFuncArg funcArg(env, info); 117 if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { 118 HILOGE("Number of arguments unmatched"); 119 NError(EINVAL).ThrowErr(env); 120 return nullptr; 121 } 122 123 auto cbExec = []() -> NError { 124 return NError(ERRNO_NOERR); 125 }; 126 auto cbComplete = [](napi_env env, NError err) -> NVal { 127 if (err) { 128 return { env, err.GetNapiErr(env) }; 129 } 130 return NVal::CreateUTF8String(env, STORAGE_DATA_PATH); 131 }; 132 133 static const std::string PROCEDURE_NAME = "GetStorageDataDir"; 134 NVal thisVar(env, funcArg.GetThisVar()); 135 if (funcArg.GetArgc() == NARG_CNT::ZERO) { 136 return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_; 137 } 138 139 NVal cb(env, funcArg[NARG_POS::FIRST]); 140 return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_; 141 } 142 GetUserId()143 int GetUserId() 144 { 145 return 0; 146 } 147 GetUserDataDir(napi_env env,napi_callback_info info)148 napi_value GetUserDataDir(napi_env env, napi_callback_info info) 149 { 150 if (!IsSystemApp()) { 151 NError(E_PERMISSION_SYS).ThrowErr(env); 152 return nullptr; 153 } 154 NFuncArg funcArg(env, info); 155 if (!funcArg.InitArgs(NARG_CNT::ZERO, NARG_CNT::ONE)) { 156 HILOGE("Number of arguments unmatched"); 157 NError(EINVAL).ThrowErr(env); 158 return nullptr; 159 } 160 161 auto userDataPath = std::make_shared<std::string>(); 162 auto cbExec = [userDataPath]() -> NError { 163 (*userDataPath).append("/storage/media/").append(std::to_string(GetUserId())).append("/local"); 164 return NError(ERRNO_NOERR); 165 }; 166 auto cbComplete = [userDataPath](napi_env env, NError err) -> NVal { 167 if (err) { 168 return { env, err.GetNapiErr(env) }; 169 } 170 return NVal::CreateUTF8String(env, *userDataPath); 171 }; 172 173 static const std::string PROCEDURE_NAME = "GetUserDataDir"; 174 NVal thisVar(env, funcArg.GetThisVar()); 175 if (funcArg.GetArgc() == NARG_CNT::ZERO) { 176 return NAsyncWorkPromise(env, thisVar).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_; 177 } 178 179 NVal cb(env, funcArg[NARG_POS::FIRST]); 180 return NAsyncWorkCallback(env, thisVar, cb).Schedule(PROCEDURE_NAME, cbExec, cbComplete).val_; 181 } 182 GetUserDownloadDir(napi_env env,napi_callback_info info)183 napi_value GetUserDownloadDir(napi_env env, napi_callback_info info) 184 { 185 if (!CheckFileManagerFullMountEnable()) { 186 HILOGE("Capability not supported"); 187 NError(E_DEVICENOTSUPPORT).ThrowErr(env); 188 return nullptr; 189 } 190 NFuncArg funcArg(env, info); 191 if (!funcArg.InitArgs(NARG_CNT::ZERO)) { 192 HILOGE("Number of arguments unmatched"); 193 NError(E_PARAMS).ThrowErr(env); 194 return nullptr; 195 } 196 static std::string downloadPath = GetPublicPath(DOWNLOAD_PATH); 197 if (downloadPath.empty()) { 198 HILOGE("Unknown error"); 199 NError(E_UNKNOWN_ERROR).ThrowErr(env); 200 return nullptr; 201 } 202 return NVal::CreateUTF8String(env, downloadPath).val_; 203 } 204 GetUserDesktopDir(napi_env env,napi_callback_info info)205 napi_value GetUserDesktopDir(napi_env env, napi_callback_info info) 206 { 207 if (!CheckFileManagerFullMountEnable()) { 208 HILOGE("Capability not supported"); 209 NError(E_DEVICENOTSUPPORT).ThrowErr(env); 210 return nullptr; 211 } 212 NFuncArg funcArg(env, info); 213 if (!funcArg.InitArgs(NARG_CNT::ZERO)) { 214 HILOGE("Number of arguments unmatched"); 215 NError(E_PARAMS).ThrowErr(env); 216 return nullptr; 217 } 218 static std::string desktopPath = GetPublicPath(DESKTOP_PATH); 219 if (desktopPath.empty()) { 220 HILOGE("Unknown error"); 221 NError(E_UNKNOWN_ERROR).ThrowErr(env); 222 return nullptr; 223 } 224 return NVal::CreateUTF8String(env, desktopPath).val_; 225 } 226 GetUserDocumentDir(napi_env env,napi_callback_info info)227 napi_value GetUserDocumentDir(napi_env env, napi_callback_info info) 228 { 229 if (!CheckFileManagerFullMountEnable()) { 230 HILOGE("Capability not supported"); 231 NError(E_DEVICENOTSUPPORT).ThrowErr(env); 232 return nullptr; 233 } 234 NFuncArg funcArg(env, info); 235 if (!funcArg.InitArgs(NARG_CNT::ZERO)) { 236 HILOGE("Number of arguments unmatched"); 237 NError(E_PARAMS).ThrowErr(env); 238 return nullptr; 239 } 240 static std::string documentsPath = GetPublicPath(DOCUMENTS_PATH); 241 if (documentsPath.empty()) { 242 HILOGE("Unknown error"); 243 NError(E_UNKNOWN_ERROR).ThrowErr(env); 244 return nullptr; 245 } 246 return NVal::CreateUTF8String(env, documentsPath).val_; 247 } 248 GetExternalStorageDir(napi_env env,napi_callback_info info)249 napi_value GetExternalStorageDir(napi_env env, napi_callback_info info) 250 { 251 if (CheckInvalidAccess(FILE_ACCESS_MANAGER_PERMISSION, env)) { 252 return nullptr; 253 } 254 NFuncArg funcArg(env, info); 255 if (!funcArg.InitArgs(NARG_CNT::ZERO)) { 256 HILOGE("Number of arguments unmatched"); 257 NError(E_PARAMS).ThrowErr(env); 258 return nullptr; 259 } 260 return NVal::CreateUTF8String(env, EXTERNAL_STORAGE_PATH).val_; 261 } 262 GetUserHomeDir(napi_env env,napi_callback_info info)263 napi_value GetUserHomeDir(napi_env env, napi_callback_info info) 264 { 265 if (CheckInvalidAccess(FILE_ACCESS_MANAGER_PERMISSION, env)) { 266 return nullptr; 267 } 268 NFuncArg funcArg(env, info); 269 if (!funcArg.InitArgs(NARG_CNT::ZERO)) { 270 HILOGE("Number of arguments unmatched"); 271 NError(E_PARAMS).ThrowErr(env); 272 return nullptr; 273 } 274 static std::string userName = GetUserName(); 275 if (userName.empty()) { 276 HILOGE("Unknown error"); 277 NError(E_UNKNOWN_ERROR).ThrowErr(env); 278 return nullptr; 279 } 280 return NVal::CreateUTF8String(env, PC_STORAGE_PATH + userName).val_; 281 } 282 } // namespace ModuleEnvironment 283 } // namespace FileManagement 284 } // namespace OHOS