1 /*
2 * Copyright (c) 2022 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 #define LOG_TAG "PermitDelegate"
17 #include "permit_delegate.h"
18 #include "device_manager_adapter.h"
19 #include "log_print.h"
20 #include "metadata/appid_meta_data.h"
21 #include "metadata/meta_data_manager.h"
22 #include "metadata/strategy_meta_data.h"
23 #include "permission/permission_validator.h"
24 #include "runtime_config.h"
25 #include "store_types.h"
26 #include "user_delegate.h"
27 #include "utils/anonymous.h"
28
29 namespace OHOS::DistributedData {
30 using DBStatus = DistributedDB::DBStatus;
31 using DBConfig = DistributedDB::RuntimeConfig;
32 using DBFlag = DistributedDB::PermissionCheckFlag;
33 using PermissionValidator = OHOS::DistributedKv::PermissionValidator;
34
PermitDelegate()35 PermitDelegate::PermitDelegate()
36 {}
37
~PermitDelegate()38 PermitDelegate::~PermitDelegate()
39 {}
40
GetInstance()41 PermitDelegate &PermitDelegate::GetInstance()
42 {
43 static PermitDelegate permit;
44 return permit;
45 }
46
Init()47 void PermitDelegate::Init()
48 {
49 auto activeCall = [this](const ActiveParam ¶m) -> bool {
50 return SyncActivate(param);
51 };
52 DBStatus status = DBConfig::SetSyncActivationCheckCallback(activeCall);
53 ZLOGI("set active callback status:%d.", status);
54
55 auto permitCall = [this](const CheckParam &Param, uint8_t flag) -> bool {
56 return VerifyPermission(Param, flag);
57 };
58 status = DBConfig::SetPermissionCheckCallback(permitCall);
59 ZLOGI("set permission callback status:%d.", status);
60
61 auto extraCall = [this](const CondParam ¶m) -> std::map<std::string, std::string> {
62 return GetExtraCondition(param);
63 };
64 status = DBConfig::SetPermissionConditionCallback(extraCall);
65 ZLOGI("set extra condition call status:%d.", status);
66 }
67
SyncActivate(const ActiveParam & param)68 bool PermitDelegate::SyncActivate(const ActiveParam ¶m)
69 {
70 ZLOGD("user:%{public}s, app:%{public}s, store:%{public}s, instanceId:%{public}d",
71 param.userId.c_str(), param.appId.c_str(), param.storeId.c_str(), param.instanceId);
72 if (param.instanceId != 0) {
73 return false;
74 }
75 std::set<std::string> activeUsers = UserDelegate::GetInstance().GetLocalUsers();
76 return activeUsers.count(param.userId);
77 }
78
VerifyPermission(const CheckParam & param,uint8_t flag)79 bool PermitDelegate::VerifyPermission(const CheckParam ¶m, uint8_t flag)
80 {
81 ZLOGI("user:%{public}s, appId:%{public}s, storeId:%{public}s, remote devId:%{public}s, instanceId:%{public}d,"
82 "flag:%{public}u", param.userId.c_str(), param.appId.c_str(), Anonymous::Change(param.storeId).c_str(),
83 Anonymous::Change(param.deviceId).c_str(), param.instanceId, flag);
84
85 auto devId = DeviceManagerAdapter::GetInstance().GetLocalDevice().uuid;
86 StoreMetaData data;
87 data.user = param.userId == "default" ? DEFAULT_USER : param.userId;
88 data.storeId = param.storeId;
89 data.deviceId = devId;
90 data.instanceId = param.instanceId;
91 appId2BundleNameMap_.Compute(param.appId, [&data, ¶m](const auto &key, std::string &value) {
92 if (!value.empty()) {
93 data.bundleName = value;
94 return true;
95 }
96 AppIDMetaData appIDMeta;
97 MetaDataManager::GetInstance().LoadMeta(key, appIDMeta, true);
98 if (appIDMeta.appId == param.appId) {
99 data.bundleName = appIDMeta.bundleName;
100 value = appIDMeta.bundleName;
101 }
102 return !value.empty();
103 });
104 auto key = data.GetKey();
105 if (!metaDataBucket_.Get(key, data)) {
106 if (!MetaDataManager::GetInstance().LoadMeta(key, data)) {
107 ZLOGE("load meta failed.");
108 return false;
109 }
110 metaDataBucket_.Set(data.GetKey(), data);
111 }
112 if (data.appType.compare("default") == 0) {
113 ZLOGD("default, sync permission success.");
114 return true;
115 }
116 auto status = VerifyStrategy(data, param.deviceId);
117 if (status != Status::SUCCESS) {
118 ZLOGE("verify strategy failed.");
119 return false;
120 }
121 return PermissionValidator::GetInstance().CheckSyncPermission(data.tokenId);
122 }
123
VerifyExtraCondition(const std::map<std::string,std::string> & cond) const124 bool PermitDelegate::VerifyExtraCondition(const std::map<std::string, std::string> &cond) const
125 {
126 (void)cond;
127 return true;
128 }
129
GetExtraCondition(const CondParam & param)130 std::map<std::string, std::string> PermitDelegate::GetExtraCondition(const CondParam ¶m)
131 {
132 (void)param;
133 return {};
134 }
135
VerifyStrategy(const StoreMetaData & data,const std::string & rmdevId) const136 Status PermitDelegate::VerifyStrategy(const StoreMetaData &data, const std::string &rmdevId) const
137 {
138 StrategyMeta local(data.deviceId, data.user, data.bundleName, data.storeId);
139 MetaDataManager::GetInstance().LoadMeta(local.GetKey(), local);
140 StrategyMeta remote(rmdevId, data.user, data.bundleName, data.storeId);
141 MetaDataManager::GetInstance().LoadMeta(remote.GetKey(), remote);
142 if (!local.IsEffect() || !remote.IsEffect()) {
143 ZLOGD("no range, sync permission success.");
144 return Status::SUCCESS;
145 }
146 auto lremotes = local.capabilityRange.remoteLabel;
147 auto rlocals = remote.capabilityRange.localLabel;
148 for (const auto &lrmote : lremotes) {
149 if (std::find(rlocals.begin(), rlocals.end(), lrmote) != rlocals.end()) {
150 ZLOGD("find range, sync permission success.");
151 return Status::SUCCESS;
152 }
153 }
154 return Status::ERROR;
155 }
156
DelCache(const std::string & key)157 void PermitDelegate::DelCache(const std::string &key)
158 {
159 metaDataBucket_.Delete(key);
160 }
161 } // namespace OHOS::DistributedData
162