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_ipc_interface_code.h"
24 #include "map_string_serializer.h"
25 #include "want.h"
26 #include "iplugin_manager.h"
27
28 static constexpr int32_t SET_POLICY_PARAM_NUM = 3;
29 static constexpr int32_t SET_POLICY_APPID_INDEX = 0;
30 static constexpr int32_t SET_POLICY_POLICY_NAME_INDEX = 1;
31 static constexpr int32_t SET_POLICY_POLICY_VALUE_INDEX = 2;
32
33 namespace OHOS {
34 namespace EDM {
35 const bool REGISTER_RESULT = IPluginManager::GetInstance()->AddPlugin(std::make_shared<SetBrowserPoliciesPlugin>());
36 const char* const BROWSER_POLICY_CHANGED_EVENT = "com.ohos.edm.browserpolicychanged";
37 const char* const EMPTY_OBJECT_STRING = "{}";
38
SetBrowserPoliciesPlugin()39 SetBrowserPoliciesPlugin::SetBrowserPoliciesPlugin()
40 {
41 policyCode_ = EdmInterfaceCode::SET_BROWSER_POLICIES;
42 policyName_ = PolicyName::POLICY_SET_BROWSER_POLICIES;
43 permissionMap_.insert(std::make_pair(
44 FuncOperateType::SET, IPlugin::PolicyPermissionConfig(EdmPermission::PERMISSION_ENTERPRISE_SET_BROWSER_POLICY,
45 IPlugin::PermissionType::SUPER_DEVICE_ADMIN, IPlugin::ApiType::PUBLIC)));
46 permissionMap_.insert(std::make_pair(
47 FuncOperateType::GET, IPlugin::PolicyPermissionConfig("", IPlugin::PermissionType::SUPER_DEVICE_ADMIN,
48 IPlugin::ApiType::PUBLIC)));
49 needSave_ = true;
50 }
51
OnHandlePolicy(std::uint32_t funcCode,MessageParcel & data,MessageParcel & reply,HandlePolicyData & policyData,int32_t userId)52 ErrCode SetBrowserPoliciesPlugin::OnHandlePolicy(std::uint32_t funcCode, MessageParcel &data, MessageParcel &reply,
53 HandlePolicyData &policyData, int32_t userId)
54 {
55 EDMLOGD("SetBrowserPoliciesPlugin OnHandlePolicy.");
56 std::vector<std::string> params;
57 data.ReadStringVector(¶ms);
58 if (params.size() < SET_POLICY_PARAM_NUM) {
59 EDMLOGD("SetBrowserPolicyPlugin param invalid.");
60 return EdmReturnErrCode::PARAM_ERROR;
61 }
62 std::string appid = params[SET_POLICY_APPID_INDEX];
63 std::string policyName = params[SET_POLICY_POLICY_NAME_INDEX];
64 std::string policyValue = params[SET_POLICY_POLICY_VALUE_INDEX];
65 if (appid.empty()) {
66 EDMLOGD("SetBrowserPolicyPlugin param invalid.");
67 return EdmReturnErrCode::PARAM_ERROR;
68 }
69 if (policyData.policyData.empty()) {
70 policyData.policyData = EMPTY_OBJECT_STRING;
71 }
72 if (policyData.mergePolicyData.empty()) {
73 policyData.mergePolicyData = EMPTY_OBJECT_STRING;
74 }
75
76 auto serializer = CjsonSerializer::GetInstance();
77 cJSON* currentPolicies = nullptr;
78 if (!serializer->Deserialize(policyData.policyData, currentPolicies)) {
79 EDMLOGE("SetBrowserPolicyPlugin parse current policies error!");
80 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
81 }
82 cJSON* mergePolicies = nullptr;
83 if (!serializer->Deserialize(policyData.mergePolicyData, mergePolicies)) {
84 EDMLOGE("SetBrowserPolicyPlugin parse merge policies error!");
85 cJSON_Delete(currentPolicies);
86 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
87 }
88
89 ErrCode errCode = ERR_OK;
90 if (policyName.empty()) {
91 errCode = SetRootPolicy(currentPolicies, mergePolicies, appid, policyValue);
92 } else {
93 errCode = SetPolicy(currentPolicies, mergePolicies, appid, policyName, policyValue);
94 }
95 if (errCode != ERR_OK) {
96 cJSON_Delete(currentPolicies);
97 cJSON_Delete(mergePolicies);
98 return errCode;
99 }
100 ErrCode ret = UpdateCurrentAndMergePolicy(currentPolicies, mergePolicies, policyData);
101 cJSON_Delete(currentPolicies);
102 cJSON_Delete(mergePolicies);
103 return ret;
104 }
105
UpdateCurrentAndMergePolicy(cJSON * currentPolicies,cJSON * mergePolicies,HandlePolicyData & policyData)106 ErrCode SetBrowserPoliciesPlugin::UpdateCurrentAndMergePolicy(cJSON* currentPolicies, cJSON* mergePolicies,
107 HandlePolicyData &policyData)
108 {
109 cJSON* currentItem;
110 cJSON_ArrayForEach(currentItem, currentPolicies) {
111 cJSON* policies = cJSON_Duplicate(currentItem, true);
112 if (!cJSON_HasObjectItem(mergePolicies, currentItem->string)) {
113 if (!cJSON_AddItemToObject(mergePolicies, currentItem->string, policies)) {
114 cJSON_Delete(policies);
115 }
116 continue;
117 }
118 cJSON* policyItem;
119 cJSON_ArrayForEach(policyItem, policies) {
120 cJSON* policy = cJSON_Duplicate(policyItem, true);
121 if (!cJSON_AddItemToObject(mergePolicies->child, policyItem->string, policy)) {
122 cJSON_Delete(policy);
123 }
124 }
125 }
126
127 auto serializer = CjsonSerializer::GetInstance();
128 std::string afterHandle;
129 std::string afterMerge;
130 if (!serializer->Serialize(currentPolicies, afterHandle) || !serializer->Serialize(mergePolicies, afterMerge)) {
131 EDMLOGE("SetBrowserPoliciesPlugin serialize current policy and merge policy failed.");
132 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
133 }
134 policyData.isChanged = afterHandle != policyData.policyData;
135 if (policyData.isChanged) {
136 policyData.policyData = afterHandle;
137 }
138 policyData.mergePolicyData = afterMerge;
139 return ERR_OK;
140 }
141
SetRootPolicy(cJSON * currentPolicies,cJSON * mergePolicies,const std::string & appid,const std::string & policyValue)142 ErrCode SetBrowserPoliciesPlugin::SetRootPolicy(cJSON* currentPolicies, cJSON* mergePolicies, const std::string &appid,
143 const std::string &policyValue)
144 {
145 cJSON* policy = cJSON_GetObjectItem(mergePolicies, appid.c_str());
146 if (policy != nullptr) {
147 EDMLOGE("SetBrowserPolicyPlugin another admin has already set this browser policy for this application.");
148 return EdmReturnErrCode::PARAM_ERROR;
149 }
150 cJSON_DeleteItemFromObject(currentPolicies, appid.c_str());
151 if (!policyValue.empty()) {
152 cJSON* value = nullptr;
153 if (!CjsonSerializer::GetInstance()->Deserialize(policyValue, value)) {
154 EDMLOGE("SetBrowserPolicyPlugin parse policyValue error!");
155 return EdmReturnErrCode::PARAM_ERROR;
156 }
157 if (!cJSON_AddItemToObject(currentPolicies, appid.c_str(), value)) {
158 EDMLOGE("SetBrowserPolicyPlugin SetRootPolicy AddItemToObject error!");
159 cJSON_Delete(value);
160 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
161 }
162 }
163 return ERR_OK;
164 }
165
SetPolicy(cJSON * currentPolicies,cJSON * mergePolicies,const std::string & appid,const std::string & policyName,const std::string & policyValue)166 ErrCode SetBrowserPoliciesPlugin::SetPolicy(cJSON* currentPolicies, cJSON* mergePolicies, const std::string &appid,
167 const std::string &policyName, const std::string &policyValue)
168 {
169 cJSON* mergePolicy = cJSON_GetObjectItem(mergePolicies, appid.c_str());
170 if (mergePolicy != nullptr) {
171 if (cJSON_GetObjectItem(mergePolicy, policyName.c_str()) != nullptr) {
172 EDMLOGE("SetBrowserPoliciesPlugin another admin has already set this item policy for this application.");
173 return EdmReturnErrCode::PARAM_ERROR;
174 }
175 }
176 cJSON* policy = cJSON_GetObjectItem(currentPolicies, appid.c_str());
177 if (policy == nullptr) {
178 CJSON_CREATE_OBJECT_AND_CHECK(policy, EdmReturnErrCode::SYSTEM_ABNORMALLY);
179 if (!cJSON_AddItemToObject(currentPolicies, appid.c_str(), policy)) {
180 EDMLOGE("SetBrowserPolicyPlugin AddItemToObject appid error!");
181 cJSON_Delete(policy);
182 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
183 }
184 }
185 cJSON_DeleteItemFromObject(policy, policyName.c_str());
186 return SetPolicyValue(policy, policyName, policyValue);
187 }
188
SetPolicyValue(cJSON * policy,std::string policyName,std::string policyValue)189 ErrCode SetBrowserPoliciesPlugin::SetPolicyValue(cJSON* policy, std::string policyName,
190 std::string policyValue)
191 {
192 if (!policyValue.empty()) {
193 cJSON* value = nullptr;
194 if (!CjsonSerializer::GetInstance()->Deserialize(policyValue, value)) {
195 EDMLOGE("SetBrowserPolicyPlugin parse policyValue error!");
196 return EdmReturnErrCode::PARAM_ERROR;
197 }
198 if (!cJSON_AddItemToObject(policy, policyName.c_str(), value)) {
199 EDMLOGE("SetBrowserPolicyPlugin AddItemToObject value error!");
200 cJSON_Delete(value);
201 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
202 }
203 }
204 return ERR_OK;
205 }
206
OnHandlePolicyDone(std::uint32_t funcCode,const std::string & adminName,bool isGlobalChanged,int32_t userId)207 void SetBrowserPoliciesPlugin::OnHandlePolicyDone(std::uint32_t funcCode, const std::string &adminName,
208 bool isGlobalChanged, int32_t userId)
209 {
210 if (!isGlobalChanged) {
211 return;
212 }
213 NotifyBrowserPolicyChanged();
214 }
215
OnGetPolicy(std::string & policyData,MessageParcel & data,MessageParcel & reply,int32_t userId)216 ErrCode SetBrowserPoliciesPlugin::OnGetPolicy(std::string &policyData, MessageParcel &data, MessageParcel &reply,
217 int32_t userId)
218 {
219 return ERR_OK;
220 }
221
NotifyBrowserPolicyChanged()222 void SetBrowserPoliciesPlugin::NotifyBrowserPolicyChanged()
223 {
224 EDMLOGD("SetBrowserPoliciesPlugin NotifyBrowserPolicyChanged.");
225 AAFwk::Want want;
226 want.SetAction(BROWSER_POLICY_CHANGED_EVENT);
227 EventFwk::CommonEventData eventData;
228 eventData.SetWant(want);
229 if (!EventFwk::CommonEventManager::PublishCommonEvent(eventData)) {
230 EDMLOGE("NotifyBrowserPolicyChanged failed.");
231 }
232 }
233
GetOthersMergePolicyData(const std::string & adminName,int32_t userId,std::string & othersMergePolicyData)234 ErrCode SetBrowserPoliciesPlugin::GetOthersMergePolicyData(const std::string &adminName, int32_t userId,
235 std::string &othersMergePolicyData)
236 {
237 EDMLOGD("SetBrowserPoliciesPlugin GetOthersMergePolicyData before.");
238 AdminValueItemsMap adminValues;
239 IPolicyManager::GetInstance()->GetAdminByPolicyName(GetPolicyName(), adminValues);
240 if (adminValues.empty()) {
241 return ERR_OK;
242 }
243 auto entry = adminValues.find(adminName);
244 if (entry != adminValues.end()) {
245 adminValues.erase(entry);
246 }
247 if (adminValues.empty()) {
248 return ERR_OK;
249 }
250 return MergeBrowserPolicy(adminValues, othersMergePolicyData);
251 }
252
MergeBrowserPolicy(const AdminValueItemsMap & adminValues,std::string & policyData)253 ErrCode SetBrowserPoliciesPlugin::MergeBrowserPolicy(const AdminValueItemsMap &adminValues, std::string &policyData)
254 {
255 cJSON* root = nullptr;
256 CJSON_CREATE_OBJECT_AND_CHECK(root, EdmReturnErrCode::SYSTEM_ABNORMALLY);
257 for (const auto &item : adminValues) {
258 if (!AddBrowserPoliciesToRoot(root, item.second)) {
259 EDMLOGE("SetBrowserPoliciesPlugin MergePolicyData error");
260 cJSON_Delete(root);
261 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
262 }
263 }
264
265 auto serializer = CjsonSerializer::GetInstance();
266 serializer->Serialize(root, policyData);
267 EDMLOGD("SetBrowserPoliciesPlugin MergePolicyData after: %{public}s", policyData.c_str());
268 cJSON_Delete(root);
269 return ERR_OK;
270 }
271
AddBrowserPoliciesToRoot(cJSON * root,const std::string & policiesString)272 bool SetBrowserPoliciesPlugin::AddBrowserPoliciesToRoot(cJSON* root, const std::string &policiesString)
273 {
274 if (policiesString.empty()) {
275 return true;
276 }
277 cJSON* adminPolicies = cJSON_Parse(policiesString.c_str());
278 if (adminPolicies == nullptr) {
279 return false;
280 }
281 cJSON *adminPolicy = adminPolicies->child;
282 while (adminPolicy != nullptr) {
283 cJSON* policy = cJSON_GetObjectItem(root, adminPolicy->string);
284 if (policy == nullptr) {
285 cJSON* copy = cJSON_Duplicate(adminPolicy, true);
286 if (copy == nullptr) {
287 cJSON_Delete(adminPolicies);
288 return false;
289 }
290 if (!cJSON_AddItemToObject(root, adminPolicy->string, copy)) {
291 cJSON_Delete(copy);
292 cJSON_Delete(adminPolicies);
293 return false;
294 }
295 adminPolicy = adminPolicy->next;
296 continue;
297 }
298 if (!AddBrowserPolicyToRoot(policy, adminPolicy)) {
299 cJSON_Delete(adminPolicies);
300 return false;
301 }
302 adminPolicy = adminPolicy->next;
303 }
304 cJSON_Delete(adminPolicies);
305 return true;
306 }
307
AddBrowserPolicyToRoot(cJSON * policy,const cJSON * adminPolicy)308 bool SetBrowserPoliciesPlugin::AddBrowserPolicyToRoot(cJSON* policy, const cJSON* adminPolicy)
309 {
310 cJSON *item = adminPolicy->child;
311 while (item != nullptr) {
312 cJSON_DeleteItemFromObject(policy, item->string);
313 cJSON* copy = cJSON_Duplicate(item, true);
314 if (copy == nullptr) {
315 return false;
316 }
317 if (!cJSON_AddItemToObject(policy, item->string, copy)) {
318 cJSON_Delete(copy);
319 return false;
320 }
321 item = item->next;
322 }
323 return true;
324 }
325 } // namespace EDM
326 } // namespace OHOS
327