• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params);
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