diff --git a/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h b/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h index 213f5bbbb5aecbf17e20a7f50b16ab95a1d3467d..a8cd415f6d4d7de80475883544cd6239e0fdfe9d 100644 --- a/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h +++ b/interfaces/innerkits/cert_manager_standard/main/include/cm_type.h @@ -154,6 +154,14 @@ enum CmErrorCode { CMR_ERROR_PASSWORD_IS_ERR = -36, }; +enum CMDialogErrorCode { + CMR_DIALOG_OK = 0, + CMR_DIALOG_ERROR = -1, + CMR_DIALOG_ERROR_INVALID_ARGUMENT = -2, + CMR_DIALOG_ERROR_INTERNAL = -3, + CMR_DIALOG_ERROR_PERMISSION_DENIED = 1011, +}; + enum CMErrorCode { /* temp use */ CMR_OK = 0, CMR_ERROR = -1, diff --git a/interfaces/kits/napi/BUILD.gn b/interfaces/kits/napi/BUILD.gn index d2ec35d3d677a991382bd9cd5893b70d2cb670e7..e493638aa9a945802ab74e8fdb21396cf3f86bc7 100644 --- a/interfaces/kits/napi/BUILD.gn +++ b/interfaces/kits/napi/BUILD.gn @@ -87,13 +87,12 @@ ohos_shared_library("certmanagerdialog") { include_dirs = [ "../../../frameworks/cert_manager_standard/main/common/include", - "include", "include/dialog", ] sources = [ - "src/cm_napi_common.cpp", "src/dialog/cm_napi_dialog.cpp", + "src/dialog/cm_napi_dialog_common.cpp", "src/dialog/cm_napi_open_dialog.cpp", ] diff --git a/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h b/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h new file mode 100644 index 0000000000000000000000000000000000000000..acfc4e0e4f5dcd77581000527a72d812fb24a104 --- /dev/null +++ b/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CM_NAPI_DIALOG_COMMON_H +#define CM_NAPI_DIALOG_COMMON_H + +#include + +#include "napi/native_api.h" +#include "napi/native_node_api.h" + +#include "cm_mem.h" +#include "cm_type.h" + +namespace CMNapi { + +static const std::string BUSINESS_ERROR_PROPERTY_CODE = "code"; +static const std::string BUSINESS_ERROR_PROPERTY_MESSAGE = "message"; +static const int32_t RESULT_NUMBER = 2; + +napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store); +napi_value ParseBoolean(napi_env env, napi_value object, bool &status); +napi_value ParseString(napi_env env, napi_value object, CmBlob *&blob); + +void ThrowError(napi_env env, int32_t errorCode, std::string errMsg); +napi_value GenerateBusinessError(napi_env env, int32_t errorCode); + +void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode, + napi_value *result, int32_t length); + +inline napi_value GetNull(napi_env env) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_get_null(env, &result)); + return result; +} + +inline napi_value GetInt32(napi_env env, int32_t value) +{ + napi_value result = nullptr; + NAPI_CALL(env, napi_create_int32(env, value, &result)); + return result; +} + +enum CmDialogPageType { + PAGE_MAIN = 1, + PAGE_CA_CERTIFICATE = 2, + PAGE_CREDENTIAL = 3, + PAGE_INSTALL_CERTIFICATE = 4 +}; + +enum ErrorCode { + SUCCESS = 0, + HAS_NO_PERMISSION = 201, + NOT_SYSTEM_APP = 202, + PARAM_ERROR = 401, + DIALOG_ERROR_GENERIC = 29700001, + DIALOG_ERROR_OPERATION_CANCELED = 29700002, +}; + +} // namespace CertManagerNapi + +#endif diff --git a/interfaces/kits/napi/include/dialog/cm_napi_open_dialog.h b/interfaces/kits/napi/include/dialog/cm_napi_open_dialog.h index e7fb0287d254b4744482b8dd14cd9b9e80f22bff..f78e582fc61a2336beee3ceae488059f94b43f44 100644 --- a/interfaces/kits/napi/include/dialog/cm_napi_open_dialog.h +++ b/interfaces/kits/napi/include/dialog/cm_napi_open_dialog.h @@ -23,23 +23,9 @@ #include "napi_common_want.h" #include "ui_content.h" -#include "cm_napi_common.h" - namespace CMNapi { napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info); -enum CmDialogErrorCode { - DIALOG_ERROR_GENERIC = 29700001, - DIALOG_ERROR_OPERATION_CANCELED = 29700002, -}; - -enum CmDialogPageType { - PAGE_MAIN = 1, - PAGE_CA_CERTIFICATE = 2, - PAGE_CREDENTIAL = 3, - PAGE_INSTALL_CERTIFICATE = 4 -}; - struct CommonAsyncContext { explicit CommonAsyncContext(napi_env env); virtual ~CommonAsyncContext(); diff --git a/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp b/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp index 6c839cca48682235c9c797ac13cabad2230e91bc..175bb45152279adf1fe7a67640c6c5f49bcdf456 100644 --- a/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp +++ b/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp @@ -16,7 +16,7 @@ #include "napi/native_api.h" #include "napi/native_node_api.h" -#include "cm_napi_common.h" +#include "cm_napi_dialog_common.h" #include "cm_napi_open_dialog.h" diff --git a/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp b/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..262535209c0554ee7927d783cae3d7c5829c141d --- /dev/null +++ b/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cm_napi_dialog_common.h" + +#include +#include "securec.h" + +#include "cm_log.h" +#include "cm_type.h" + +namespace CMNapi { +namespace { +constexpr int CM_MAX_DATA_LEN = 0x6400000; // The maximum length is 100M + +static const std::string DIALOG_NO_PERMISSION_MSG = "the caller has no permission"; +static const std::string DIALOG_INVALID_PARAMS_MSG = "the input parameters is invalid"; +static const std::string DIALOG_GENERIC_MSG = "there is an internal error"; + +static const std::unordered_map DIALOG_CODE_TO_JS_CODE_MAP = { + // invalid params + { CMR_DIALOG_ERROR_INVALID_ARGUMENT, PARAM_ERROR }, + // no permission + { CMR_DIALOG_ERROR_PERMISSION_DENIED, HAS_NO_PERMISSION }, + // internal error + { CMR_DIALOG_ERROR_INTERNAL, DIALOG_ERROR_GENERIC }, +}; + +static const std::unordered_map DIALOG_CODE_TO_MSG_MAP = { + { CMR_DIALOG_ERROR_INVALID_ARGUMENT, DIALOG_INVALID_PARAMS_MSG }, + { CMR_DIALOG_ERROR_PERMISSION_DENIED, DIALOG_NO_PERMISSION_MSG }, + { CMR_DIALOG_ERROR_INTERNAL, DIALOG_GENERIC_MSG }, +}; +} // namespace + +napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store) +{ + napi_valuetype type; + napi_typeof(env, object, &type); + if (type != napi_number) { + CM_LOG_E("param type is not number"); + return nullptr; + } + uint32_t temp = 0; + napi_get_value_uint32(env, object, &temp); + store = temp; + return GetInt32(env, 0); +} + +napi_value ParseBoolean(napi_env env, napi_value object, bool &status) +{ + napi_valuetype type; + napi_typeof(env, object, &type); + if (type != napi_boolean) { + CM_LOG_E("param type is not bool"); + return nullptr; + } + bool temp = false; + napi_get_value_bool(env, object, &temp); + status = temp; + return GetInt32(env, 0); +} + +napi_value ParseString(napi_env env, napi_value obj, CmBlob *&blob) +{ + napi_valuetype type = napi_undefined; + NAPI_CALL(env, napi_typeof(env, obj, &type)); + if (type != napi_string) { + CM_LOG_E("the type of param is not string"); + return nullptr; + } + size_t length = 0; + napi_status status = napi_get_value_string_utf8(env, obj, nullptr, 0, &length); + if (status != napi_ok) { + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get string length"); + return nullptr; + } + + // add 0 length check + if ((length == 0) || (length > CM_MAX_DATA_LEN)) { + CM_LOG_E("input string length is 0 or too large, length: %d", length); + return nullptr; + } + + char *data = static_cast(CmMalloc(length + 1)); + if (data == nullptr) { + napi_throw_error(env, nullptr, "could not alloc memory"); + CM_LOG_E("could not alloc memory"); + return nullptr; + } + (void)memset_s(data, length + 1, 0, length + 1); + + size_t res = 0; + status = napi_get_value_string_utf8(env, obj, data, length + 1, &res); + if (status != napi_ok) { + CmFree(data); + GET_AND_THROW_LAST_ERROR((env)); + CM_LOG_E("could not get string"); + return nullptr; + } + + blob = static_cast(CmMalloc(sizeof(CmBlob))); + if (blob == nullptr) { + CmFree(data); + napi_throw_error(env, nullptr, "could not alloc memory"); + CM_LOG_E("could not alloc memory"); + return nullptr; + } + blob->data = reinterpret_cast(data); + blob->size = static_cast((length + 1) & UINT32_MAX); + + return GetInt32(env, 0); +} + +static const char *GetJsErrorMsg(int32_t errCode) +{ + auto iter = DIALOG_CODE_TO_MSG_MAP.find(errCode); + if (iter != DIALOG_CODE_TO_MSG_MAP.end()) { + return (iter->second).c_str(); + } + return DIALOG_GENERIC_MSG.c_str(); +} + +int32_t TranformErrorCode(int32_t errorCode) +{ + auto iter = DIALOG_CODE_TO_JS_CODE_MAP.find(errorCode); + if (iter != DIALOG_CODE_TO_JS_CODE_MAP.end()) { + return iter->second; + } + return DIALOG_ERROR_GENERIC; +} + +napi_value GenerateBusinessError(napi_env env, int32_t errorCode) +{ + const char *errorMessage = GetJsErrorMsg(errorCode); + if (errorMessage == nullptr) { + return nullptr; + } + + napi_value businessErrorMsg = nullptr; + NAPI_CALL(env, napi_create_object(env, &businessErrorMsg)); + + napi_value code = nullptr; + int32_t outputCode = TranformErrorCode(errorCode); + NAPI_CALL(env, napi_create_int32(env, outputCode, &code)); + NAPI_CALL(env, napi_set_named_property(env, businessErrorMsg, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code)); + napi_value message = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, errorMessage, NAPI_AUTO_LENGTH, &message)); + NAPI_CALL(env, napi_set_named_property(env, businessErrorMsg, BUSINESS_ERROR_PROPERTY_MESSAGE.c_str(), message)); + return businessErrorMsg; +} + +void ThrowError(napi_env env, int32_t errorCode, std::string errMsg) +{ + napi_value paramsError = nullptr; + napi_value outCode = nullptr; + napi_value message = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, errorCode, &outCode)); + NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message)); + NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, ¶msError)); + NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, paramsError, + BUSINESS_ERROR_PROPERTY_CODE.c_str(), outCode)); + NAPI_CALL_RETURN_VOID(env, napi_throw(env, paramsError)); +} + +void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode, + napi_value *result, int32_t length) +{ + if (length < RESULT_NUMBER) { + return; + } + if (resultCode == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result[1])); + } else { + NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, result[0])); + } +} + + +} // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/dialog/cm_napi_open_dialog.cpp b/interfaces/kits/napi/src/dialog/cm_napi_open_dialog.cpp index 654a08aa0ebdaebd0ab12131ac9d85ad553fc930..14042cfc71a954f744e91637feb0c44f83db039e 100644 --- a/interfaces/kits/napi/src/dialog/cm_napi_open_dialog.cpp +++ b/interfaces/kits/napi/src/dialog/cm_napi_open_dialog.cpp @@ -20,7 +20,7 @@ #include "cert_manager_api.h" #include "cm_log.h" -#include "cm_napi_common.h" +#include "cm_napi_dialog_common.h" #include "want.h" #include "want_params_wrapper.h" @@ -112,7 +112,7 @@ void CmUIExtensionCallback::OnError(const int32_t errorCode, const std::string& CM_LOG_E("copy error str failed"); return; } - ThrowError(this->reqContext_->env, PARAM_ERROR, errStr); + ThrowError(this->reqContext_->env, DIALOG_ERROR_GENERIC, errStr); } void CmUIExtensionCallback::OnRemoteReady(const std::shared_ptr& uiProxy) @@ -238,6 +238,19 @@ static void StartUIExtensionAbility(std::shared_ptr return; } +static bool IsCmDialogPageTypeEnum(const uint32_t value) +{ + switch (static_cast(value)) { + case CmDialogPageType::PAGE_MAIN: + case CmDialogPageType::PAGE_CA_CERTIFICATE: + case CmDialogPageType::PAGE_CREDENTIAL: + case CmDialogPageType::PAGE_INSTALL_CERTIFICATE: + return true; + default: + return false; + } +} + napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info) { CM_LOG_I("cert manager dialog enter"); @@ -270,6 +283,12 @@ napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info) return result; } + if (!IsCmDialogPageTypeEnum(asyncContext->pageType)) { + CM_LOG_E("pageType invalid"); + ThrowError(env, PARAM_ERROR, "pageType invalid"); + return nullptr; + } + asyncContext->env = env; OHOS::AAFwk::Want want; want.SetElementName(CERT_MANAGER_BUNDLENAME, CERT_MANAGER_ABILITYNAME);