1 /*
2  * Copyright (c) 2024 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 "el5_filekey_manager_napi.h"
17 
18 #include <unordered_map>
19 
20 #include "data_lock_type.h"
21 #include "el5_filekey_manager_error.h"
22 #include "el5_filekey_manager_kit.h"
23 #include "el5_filekey_manager_log.h"
24 
25 namespace OHOS {
26 namespace Security {
27 namespace AccessToken {
28 namespace {
29 constexpr uint32_t MAX_PARAM_SIZE = 1;
30 const std::unordered_map<uint32_t, std::string> ErrMsgMap {
31     {EFM_ERR_NO_PERMISSION, "Permission denied."},
32     {EFM_ERR_NOT_SYSTEM_APP, "Not system app."},
33     {EFM_ERR_INVALID_PARAMETER, "Parameter error."},
34     {EFM_ERR_SYSTEMCAP_NOT_SUPPORT, "The specified SystemCapability name was not found."},
35     {EFM_ERR_INVALID_DATATYPE, "Invalid DataType."},
36     {EFM_ERR_REMOTE_CONNECTION, "The system ability work abnormally."},
37     {EFM_ERR_FIND_ACCESS_FAILED, "The application is not enabled the data protection under lock screen."},
38     {EFM_ERR_ACCESS_RELEASED, "File access is denied."},
39     {EFM_ERR_RELEASE_ACCESS_FAILED, "File access was not acquired."},
40 };
41 }
42 
ThrowError(napi_env env,int32_t errCode)43 void ThrowError(napi_env env, int32_t errCode)
44 {
45     napi_value businessError = nullptr;
46 
47     napi_value code = nullptr;
48     napi_create_int32(env, errCode, &code);
49 
50     std::string errMsg = "Unknown error, errCode + " + std::to_string(errCode) + ".";
51     auto iter = ErrMsgMap.find(errCode);
52     if (iter != ErrMsgMap.end()) {
53         errMsg = iter->second;
54     }
55 
56     napi_value msg = nullptr;
57     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &msg);
58 
59     napi_create_error(env, nullptr, msg, &businessError);
60     napi_set_named_property(env, businessError, "code", code);
61     napi_set_named_property(env, businessError, "message", msg);
62 
63     napi_throw(env, businessError);
64 }
65 
ParseDataType(const napi_env & env,napi_value args,int32_t & dataLockType)66 bool ParseDataType(const napi_env &env, napi_value args, int32_t &dataLockType)
67 {
68     // data-lock-type
69     napi_valuetype valuetype = napi_undefined;
70     napi_typeof(env, args, &valuetype);
71     if (valuetype != napi_number) {
72         LOG_ERROR("Parameter type %{public}d error. Number expected.", valuetype);
73         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
74         return false;
75     }
76     napi_get_value_int32(env, args, &dataLockType);
77     return true;
78 }
79 
CheckDataType(napi_env env,int32_t dataLockType)80 bool CheckDataType(napi_env env, int32_t dataLockType)
81 {
82     if ((static_cast<DataLockType>(dataLockType) != DEFAULT_DATA) &&
83         (static_cast<DataLockType>(dataLockType) != MEDIA_DATA) &&
84         (static_cast<DataLockType>(dataLockType) != ALL_DATA)) {
85         ThrowError(env, EFM_ERR_INVALID_DATATYPE);
86         return false;
87     }
88     return true;
89 }
90 
AcquireAccess(napi_env env,napi_callback_info info)91 napi_value AcquireAccess(napi_env env, napi_callback_info info)
92 {
93     size_t argc = MAX_PARAM_SIZE;
94     napi_value argv[MAX_PARAM_SIZE] = {nullptr};
95     if (napi_get_cb_info(env, info, &argc, argv, NULL, NULL) != napi_ok) {
96         LOG_ERROR("napi_get_cb_info failed.");
97         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
98         return nullptr;
99     }
100 
101     int32_t dataLockType = DEFAULT_DATA;
102     if ((argc == MAX_PARAM_SIZE) && !ParseDataType(env, argv[0], dataLockType)) {
103         return nullptr;
104     }
105 
106     if (!CheckDataType(env, dataLockType)) {
107         LOG_ERROR("Invalid DataType.");
108         return nullptr;
109     }
110 
111     int32_t retCode = El5FilekeyManagerKit::AcquireAccess(static_cast<DataLockType>(dataLockType));
112     if (retCode != EFM_SUCCESS) {
113         ThrowError(env, retCode);
114         retCode = ACCESS_DENIED;
115     }
116 
117     napi_value result = nullptr;
118     NAPI_CALL(env, napi_create_int32(env, retCode, &result));
119     return result;
120 }
121 
ReleaseAccess(napi_env env,napi_callback_info info)122 napi_value ReleaseAccess(napi_env env, napi_callback_info info)
123 {
124     size_t argc = MAX_PARAM_SIZE;
125     napi_value argv[MAX_PARAM_SIZE] = {nullptr};
126     if (napi_get_cb_info(env, info, &argc, argv, NULL, NULL) != napi_ok) {
127         LOG_ERROR("napi_get_cb_info failed.");
128         ThrowError(env, EFM_ERR_INVALID_PARAMETER);
129         return nullptr;
130     }
131 
132     int32_t dataLockType = DEFAULT_DATA;
133     if ((argc == MAX_PARAM_SIZE) && !ParseDataType(env, argv[0], dataLockType)) {
134         return nullptr;
135     }
136 
137     if (!CheckDataType(env, dataLockType)) {
138         LOG_ERROR("Invalid DataType.");
139         return nullptr;
140     }
141 
142     int32_t retCode = El5FilekeyManagerKit::ReleaseAccess(static_cast<DataLockType>(dataLockType));
143     if (retCode != EFM_SUCCESS) {
144         ThrowError(env, retCode);
145         retCode = RELEASE_DENIED;
146     }
147 
148     napi_value result = nullptr;
149     NAPI_CALL(env, napi_create_int32(env, retCode, &result));
150     return result;
151 }
152 
153 EXTERN_C_START
154 /*
155  * function for module exports
156  */
Init(napi_env env,napi_value exports)157 static napi_value Init(napi_env env, napi_value exports)
158 {
159     napi_property_descriptor properties[] = {
160         DECLARE_NAPI_FUNCTION("acquireAccess", AcquireAccess),
161         DECLARE_NAPI_FUNCTION("releaseAccess", ReleaseAccess)
162     };
163 
164     napi_define_properties(env, exports, sizeof(properties) / sizeof(properties[0]), properties);
165 
166     napi_value dataType = nullptr;
167     napi_create_object(env, &dataType);
168 
169     napi_value prop = nullptr;
170     napi_create_int32(env, MEDIA_DATA, &prop);
171     napi_set_named_property(env, dataType, "MEDIA_DATA", prop);
172 
173     prop = nullptr;
174     napi_create_int32(env, ALL_DATA, &prop);
175     napi_set_named_property(env, dataType, "ALL_DATA", prop);
176 
177     napi_value accessStatus = nullptr;
178     napi_create_object(env, &accessStatus);
179 
180     prop = nullptr;
181     napi_create_int32(env, ACCESS_GRANTED, &prop);
182     napi_set_named_property(env, accessStatus, "ACCESS_GRANTED", prop);
183 
184     prop = nullptr;
185     napi_create_int32(env, ACCESS_DENIED, &prop);
186     napi_set_named_property(env, accessStatus, "ACCESS_DENIED", prop);
187 
188     napi_value releaseStatus = nullptr;
189     napi_create_object(env, &releaseStatus);
190 
191     prop = nullptr;
192     napi_create_int32(env, RELEASE_GRANTED, &prop);
193     napi_set_named_property(env, releaseStatus, "RELEASE_GRANTED", prop);
194 
195     prop = nullptr;
196     napi_create_int32(env, RELEASE_DENIED, &prop);
197     napi_set_named_property(env, releaseStatus, "RELEASE_DENIED", prop);
198 
199     napi_property_descriptor exportFuncs[] = {
200         DECLARE_NAPI_PROPERTY("DataType", dataType),
201         DECLARE_NAPI_PROPERTY("AccessStatus", accessStatus),
202         DECLARE_NAPI_PROPERTY("ReleaseStatus", releaseStatus),
203     };
204     napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(exportFuncs[0]), exportFuncs);
205 
206     return exports;
207 }
208 EXTERN_C_END
209 
210 /*
211  * Module define
212  */
213 static napi_module g_module = {
214     .nm_version = 1,
215     .nm_flags = 0,
216     .nm_filename = nullptr,
217     .nm_register_func = Init,
218     .nm_modname = "ability.screenLockFileManager",
219     .nm_priv = static_cast<void *>(nullptr),
220     .reserved = {nullptr}
221 };
222 
223 /*
224  * Module register function
225  */
RegisterEl5FilekeyManager(void)226 extern "C" __attribute__((constructor)) void RegisterEl5FilekeyManager(void)
227 {
228     napi_module_register(&g_module);
229 }
230 }  // namespace AccessToken
231 }  // namespace Security
232 }  // namespace OHOS
233