1 /*
2  * Copyright (c) 2023-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 "set_browser_policies_plugin.h"
17 
18 #include "bundle_manager_utils.h"
19 #include "cjson_check.h"
20 #include "cjson_serializer.h"
21 #include "common_event_manager.h"
22 #include "common_event_support.h"
23 #include "edm_constants.h"
24 #include "edm_ipc_interface_code.h"
25 #include "map_string_serializer.h"
26 #include "want.h"
27 #include "plugin_manager.h"
28 
29 static constexpr int32_t SET_POLICY_PARAM_NUM = 3;
30 static constexpr int32_t SET_POLICY_APPID_INDEX = 0;
31 static constexpr int32_t SET_POLICY_POLICY_NAME_INDEX = 1;
32 static constexpr int32_t SET_POLICY_POLICY_VALUE_INDEX = 2;
33 
34 namespace OHOS {
35 namespace EDM {
36 const bool REGISTER_RESULT = PluginManager::GetInstance()->AddPlugin(std::make_shared<SetBrowserPoliciesPlugin>());
37 const char* const BROWSER_POLICY_CHANGED_EVENT = "com.ohos.edm.browserpolicychanged";
38 
SetBrowserPoliciesPlugin()39 SetBrowserPoliciesPlugin::SetBrowserPoliciesPlugin()
40 {
41     policyCode_ = EdmInterfaceCode::SET_BROWSER_POLICIES;
42     policyName_ = "set_browser_policies";
43     permissionMap_.insert(std::make_pair(
44         FuncOperateType::SET, IPlugin::PolicyPermissionConfig("ohos.permission.ENTERPRISE_SET_BROWSER_POLICY",
45         IPlugin::PermissionType::SUPER_DEVICE_ADMIN, IPlugin::ApiType::PUBLIC)));
46     needSave_ = true;
47 }
48 
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,HandlePolicyData & policyData,int32_t userId)49 ErrCode SetBrowserPoliciesPlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
50     HandlePolicyData &policyData, int32_t userId)
51 {
52     EDMLOGD("SetBrowserPoliciesPlugin OnHandlePolicy.");
53     std::string beforeHandle = policyData.policyData;
54     std::string afterHandle;
55     ErrCode errCode = ERR_OK;
56     int32_t type = data.ReadInt32();
57     if (type == EdmConstants::SET_POLICY_TYPE) {
58         std::vector<std::string> params;
59         data.ReadStringVector(&params);
60         if (params.size() < SET_POLICY_PARAM_NUM) {
61             EDMLOGD("SetBrowserPolicyPlugin param invalid.");
62             return EdmReturnErrCode::PARAM_ERROR;
63         }
64         std::string appid = params[SET_POLICY_APPID_INDEX];
65         std::string policyName = params[SET_POLICY_POLICY_NAME_INDEX];
66         std::string policyValue = params[SET_POLICY_POLICY_VALUE_INDEX];
67         if (appid.empty()) {
68             EDMLOGD("SetBrowserPolicyPlugin param invalid.");
69             return EdmReturnErrCode::PARAM_ERROR;
70         }
71 
72         if (beforeHandle.empty()) {
73             beforeHandle = "{}";
74         }
75 
76         if (policyName.empty()) {
77             errCode = SetRootPolicy(beforeHandle, appid, policyValue, afterHandle);
78         } else {
79             errCode = SetPolicy(beforeHandle, appid, policyName, policyValue, afterHandle);
80         }
81     } else if (type == EdmConstants::SET_POLICIES_TYPE) {
82         auto serializer_ = MapStringSerializer::GetInstance();
83         std::map<std::string, std::string> policies;
84         std::map<std::string, std::string> policyDataMap;
85         serializer_->GetPolicy(data, policies);
86         serializer_->Deserialize(beforeHandle, policyDataMap);
87         errCode = SetPolicies(policies, policyDataMap);
88         serializer_->Serialize(policyDataMap, afterHandle);
89     } else {
90         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
91     }
92 
93     if (errCode != ERR_OK) {
94         return errCode;
95     }
96 
97     policyData.isChanged = afterHandle != beforeHandle;
98     if (policyData.isChanged) {
99         policyData.policyData = afterHandle;
100     }
101 
102     return errCode;
103 }
104 
SetPolicies(std::map<std::string,std::string> & policies,std::map<std::string,std::string> & currentData)105 ErrCode SetBrowserPoliciesPlugin::SetPolicies(std::map<std::string, std::string> &policies,
106     std::map<std::string, std::string> &currentData)
107 {
108     EDMLOGD("SetBrowserPoliciesPlugin OnSetPolicy.");
109     if (policies.empty()) {
110         EDMLOGD("SetBrowserPoliciesPlugin policies is empty.");
111         return EdmReturnErrCode::PARAM_ERROR;
112     }
113     auto iter = policies.begin();
114     if (iter->second.empty()) {
115         currentData.erase(iter->first);
116     } else {
117         currentData[iter->first] = iter->second;
118     }
119     return ERR_OK;
120 }
121 
SetRootPolicy(const std::string policyData,std::string appid,std::string policyValue,std::string & afterHandle)122 ErrCode SetBrowserPoliciesPlugin::SetRootPolicy(const std::string policyData, std::string appid,
123     std::string policyValue, std::string &afterHandle)
124 {
125     cJSON* policies = nullptr;
126     auto serializer_ = CjsonSerializer::GetInstance();
127     if (!serializer_->Deserialize(policyData, policies)) {
128         EDMLOGD("SetBrowserPolicyPlugin parse policies error!");
129         return EdmReturnErrCode::PARAM_ERROR;
130     }
131     cJSON_DeleteItemFromObject(policies, appid.c_str());
132     if (!policyValue.empty()) {
133         cJSON* value = nullptr;
134         if (!serializer_->Deserialize(policyValue, value)) {
135             EDMLOGD("SetBrowserPolicyPlugin parse policyValue error!");
136             cJSON_Delete(policies);
137             return EdmReturnErrCode::PARAM_ERROR;
138         }
139         std::string valueString;
140         serializer_->Serialize(value, valueString);
141         cJSON_Delete(value);
142         cJSON_AddStringToObject(policies, appid.c_str(), valueString.c_str());
143     }
144     serializer_->Serialize(policies, afterHandle);
145     cJSON_Delete(policies);
146     return ERR_OK;
147 }
148 
SetPolicy(const std::string policyData,std::string appid,std::string policyName,std::string policyValue,std::string & afterHandle)149 ErrCode SetBrowserPoliciesPlugin::SetPolicy(const std::string policyData, std::string appid, std::string policyName,
150     std::string policyValue, std::string &afterHandle)
151 {
152     cJSON* policies = nullptr;
153     auto serializer_ = CjsonSerializer::GetInstance();
154     if (!serializer_->Deserialize(policyData, policies)) {
155         EDMLOGE("SetBrowserPolicyPlugin parse policies error!");
156         return EdmReturnErrCode::PARAM_ERROR;
157     }
158 
159     cJSON* beforeParsedPolicy = cJSON_GetObjectItem(policies, appid.c_str());
160     cJSON* policy = nullptr;
161     if (beforeParsedPolicy == nullptr) {
162         cJSON* appidObj = nullptr;
163         CJSON_CREATE_OBJECT_AND_CHECK_AND_CLEAR(appidObj, EdmReturnErrCode::SYSTEM_ABNORMALLY, policies);
164         if (!cJSON_AddItemToObject(policies, appid.c_str(), appidObj)) {
165             EDMLOGE("SetBrowserPolicyPlugin AddItemToObject appid error!");
166             cJSON_Delete(policies);
167             cJSON_Delete(appidObj);
168             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
169         }
170         CJSON_CREATE_OBJECT_AND_CHECK_AND_CLEAR(policy, EdmReturnErrCode::SYSTEM_ABNORMALLY, policies);
171     } else {
172         std::string beforeParsedPolicyString = cJSON_GetStringValue(beforeParsedPolicy);
173         if (!serializer_->Deserialize(beforeParsedPolicyString, policy)) {
174             EDMLOGE("SetBrowserPolicyPlugin parse policies error!");
175             cJSON_Delete(policies);
176             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
177         }
178     }
179     cJSON_DeleteItemFromObject(policy, policyName.c_str());
180     ErrCode ret = SetPolicyValue(policy, policyName, policyValue);
181     if (ret != ERR_OK) {
182         cJSON_Delete(policies);
183         cJSON_Delete(policy);
184         return ret;
185     }
186     std::string policyString;
187     serializer_->Serialize(policy, policyString);
188     cJSON_ReplaceItemInObject(policies, appid.c_str(), cJSON_CreateString(policyString.c_str()));
189     serializer_->Serialize(policies, afterHandle);
190     cJSON_Delete(policies);
191     cJSON_Delete(policy);
192     return ERR_OK;
193 }
194 
SetPolicyValue(cJSON * policy,std::string policyName,std::string policyValue)195 ErrCode SetBrowserPoliciesPlugin::SetPolicyValue(cJSON* policy, std::string policyName,
196     std::string policyValue)
197 {
198     if (!policyValue.empty()) {
199         cJSON* value = nullptr;
200         if (!CjsonSerializer::GetInstance()->Deserialize(policyValue, value)) {
201             EDMLOGE("SetBrowserPolicyPlugin parse policyValue error!");
202             return EdmReturnErrCode::PARAM_ERROR;
203         }
204         if (!cJSON_AddItemToObject(policy, policyName.c_str(), value)) {
205             EDMLOGE("SetBrowserPolicyPlugin AddItemToObject value error!");
206             cJSON_Delete(value);
207             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
208         }
209     }
210     return ERR_OK;
211 }
212 
OnHandlePolicyDone(std::uint32_t funcCode,const std::string & adminName,bool isGlobalChanged,int32_t userId)213 void SetBrowserPoliciesPlugin::OnHandlePolicyDone(std::uint32_t funcCode, const std::string &adminName,
214     bool isGlobalChanged, int32_t userId)
215 {
216     if (!isGlobalChanged) {
217         return;
218     }
219     NotifyBrowserPolicyChanged();
220 }
221 
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)222 ErrCode SetBrowserPoliciesPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
223     int32_t userId)
224 {
225     auto mapStringSerilizer_ = MapStringSerializer::GetInstance();
226     std::map<std::string, std::string> policies;
227     mapStringSerilizer_->Deserialize(policyData, policies);
228     std::string appId = data.ReadString();
229     if (appId.empty() && FAILED(BundleManagerUtils::GetAppIdByCallingUid(appId))) {
230         reply.WriteInt32(EdmReturnErrCode::SYSTEM_ABNORMALLY);
231         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
232     }
233     reply.WriteInt32(ERR_OK);
234     std::string policy;
235     if (policies.count(appId) > 0) {
236         policy = policies[appId];
237     }
238     reply.WriteString(policy);
239     return ERR_OK;
240 }
241 
NotifyBrowserPolicyChanged()242 void SetBrowserPoliciesPlugin::NotifyBrowserPolicyChanged()
243 {
244     EDMLOGD("SetBrowserPoliciesPlugin NotifyBrowserPolicyChanged.");
245     AAFwk::Want want;
246     want.SetAction(BROWSER_POLICY_CHANGED_EVENT);
247     EventFwk::CommonEventData eventData;
248     eventData.SetWant(want);
249     if (!EventFwk::CommonEventManager::PublishCommonEvent(eventData)) {
250         EDMLOGE("NotifyBrowserPolicyChanged failed.");
251     }
252 }
253 } // namespace EDM
254 } // namespace OHOS
255