diff --git a/interfaces/kits/napi/BUILD.gn b/interfaces/kits/napi/BUILD.gn index 1d10a31df9f430ed07f5ed5a157e61b3c2cc5ed1..d24b2599856327b0b87c5464efb30a24d4ba3ed5 100644 --- a/interfaces/kits/napi/BUILD.gn +++ b/interfaces/kits/napi/BUILD.gn @@ -89,6 +89,7 @@ ohos_shared_library("certmanagerdialog") { "src/dialog/cm_napi_dialog_common.cpp", "src/dialog/cm_napi_open_dialog.cpp", "src/dialog/cm_napi_open_install_dialog.cpp", + "src/dialog/cm_napi_open_uninstall_dialog.cpp", ] external_deps = [ diff --git a/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h b/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h index 2c8705b4211665f3877f519ea411ed49bb40245f..2549997c2c90ad918d60aa2c609011969033327e 100644 --- a/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h +++ b/interfaces/kits/napi/include/dialog/cm_napi_dialog_common.h @@ -53,6 +53,8 @@ inline napi_value GetInt32(napi_env env, int32_t value) return result; } +int32_t GetCallerLabelName(std::shared_ptr asyncContext); + enum CmDialogPageType { PAGE_MAIN = 1, PAGE_CA_CERTIFICATE = 2, 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 c34925d582c1972a34072ca25cd6876c5dfeed93..3d24277ee1280e49db1d1cac3afe8ea5f57ce27f 100644 --- a/interfaces/kits/napi/include/dialog/cm_napi_open_dialog.h +++ b/interfaces/kits/napi/include/dialog/cm_napi_open_dialog.h @@ -22,6 +22,7 @@ #include "napi_base_context.h" #include "napi_common_want.h" #include "ui_content.h" +#include "cm_type.h" namespace CMNapi { const std::string PARAM_UI_EXTENSION_TYPE = "ability.want.params.uiExtensionType"; @@ -32,16 +33,19 @@ const std::string CERT_MANAGER_PAGE_TYPE = "pageType"; const std::string CERT_MANAGER_CERTSCOPE_TYPE = "certScope"; const std::string CERT_MANAGER_CERTIFICATE_DATA = "cert"; const std::string CERT_MANAGER_CALLER_BUNDLENAME = "bundleName"; +const std::string CERT_MANAGER_CERT_URI = "certUri"; const std::string CERT_MANAGER_OPERATION_TYPE = "operationType"; constexpr int32_t PARAM0 = 0; constexpr int32_t PARAM1 = 1; constexpr int32_t PARAM2 = 2; constexpr int32_t PARAM3 = 3; constexpr int32_t PARAM_SIZE_TWO = 2; +constexpr int32_t PARAM_SIZE_THREE = 3; constexpr int32_t PARAM_SIZE_FOUR = 4; napi_value CMNapiOpenCertManagerDialog(napi_env env, napi_callback_info info); napi_value CMNapiOpenInstallCertDialog(napi_env env, napi_callback_info info); +napi_value CMNapiOpenUninstallCertDialog(napi_env env, napi_callback_info info); struct CommonAsyncContext { explicit CommonAsyncContext(napi_env env); @@ -61,6 +65,7 @@ struct CmUIExtensionRequestContext : public CommonAsyncContext { uint32_t certificateScope = 0; std::string certStr = ""; std::string labelName = ""; + CmBlob *certUri = nullptr; }; class CmUIExtensionCallback { diff --git a/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp b/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp index f0a9d7141c98b39e20dc7d9a2e7021b7c01ca87d..3b33b94fb78b8faccf6168bf6e08d7992fd46373 100644 --- a/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp +++ b/interfaces/kits/napi/src/dialog/cm_napi_dialog.cpp @@ -93,6 +93,7 @@ static napi_value CMDialogNapiRegister(napi_env env, napi_value exports) /* dialog */ DECLARE_NAPI_FUNCTION("openCertificateManagerDialog", CMNapiOpenCertManagerDialog), DECLARE_NAPI_FUNCTION("openInstallCertificateDialog", CMNapiOpenInstallCertDialog), + DECLARE_NAPI_FUNCTION("openUninstallCertificateDialog", CMNapiOpenUninstallCertDialog), }; NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); return exports; diff --git a/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp b/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp index 5821f26c81cc3ee57232f684b7b70ef841af0d1d..9b082bb85eef709754bf621d8bf2d9bf895d97e4 100644 --- a/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp +++ b/interfaces/kits/napi/src/dialog/cm_napi_dialog_common.cpp @@ -20,6 +20,9 @@ #include "cm_log.h" #include "cm_type.h" +#include "iservice_registry.h" +#include "bundle_mgr_proxy.h" +#include "system_ability_definition.h" #define BYTE_SHIFT_16 0x10 #define BYTE_SHIFT_8 0x08 @@ -56,6 +59,8 @@ static const std::string MAX_QUANTITY_REACHED_MSG = "the number of certificates "reaches the maxinum allowed."; static const std::string SA_INTERNAL_ERROR_MSG = "sa internal error."; static const std::string NOT_EXIST_MSG = "the certificate dose not exist."; +static const std::string NOT_ENTERPRISE_DEVICE_MSG = "The operation does not comply with the device security policy," + "such as the device does not allow users to manage the ca certificate of the global user."; static const std::unordered_map DIALOG_CODE_TO_JS_CODE_MAP = { // internal error @@ -73,6 +78,7 @@ static const std::unordered_map DIALOG_CODE_TO_JS_CODE_MAP = { { CMR_DIALOG_ERROR_MAX_QUANTITY_REACHED, DIALOG_ERROR_INSTALL_FAILED }, { CMR_DIALOG_ERROR_SA_INTERNAL_ERROR, DIALOG_ERROR_INSTALL_FAILED }, { CMR_DIALOG_ERROR_NOT_EXIST, DIALOG_ERROR_INSTALL_FAILED }, + { CMR_DIALOG_ERROR_NOT_ENTERPRISE_DEVICE, DIALOG_ERROR_NOT_COMPLY_SECURITY_POLICY }, }; static const std::unordered_map DIALOG_CODE_TO_MSG_MAP = { @@ -80,6 +86,7 @@ static const std::unordered_map DIALOG_CODE_TO_MSG_MAP = { { CMR_DIALOG_ERROR_OPERATION_CANCELS, DIALOG_OPERATION_CANCELS_MSG }, { CMR_DIALOG_ERROR_INSTALL_FAILED, DIALOG_INSTALL_FAILED_MSG }, { CMR_DIALOG_ERROR_NOT_SUPPORTED, DIALOG_NOT_SUPPORTED_MSG }, + { CMR_DIALOG_ERROR_NOT_ENTERPRISE_DEVICE, NOT_ENTERPRISE_DEVICE_MSG }, { CMR_DIALOG_ERROR_PARSE_CERT_FAILED, DIOLOG_OPERATION_FAILED_MSG + PARSE_CERT_FAILED_MSG }, { CMR_DIALOG_ERROR_ADVANCED_SECURITY, DIOLOG_OPERATION_FAILED_MSG + ADVANCED_SECURITY_MSG }, @@ -343,7 +350,6 @@ napi_value GenerateBusinessError(napi_env env, int32_t errorCode) napi_value code = nullptr; int32_t outputCode = TranformErrorCode(errorCode); NAPI_CALL(env, napi_create_int32(env, outputCode, &code)); - napi_value message = nullptr; NAPI_CALL(env, napi_create_string_utf8(env, errorMessage, NAPI_AUTO_LENGTH, &message)); @@ -379,5 +385,54 @@ void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode, } } +static OHOS::sptr GetBundleMgrProxy() +{ + auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + CM_LOG_E("fail to get system ability mgr."); + return nullptr; + } + + auto remoteObject = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + CM_LOG_E("fail to get bundle manager proxy."); + return nullptr; + } + return OHOS::iface_cast(remoteObject); +} + +int32_t GetCallerLabelName(std::shared_ptr asyncContext) +{ + OHOS::sptr bundleMgrProxy = GetBundleMgrProxy(); + if (bundleMgrProxy == nullptr) { + CM_LOG_E("Failed to get bundle manager proxy."); + return CM_FAILURE; + } + + OHOS::AppExecFwk::BundleInfo bundleInfo; + int32_t flags = static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_DEFAULT) | + static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) | + static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) | + static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY); + int32_t resCode = bundleMgrProxy->GetBundleInfoForSelf(flags, bundleInfo); + if (resCode != CM_SUCCESS) { + CM_LOG_E("Failed to get bundleInfo, resCode is %d", resCode); + return CM_FAILURE; + } + + if (asyncContext->context->GetResourceManager() == nullptr) { + CM_LOG_E("context get resourcemanager faild"); + return CMR_ERROR_NULL_POINTER; + } + + resCode = asyncContext->context->GetResourceManager()->GetStringById(bundleInfo.applicationInfo.labelId, + asyncContext->labelName); + if (resCode != CM_SUCCESS) { + CM_LOG_E("getStringById is faild, resCode is %d", resCode); + return CM_FAILURE; + } + return CM_SUCCESS; +} + } // namespace CertManagerNapi diff --git a/interfaces/kits/napi/src/dialog/cm_napi_open_install_dialog.cpp b/interfaces/kits/napi/src/dialog/cm_napi_open_install_dialog.cpp index cb333b83ff6a2c1b6358996adf53afeb1500cfdc..59a6d20be6baa17e934e29c260862d2971959ccb 100644 --- a/interfaces/kits/napi/src/dialog/cm_napi_open_install_dialog.cpp +++ b/interfaces/kits/napi/src/dialog/cm_napi_open_install_dialog.cpp @@ -186,55 +186,6 @@ static OHOS::AAFwk::Want CMGetInstallCertWant(std::shared_ptr GetBundleMgrProxy() -{ - auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (!systemAbilityManager) { - CM_LOG_E("fail to get system ability mgr."); - return nullptr; - } - - auto remoteObject = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); - if (!remoteObject) { - CM_LOG_E("fail to get bundle manager proxy."); - return nullptr; - } - return OHOS::iface_cast(remoteObject); -} - -static int32_t GetCallerLabelName(std::shared_ptr asyncContext) -{ - OHOS::sptr bundleMgrProxy = GetBundleMgrProxy(); - if (bundleMgrProxy == nullptr) { - CM_LOG_E("Failed to get bundle manager proxy."); - return CM_FAILURE; - } - - OHOS::AppExecFwk::BundleInfo bundleInfo; - int32_t flags = static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_DEFAULT) | - static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION) | - static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE) | - static_cast(OHOS::AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY); - int32_t resCode = bundleMgrProxy->GetBundleInfoForSelf(flags, bundleInfo); - if (resCode != CM_SUCCESS) { - CM_LOG_E("Failed to get bundleInfo, resCode is %d", resCode); - return CM_FAILURE; - } - - if (asyncContext->context->GetResourceManager() == nullptr) { - CM_LOG_E("context get resourcemanager faild"); - return CMR_ERROR_NULL_POINTER; - } - - resCode = asyncContext->context->GetResourceManager()->GetStringById(bundleInfo.applicationInfo.labelId, - asyncContext->labelName); - if (resCode != CM_SUCCESS) { - CM_LOG_E("getStringById is faild, resCode is %d", resCode); - return CM_FAILURE; - } - return CM_SUCCESS; -} - napi_value CMNapiOpenInstallCertDialog(napi_env env, napi_callback_info info) { CM_LOG_D("cert install dialog enter"); diff --git a/interfaces/kits/napi/src/dialog/cm_napi_open_uninstall_dialog.cpp b/interfaces/kits/napi/src/dialog/cm_napi_open_uninstall_dialog.cpp new file mode 100755 index 0000000000000000000000000000000000000000..52e832d883ccec99b679969db431c9e06718d018 --- /dev/null +++ b/interfaces/kits/napi/src/dialog/cm_napi_open_uninstall_dialog.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 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_open_dialog.h" +#include "cm_napi_dialog_common.h" + +#include "cm_log.h" + +#include "syspara/parameters.h" +#include "securec.h" +#include "want.h" +#include "want_params_wrapper.h" + +namespace CMNapi { + +class CmUninstallUIExtensionCallback : public CmUIExtensionCallback { +public: + explicit CmUninstallUIExtensionCallback( + std::shared_ptr& reqContext) : CmUIExtensionCallback(reqContext) + { + this->reqContext_ = reqContext; + } + + ~CmUninstallUIExtensionCallback() override + { + CM_LOG_D("~CmUninstallUIExtensionCallback"); + } + + void OnRelease(const int32_t releaseCode) override + { + CM_LOG_D("UninstallUIExtensionComponent OnRelease(), releaseCode = %d", releaseCode); + if (SetErrorCode(CMR_DIALOG_ERROR_OPERATION_CANCELS)) { + SendMessageBack(); + } + } + + void OnResult(const int32_t resultCode, const OHOS::AAFwk::Want& result) override + { + CM_LOG_D("UninstallUIExtensionComponent OnResult(), resultCode = %d", resultCode); + this->resultCode_ = resultCode; + this->resultWant_ = result; + if (SetErrorCode(this->resultCode_)) { + SendMessageBack(); + } + } + + void OnReceive(const OHOS::AAFwk::WantParams& request) override + { + CM_LOG_D("UninstallUIExtensionComponent OnReceive()"); + if (SetErrorCode(0)) { + SendMessageBack(); + } + } + + void ProcessCallback(napi_env env, const CommonAsyncContext* asyncContext) override + { + napi_value args = nullptr; + if (asyncContext->errCode == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &args)); + } else { + args = GenerateBusinessError(env, asyncContext->errCode); + } + + if (asyncContext->deferred != nullptr) { + if (asyncContext->errCode == CM_SUCCESS) { + NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, asyncContext->deferred, args)); + } else { + NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncContext->deferred, args)); + } + } + } + + void OnDestroy() override + { + CM_LOG_D("UninstallUIExtensionComponent OnDestroy()"); + } + +private: + bool SetErrorCode(int32_t errCode) + { + if (this->reqContext_ == nullptr) { + CM_LOG_E("OnError reqContext is nullptr"); + return false; + } + if (this->alreadyCallback_) { + CM_LOG_D("alreadyCallback"); + return false; + } + this->alreadyCallback_ = true; + this->reqContext_->errCode = errCode; + return true; + }; + int32_t resultCode_ = 0; + OHOS::AAFwk::Want resultWant_; + std::shared_ptr reqContext_ = nullptr; + bool alreadyCallback_ = false; +}; + +static bool CMIsCertificateType(const uint32_t value, uint32_t &pageType) +{ + switch (static_cast(value)) { + case CmCertificateType::CA_CERT: + pageType = CmDialogPageType::PAGE_INSTALL_CA_GUIDE; + return true; + default: + return false; + } +} + +static napi_value CMInitAsyncContext(std::shared_ptr asyncContext, + napi_value argv[], size_t length) +{ + //Parse the first param: context + if (!ParseCmUIAbilityContextReq(asyncContext->env, argv[PARAM0], asyncContext->context)) { + CM_LOG_E("ParseUIAbilityContextReq failed"); + return nullptr; + } + + //Parse the second param: certType + uint32_t certificateType = 0; + if (ParseUint32(asyncContext->env, argv[PARAM1], certificateType) == nullptr) { + CM_LOG_E("parse type failed"); + return nullptr; + } + if (!CMIsCertificateType(certificateType, asyncContext->certificateType)) { + CM_LOG_E("certificateType invalid"); + return nullptr; + } + + //Parse the third param: certUri + if (ParseString(asyncContext->env, argv[PARAM2], asyncContext->certUri) == nullptr) { + CM_LOG_E("certUri is invalid"); + return nullptr; + } + //return 0 + return GetInt32(asyncContext->env, 0); +} + +static OHOS::AAFwk::Want CMGetUninstallCertWant(std::shared_ptr asyncContext) +{ + OHOS::AAFwk::Want want; + want.SetElementName(CERT_MANAGER_BUNDLENAME, CERT_MANAGER_ABILITYNAME); + want.SetParam(CERT_MANAGER_PAGE_TYPE, static_cast(asyncContext->certificateType)); + want.SetParam(CERT_MANAGER_CALLER_BUNDLENAME, asyncContext->labelName); + CmBlob *certUri = asyncContext->certUri; + std::string uriStr(reinterpret_cast(certUri->data), certUri->size); + want.SetParam(CERT_MANAGER_CERT_URI, uriStr); + want.SetParam(PARAM_UI_EXTENSION_TYPE, SYS_COMMON_UI); + want.SetParam(CERT_MANAGER_OPERATION_TYPE, static_cast(DIALOG_OPERATION_UNINSTALL)); + return want; +} + +napi_value CMNapiOpenUninstallCertDialog(napi_env env, napi_callback_info info) +{ + //determine the type of device + CM_LOG_D("enter uninstall cert dialog"); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_undefined(env, &result)); + if (OHOS::system::GetParameter("const.product.devicetype", "") != "2in1") { + CM_LOG_E("device type is not 2in1"); + std::string errMsg = "Device type error, device type is not 2in1"; + ThrowError(env, DIALOG_ERROR_NOT_SUPPORTED, errMsg); + return result; + } + + //determine the number of parameters + size_t argc = PARAM_SIZE_THREE; + napi_value argv[PARAM_SIZE_THREE] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); + if (argc != PARAM_SIZE_THREE) { + CM_LOG_E("param number mismatch"); + std::string errMsg = "Parameter Error. Params number mismatch, need " + std::to_string(PARAM_SIZE_THREE) + + ", given " + std::to_string(argc); + ThrowError(env, PARAM_ERROR, errMsg); + return result; + } + + //parse and init context + auto asyncContext = std::make_shared(env); + asyncContext->env = env; + if (CMInitAsyncContext(asyncContext, argv, argc) == nullptr) { + CM_LOG_E("Parse param and init asyncContext failed"); + ThrowError(env, PARAM_ERROR, "Parse param and init asyncContext failed"); + return nullptr; + } + + //get lable name + if (GetCallerLabelName(asyncContext) != CM_SUCCESS) { + CM_LOG_E("get caller labelName faild"); + ThrowError(env, DIALOG_ERROR_GENERIC, "get caller labelName faild"); + return nullptr; + } + NAPI_CALL(env, napi_create_promise(env, &asyncContext->deferred, &result)); + + //set want params + auto uiExtCallback = std::make_shared(asyncContext); + StartUIExtensionAbility(asyncContext, CMGetUninstallCertWant(asyncContext), uiExtCallback); + CM_LOG_D("cert install dialog end"); + return result; +} +} // namespace CMNapi \ No newline at end of file