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