• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &param) -> 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 &param) -> 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 &param)
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 &param, 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, &param](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 &param)
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