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 <memory>
17 #include <map>
18 #include "app_domain_verify_manager_napi.h"
19 #include "app_domain_verify_hilog.h"
20 #include "app_domain_verify_mgr_client.h"
21 #include "app_domain_verify_error.h"
22 #include "api_event_reporter.h"
23
24 namespace OHOS::AppDomainVerify {
25 constexpr int32_t API_SUCCESS = 0;
26 constexpr int32_t API_FAIL = 1;
27 constexpr int32_t MAX_STR_INPUT_SIZE = 256;
28 constexpr int32_t STRING_BUF_MAX_SIZE = 4096;
29 std::map<ErrorCode, const char*> ErrCodeMap = { { ErrorCode::E_PERMISSION_DENIED, "Permission denied." },
30 { ErrorCode::E_IS_NOT_SYS_APP, "System API accessed by non-system app." },
31 { ErrorCode::E_PARAM_ERROR, "Parameter error." }, { ErrorCode::E_INTERNAL_ERR, "Internal error." } };
GetString(napi_env env,napi_value value)32 static std::string GetString(napi_env env, napi_value value)
33 {
34 std::unique_ptr<char[]> valueBuf = std::make_unique<char[]>(STRING_BUF_MAX_SIZE);
35 size_t size = 0;
36 NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, value, valueBuf.get(), STRING_BUF_MAX_SIZE, &size), "");
37 std::string result = std::string(valueBuf.get(), size);
38 return result;
39 }
BuildString(const napi_env & env,const std::string & data)40 static napi_value BuildString(const napi_env& env, const std::string& data)
41 {
42 napi_value result;
43 NAPI_CALL_BASE(env, napi_create_string_utf8(env, data.c_str(), NAPI_AUTO_LENGTH, &result), nullptr);
44 return result;
45 }
BuildStringArray(const napi_env & env,const std::vector<std::string> & data)46 static napi_value BuildStringArray(const napi_env& env, const std::vector<std::string>& data)
47 {
48 napi_value arr;
49 NAPI_CALL_BASE(env, napi_create_array(env, &arr), nullptr);
50 size_t index = 0;
51 for (auto&& str : data) {
52 napi_value value = BuildString(env, str);
53 NAPI_CALL_BASE(env, napi_set_element(env, arr, index++, value), nullptr);
54 }
55 return arr;
56 }
CheckInput(const std::string & input)57 static bool CheckInput(const std::string& input)
58 {
59 if (input.empty() || input.size() > MAX_STR_INPUT_SIZE) {
60 return false;
61 }
62 return true;
63 }
BuildError(const napi_env & env,ErrorCode errorCode)64 static napi_value BuildError(const napi_env& env, ErrorCode errorCode)
65 {
66 auto ret = napi_throw_error(env, std::to_string(errorCode).c_str(), ErrCodeMap[errorCode]);
67 if (ret != napi_status::napi_ok) {
68 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "throw err failed.");
69 }
70 return nullptr;
71 }
QueryAssociatedDomains(napi_env env,napi_callback_info info)72 napi_value QueryAssociatedDomains(napi_env env, napi_callback_info info)
73 {
74 size_t argc = 1;
75 napi_value args[1] = { nullptr };
76
77 Dfx::ApiEventReporter reporter("QueryAssociatedDomains");
78 NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), nullptr);
79 std::string bundleName = GetString(env, args[0]);
80 if (!CheckInput(bundleName)) {
81 reporter.WriteEndEvent(API_FAIL, ErrorCode::E_PARAM_ERROR);
82 return BuildError(env, ErrorCode::E_PARAM_ERROR);
83 }
84 std::vector<std::string> domains;
85 auto ret = AppDomainVerifyMgrClient::GetInstance()->QueryAssociatedDomains(bundleName, domains);
86 if (ret != 0) {
87 if (ErrCodeMap.count(static_cast<ErrorCode>(ret)) != 0) {
88 reporter.WriteEndEvent(API_FAIL, static_cast<ErrorCode>(ret));
89 return BuildError(env, static_cast<ErrorCode>(ret));
90 } else {
91 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "unknown error:%{public}d.", ret);
92 reporter.WriteEndEvent(API_FAIL, ret);
93 return BuildStringArray(env, domains);
94 }
95 }
96 reporter.WriteEndEvent(API_SUCCESS, ret);
97 return BuildStringArray(env, domains);
98 }
QueryAssociatedBundleNames(napi_env env,napi_callback_info info)99 napi_value QueryAssociatedBundleNames(napi_env env, napi_callback_info info)
100 {
101 size_t argc = 1;
102 napi_value args[1] = { nullptr };
103
104 Dfx::ApiEventReporter reporter("QueryAssociatedBundleNames");
105 NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr), nullptr);
106 std::string domain = GetString(env, args[0]);
107 if (!CheckInput(domain)) {
108 reporter.WriteEndEvent(API_FAIL, ErrorCode::E_PARAM_ERROR);
109 return BuildError(env, ErrorCode::E_PARAM_ERROR);
110 }
111 std::vector<std::string> bundleNames;
112 auto ret = AppDomainVerifyMgrClient::GetInstance()->QueryAssociatedBundleNames(domain, bundleNames);
113 if (ret != 0) {
114 if (ErrCodeMap.count(static_cast<ErrorCode>(ret)) != 0) {
115 reporter.WriteEndEvent(API_FAIL, static_cast<ErrorCode>(ret));
116 return BuildError(env, static_cast<ErrorCode>(ret));
117 } else {
118 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MGR_MODULE_SERVICE, "unknown error:%{public}d.", ret);
119 reporter.WriteEndEvent(API_FAIL, ret);
120 return BuildStringArray(env, bundleNames);
121 }
122 }
123 reporter.WriteEndEvent(API_SUCCESS, ret);
124 return BuildStringArray(env, bundleNames);
125 }
126 }