1 /*
2 * Copyright (c) 2022-2023 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 "trust_group_manager.h"
17
18 #include "device_profile_errors.h"
19 #include "device_profile_log.h"
20 #include "device_profile_storage_manager.h"
21 #include "device_profile_utils.h"
22 #include "dp_device_manager.h"
23 #include "sync_coordinator.h"
24
25 namespace OHOS {
26 namespace DeviceProfile {
27 namespace {
28 const std::string TAG = "TrustGroupManager";
29
30 constexpr int32_t VISIBILITY_PUBLIC = -1;
31 const std::string AUTH_APPID = "device_profile_auth";
32 }
33
34 IMPLEMENT_SINGLE_INSTANCE(TrustGroupManager);
35
from_json(const nlohmann::json & jsonObject,GroupInfo & groupInfo)36 void from_json(const nlohmann::json& jsonObject, GroupInfo& groupInfo)
37 {
38 if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end() && jsonObject[FIELD_GROUP_NAME].is_string()) {
39 jsonObject.at(FIELD_GROUP_NAME).get_to(groupInfo.groupName);
40 }
41 if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end() && jsonObject[FIELD_GROUP_ID].is_string()) {
42 jsonObject.at(FIELD_GROUP_ID).get_to(groupInfo.groupId);
43 }
44 if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end() && jsonObject[FIELD_GROUP_OWNER].is_string()) {
45 jsonObject.at(FIELD_GROUP_OWNER).get_to(groupInfo.groupOwner);
46 }
47 if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end() && jsonObject[FIELD_GROUP_TYPE].is_number_integer()) {
48 jsonObject.at(FIELD_GROUP_TYPE).get_to(groupInfo.groupType);
49 }
50 if (jsonObject.find(FIELD_GROUP_VISIBILITY) != jsonObject.end() &&
51 jsonObject[FIELD_GROUP_VISIBILITY].is_number_integer()) {
52 jsonObject.at(FIELD_GROUP_VISIBILITY).get_to(groupInfo.groupVisibility);
53 }
54 }
55
InitHichainService()56 bool TrustGroupManager::InitHichainService()
57 {
58 if (hichainGmInstance_ != nullptr) {
59 return true;
60 }
61
62 if (InitDeviceAuthService() != ERR_OK) {
63 HILOGE("auth InitDeviceAuthService failed");
64 return false;
65 }
66
67 hichainGmInstance_ = GetGmInstance();
68 if (hichainGmInstance_ == nullptr) {
69 HILOGE("auth GetGmInstance failed");
70 return false;
71 }
72
73 InitDataChangeListener();
74 HILOGI("init succeeded");
75 return true;
76 }
77
InitDataChangeListener()78 void TrustGroupManager::InitDataChangeListener()
79 {
80 dataChangeListener_.onDeviceUnBound = OnDeviceUnBoundAdapter;
81 if (hichainGmInstance_->regDataChangeListener(AUTH_APPID.c_str(), &dataChangeListener_) != 0) {
82 HILOGE("auth RegDataChangeListener failed");
83 }
84 }
85
CheckTrustGroup(const std::string & deviceId)86 bool TrustGroupManager::CheckTrustGroup(const std::string& deviceId)
87 {
88 if (!InitHichainService()) {
89 HILOGE("auth GetGmInstance failed");
90 return false;
91 }
92
93 uint32_t groupNum = 0;
94 char* returnGroups = nullptr;
95 int32_t ret = hichainGmInstance_->getRelatedGroups(ANY_OS_ACCOUNT, AUTH_APPID.c_str(), deviceId.c_str(),
96 &returnGroups, &groupNum);
97 if (ret != ERR_OK) {
98 HILOGE("failed, ret:%{public}d", ret);
99 return false;
100 }
101 return CheckGroupsInfo(returnGroups, groupNum);
102 }
103
CheckGroupsInfo(const char * returnGroups,uint32_t groupNum)104 bool TrustGroupManager::CheckGroupsInfo(const char* returnGroups, uint32_t groupNum)
105 {
106 if (returnGroups == nullptr || groupNum == 0) {
107 HILOGE("failed, returnGroups is nullptr");
108 return false;
109 }
110
111 nlohmann::json jsonObject = nlohmann::json::parse(returnGroups, nullptr, false);
112 if (jsonObject.is_discarded()) {
113 HILOGE("returnGroups parse error");
114 return false;
115 }
116 if (!jsonObject.is_array()) {
117 HILOGE("not array type");
118 return false;
119 }
120 std::vector<GroupInfo> groupInfos = jsonObject.get<std::vector<GroupInfo>>();
121 for (const auto& groupInfo : groupInfos) {
122 // check group visibility is whether public or not
123 if (groupInfo.groupVisibility != VISIBILITY_PUBLIC) {
124 continue;
125 }
126
127 // check group type is whether (same count or point to point) or not
128 if (groupInfo.groupType == GroupType::IDENTICAL_ACCOUNT_GROUP ||
129 groupInfo.groupType == GroupType::PEER_TO_PEER_GROUP) {
130 HILOGI("check success type = %{public}d", groupInfo.groupType);
131 return true;
132 }
133 }
134 HILOGE("check failed, not in trust group");
135 return false;
136 }
137
OnDeviceUnBoundAdapter(const char * peerUdid,const char * groupInfo)138 void TrustGroupManager::OnDeviceUnBoundAdapter(const char* peerUdid, const char* groupInfo)
139 {
140 const std::string udid = peerUdid;
141 if (!CheckDeviceId(udid)) {
142 return;
143 }
144
145 auto removeUnBoundDeviceTask = [udid = std::move(udid)]() {
146 HILOGI("remove unbound deivce profile start, udid = %{public}s",
147 DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
148 if (GetInstance().CheckTrustGroup(udid)) {
149 HILOGI("unbound device in trust group");
150 return;
151 }
152
153 if (DeviceProfileStorageManager::GetInstance().RemoveUnBoundDeviceProfile(udid) != ERR_OK) {
154 HILOGE("remove unbound device profile failed, udid = %{public}s",
155 DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
156 } else {
157 HILOGI("remove unbound deivce profile success, udid = %{public}s",
158 DeviceProfileUtils::AnonymizeDeviceId(udid).c_str());
159 }
160 DpDeviceManager::GetInstance().RemoveDeviceIdsByUdid(udid);
161 };
162 if (!SyncCoordinator::GetInstance().DispatchSyncTask(removeUnBoundDeviceTask)) {
163 HILOGE("post task failed");
164 return;
165 }
166 }
167
CheckDeviceId(const std::string udid)168 bool TrustGroupManager::CheckDeviceId(const std::string udid)
169 {
170 std::string localDeviceId;
171 DpDeviceManager::GetInstance().GetLocalDeviceUdid(localDeviceId);
172 if (udid.empty() || localDeviceId.empty()) {
173 HILOGE("device id is empty");
174 return false;
175 }
176
177 if (udid == localDeviceId) {
178 return false;
179 }
180 return true;
181 }
182 } // namespace DeviceProfile
183 } // namespace OHOS