• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #define LOG_TAG "DirectoryManager"
16 #include "directory_manager.h"
17 
18 #include <dirent.h>
19 #include <sys/stat.h>
20 
21 #include <string>
22 
23 #include "accesstoken_kit.h"
24 #include "log_print.h"
25 #include "types.h"
26 #include "unistd.h"
27 namespace OHOS::DistributedData {
28 using OHOS::DistributedKv::SecurityLevel;
29 using namespace OHOS::Security::AccessToken;
DirectoryManager()30 DirectoryManager::DirectoryManager()
31     : actions_({ { "{security}", &DirectoryManager::GetSecurity }, { "{store}", &DirectoryManager::GetStore },
32         { "{type}", &DirectoryManager::GetType }, { "{area}", &DirectoryManager::GetArea },
33         { "{userId}", &DirectoryManager::GetUserId }, { "{bundleName}", &DirectoryManager::GetBundleName },
34         { "{hapName}", &DirectoryManager::GetHapName } })
35 {
36 }
37 
GetInstance()38 DirectoryManager &DirectoryManager::GetInstance()
39 {
40     static DirectoryManager instance;
41     return instance;
42 }
43 
GetStorePath(const StoreMetaData & metaData,uint32_t version)44 std::string DirectoryManager::GetStorePath(const StoreMetaData &metaData, uint32_t version)
45 {
46     return GenPath(metaData, version, "");
47 }
48 
GetStoreBackupPath(const StoreMetaData & metaData,uint32_t version)49 std::string DirectoryManager::GetStoreBackupPath(const StoreMetaData &metaData, uint32_t version)
50 {
51     auto rootBackupPath = GenPath(metaData, version, "backup");
52     return rootBackupPath + "/" + metaData.storeId;
53 }
54 
GetSecretKeyPath(const StoreMetaData & metaData,uint32_t version)55 std::string DirectoryManager::GetSecretKeyPath(const StoreMetaData &metaData, uint32_t version)
56 {
57     return GenPath(metaData, version, "secret");
58 }
59 
GetMetaStorePath(uint32_t version)60 std::string DirectoryManager::GetMetaStorePath(uint32_t version)
61 {
62     int32_t index = GetVersionIndex(version);
63     if (index < 0) {
64         return "";
65     }
66 
67     auto &strategy = strategies_[index];
68     if (strategy.autoCreate) {
69         CreateDirectory(strategy.metaPath);
70     }
71     return strategy.metaPath;
72 }
73 
GetMetaBackupPath(uint32_t version)74 std::string DirectoryManager::GetMetaBackupPath(uint32_t version)
75 {
76     int32_t index = GetVersionIndex(version);
77     if (index < 0) {
78         return "";
79     }
80 
81     auto &strategy = strategies_[index];
82     std::string path = strategy.metaPath + "/backup";
83     if (strategy.autoCreate) {
84         CreateDirectory(path);
85     }
86     return path;
87 }
88 
Initialize(const std::vector<Strategy> & strategies)89 void DirectoryManager::Initialize(const std::vector<Strategy> &strategies)
90 {
91     strategies_.resize(strategies.size());
92     for (size_t i = 0; i < strategies.size(); ++i) {
93         const Strategy &strategy = strategies[i];
94         StrategyImpl &impl = strategies_[i];
95         impl.autoCreate = strategy.autoCreate;
96         impl.version = strategy.version;
97         impl.metaPath = strategy.metaPath;
98         impl.path = Split(strategy.pattern, "/");
99         impl.pipes.clear();
100         for (auto &value : impl.path) {
101             auto it = actions_.find(value);
102             impl.pipes.push_back(it == actions_.end() ? nullptr : it->second);
103         }
104     }
105 
106     std::sort(strategies_.begin(), strategies_.end(),
107         [](const StrategyImpl &curr, const StrategyImpl &prev) { return curr.version > prev.version; });
108 }
109 
GetType(const StoreMetaData & metaData) const110 std::string DirectoryManager::GetType(const StoreMetaData &metaData) const
111 {
112     auto type = AccessTokenKit::GetTokenTypeFlag(metaData.tokenId);
113     if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
114         return "service";
115     }
116     return "app";
117 }
118 
GetStore(const StoreMetaData & metaData) const119 std::string DirectoryManager::GetStore(const StoreMetaData &metaData) const
120 {
121     if (metaData.storeType >= StoreMetaData::StoreType::STORE_KV_BEGIN
122         && metaData.storeType <= StoreMetaData::StoreType::STORE_KV_END) {
123         return "kvdb";
124     }
125     // rdb use empty session
126     if (metaData.storeType >= StoreMetaData::StoreType::STORE_RELATIONAL_BEGIN
127         && metaData.storeType <= StoreMetaData::StoreType::STORE_RELATIONAL_END) {
128         return "rdb";
129     }
130     return "other";
131 }
132 
GetSecurity(const StoreMetaData & metaData) const133 std::string DirectoryManager::GetSecurity(const StoreMetaData &metaData) const
134 {
135     switch (metaData.securityLevel) {
136         case SecurityLevel::NO_LABEL:
137             if ((metaData.bundleName != metaData.appId) || (metaData.appType != "harmony")) {
138                 break;
139             }
140             [[fallthrough]];
141         case SecurityLevel::S0: [[fallthrough]];
142         case SecurityLevel::S1:
143             return "misc_de";
144     }
145     return "misc_ce";
146 }
147 
GetArea(const StoreMetaData & metaData) const148 std::string DirectoryManager::GetArea(const StoreMetaData &metaData) const
149 {
150     return std::string("el") + std::to_string(metaData.area);
151 }
152 
GetUserId(const StoreMetaData & metaData) const153 std::string DirectoryManager::GetUserId(const StoreMetaData &metaData) const
154 {
155     auto type = AccessTokenKit::GetTokenTypeFlag(metaData.tokenId);
156     if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
157         return "public";
158     }
159     return metaData.user;
160 }
161 
GetBundleName(const StoreMetaData & metaData) const162 std::string DirectoryManager::GetBundleName(const StoreMetaData &metaData) const
163 {
164     if (metaData.instanceId == 0) {
165         return metaData.bundleName;
166     }
167     return metaData.bundleName + "_" + std::to_string(metaData.instanceId);
168 }
169 
GetHapName(const StoreMetaData & metaData) const170 std::string DirectoryManager::GetHapName(const StoreMetaData &metaData) const
171 {
172     return metaData.hapName;
173 }
174 
Split(const std::string & source,const std::string & pattern) const175 std::vector<std::string> DirectoryManager::Split(const std::string &source, const std::string &pattern) const
176 {
177     std::vector<std::string> values;
178     std::string::size_type pos = 0;
179     std::string::size_type nextPos = 0;
180     while (nextPos != std::string::npos) {
181         nextPos = source.find(pattern, pos);
182         if (nextPos == pos) {
183             pos = pos + pattern.size();
184             continue;
185         }
186         values.push_back(source.substr(pos, nextPos - pos));
187         pos = nextPos + pattern.size();
188     }
189     return values;
190 }
191 
GetVersionIndex(uint32_t version) const192 int32_t DirectoryManager::GetVersionIndex(uint32_t version) const
193 {
194     for (size_t i = 0; i < strategies_.size(); ++i) {
195         if (version >= strategies_[i].version) {
196             return i;
197         }
198     }
199     return int32_t(strategies_.size()) - 1;
200 }
201 
GetVersions()202 std::vector<uint32_t> DirectoryManager::GetVersions()
203 {
204     std::vector<uint32_t> versions;
205     for (size_t i = 0; i < strategies_.size(); ++i) {
206         versions[i] = strategies_[i].version;
207     }
208     return versions;
209 }
210 
GenPath(const StoreMetaData & metaData,uint32_t version,const std::string & exPath) const211 std::string DirectoryManager::GenPath(const StoreMetaData &metaData, uint32_t version, const std::string &exPath) const
212 {
213     int32_t index = GetVersionIndex(version);
214     if (index < 0) {
215         return "";
216     }
217     std::string path;
218     auto &strategy = strategies_[index];
219     for (size_t i = 0; i < strategy.pipes.size(); ++i) {
220         std::string section;
221         if (strategy.pipes[i] == nullptr) {
222             section = strategy.path[i];
223         } else {
224             section = (this->*(strategy.pipes[i]))(metaData);
225         }
226         if (section.empty()) {
227             continue;
228         }
229         path += "/" + section;
230     }
231     if (!exPath.empty()) {
232         path += "/" + exPath;
233     }
234     if (strategy.autoCreate) {
235         CreateDirectory(path);
236     }
237     return path;
238 }
239 
CreateDirectory(const std::string & path) const240 bool DirectoryManager::CreateDirectory(const std::string &path) const
241 {
242     if (access(path.c_str(), F_OK) == 0) {
243         return true;
244     }
245 
246     std::string::size_type index = 0;
247     do {
248         std::string subPath;
249         index = path.find('/', index + 1);
250         if (index == std::string::npos) {
251             subPath = path;
252         } else {
253             subPath = path.substr(0, index);
254         }
255 
256         if (access(subPath.c_str(), F_OK) != 0) {
257             if (mkdir(subPath.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0) {
258                 return false;
259             }
260         }
261     } while (index != std::string::npos);
262 
263     return access(path.c_str(), F_OK) == 0;
264 }
265 } // namespace OHOS::DistributedData
266