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