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 (CheckInvalidAccess(READ_WRITE_DOWNLOAD_PERMISSION, env)) {
186 return nullptr;
187 }
188 NFuncArg funcArg(env, info);
189 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
190 HILOGE("Number of arguments unmatched");
191 NError(E_PARAMS).ThrowErr(env);
192 return nullptr;
193 }
194 static std::string downloadPath = GetPublicPath(DOWNLOAD_PATH);
195 if (downloadPath.empty()) {
196 HILOGE("Unknown error");
197 NError(E_UNKNOWN_ERROR).ThrowErr(env);
198 return nullptr;
199 }
200 return NVal::CreateUTF8String(env, downloadPath).val_;
201 }
202
GetUserDesktopDir(napi_env env,napi_callback_info info)203 napi_value GetUserDesktopDir(napi_env env, napi_callback_info info)
204 {
205 if (CheckInvalidAccess(READ_WRITE_DESKTOP_PERMISSION, env)) {
206 return nullptr;
207 }
208 NFuncArg funcArg(env, info);
209 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
210 HILOGE("Number of arguments unmatched");
211 NError(E_PARAMS).ThrowErr(env);
212 return nullptr;
213 }
214 static std::string desktopPath = GetPublicPath(DESKTOP_PATH);
215 if (desktopPath.empty()) {
216 HILOGE("Unknown error");
217 NError(E_UNKNOWN_ERROR).ThrowErr(env);
218 return nullptr;
219 }
220 return NVal::CreateUTF8String(env, desktopPath).val_;
221 }
222
GetUserDocumentDir(napi_env env,napi_callback_info info)223 napi_value GetUserDocumentDir(napi_env env, napi_callback_info info)
224 {
225 if (CheckInvalidAccess(READ_WRITE_DOCUMENTS_PERMISSION, env)) {
226 return nullptr;
227 }
228 NFuncArg funcArg(env, info);
229 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
230 HILOGE("Number of arguments unmatched");
231 NError(E_PARAMS).ThrowErr(env);
232 return nullptr;
233 }
234 static std::string documentsPath = GetPublicPath(DOCUMENTS_PATH);
235 if (documentsPath.empty()) {
236 HILOGE("Unknown error");
237 NError(E_UNKNOWN_ERROR).ThrowErr(env);
238 return nullptr;
239 }
240 return NVal::CreateUTF8String(env, documentsPath).val_;
241 }
242
GetExternalStorageDir(napi_env env,napi_callback_info info)243 napi_value GetExternalStorageDir(napi_env env, napi_callback_info info)
244 {
245 if (CheckInvalidAccess(FILE_ACCESS_MANAGER_PERMISSION, env)) {
246 return nullptr;
247 }
248 NFuncArg funcArg(env, info);
249 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
250 HILOGE("Number of arguments unmatched");
251 NError(E_PARAMS).ThrowErr(env);
252 return nullptr;
253 }
254 return NVal::CreateUTF8String(env, EXTERNAL_STORAGE_PATH).val_;
255 }
256
GetUserHomeDir(napi_env env,napi_callback_info info)257 napi_value GetUserHomeDir(napi_env env, napi_callback_info info)
258 {
259 if (CheckInvalidAccess(FILE_ACCESS_MANAGER_PERMISSION, env)) {
260 return nullptr;
261 }
262 NFuncArg funcArg(env, info);
263 if (!funcArg.InitArgs(NARG_CNT::ZERO)) {
264 HILOGE("Number of arguments unmatched");
265 NError(E_PARAMS).ThrowErr(env);
266 return nullptr;
267 }
268 static std::string userName = GetUserName();
269 if (userName.empty()) {
270 HILOGE("Unknown error");
271 NError(E_UNKNOWN_ERROR).ThrowErr(env);
272 return nullptr;
273 }
274 return NVal::CreateUTF8String(env, PC_STORAGE_PATH + userName).val_;
275 }
276 } // namespace ModuleEnvironment
277 } // namespace FileManagement
278 } // namespace OHOS