2 * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "include/fb_generated.h"
17 #include "include/flatbuffers/flatbuffers.h"
18 #include "serializer.hpp"
23 namespace ldp_xml_parser {
25 std::map<Decision, FB::Decision> decisions_map {
26 { Decision::ANY, FB::Decision_ANY },
27 { Decision::DENY, FB::Decision_DENY },
28 { Decision::ALLOW, FB::Decision_ALLOW },
29 { Decision::CHECK, FB::Decision_CHECK }
32 std::map<BusAccessType, FB::BusAccessType> bus_access_map {
33 { BusAccessType::USER, FB::BusAccessType_USER },
34 { BusAccessType::GROUP, FB::BusAccessType_GROUP },
35 { BusAccessType::ALL_USERS, FB::BusAccessType_ALL_USERS },
36 { BusAccessType::ALL_GROUPS, FB::BusAccessType_ALL_GROUPS },
39 std::map<MessageType, FB::MessageType> message_type_map {
40 { MessageType::ANY, FB::MessageType_ANY },
41 { MessageType::METHOD_CALL, FB::MessageType_METHOD_CALL },
42 { MessageType::METHOD_RETURN, FB::MessageType_METHOD_RETURN },
43 { MessageType::ERROR, FB::MessageType_ERROR },
44 { MessageType::SIGNAL, FB::MessageType_SIGNAL }
48 struct Serializer::type_helper<PolicyOwn> {
49 typedef struct FB::OwnSet set;
50 typedef struct FB::OwnSetBuilder builder;
51 typedef struct FB::PolicyOwn policy;
52 typedef struct FB::PolicyOwnPair pair;
53 static constexpr auto create_set = &FB::CreateOwnSet;
54 static constexpr auto create_policy = &FB::CreatePolicyOwn;
55 static constexpr auto create_policy_pair = &FB::CreatePolicyOwnPair;
59 struct Serializer::type_helper<PolicySend> {
60 typedef struct FB::SendSet set;
61 typedef struct FB::SendSetBuilder builder;
62 typedef struct FB::PolicySend policy;
63 typedef struct FB::PolicySendPair pair;
64 typedef struct FB::ItemSend item;
65 static constexpr auto create_set = &FB::CreateSendSet;
66 static constexpr auto create_policy = &FB::CreatePolicySend;
67 static constexpr auto create_policy_pair = &FB::CreatePolicySendPair;
68 static constexpr auto create_item = &FB::CreateItemSend;
72 struct Serializer::type_helper<PolicyReceive> {
73 typedef struct FB::ReceiveSet set;
74 typedef struct FB::ReceiveSetBuilder builder;
75 typedef struct FB::PolicyReceive policy;
76 typedef struct FB::PolicyReceivePair pair;
77 typedef struct FB::ItemReceive item;
78 static constexpr auto create_set = &FB::CreateReceiveSet;
79 static constexpr auto create_policy = &FB::CreatePolicyReceive;
80 static constexpr auto create_policy_pair = &FB::CreatePolicyReceivePair;
81 static constexpr auto create_item = &FB::CreateItemReceive;
85 struct Serializer::type_helper<PolicyAccess> {
86 typedef struct FB::AccessSet set;
87 typedef struct FB::AccessSetBuilder builder;
88 typedef struct FB::PolicyAccess policy;
89 typedef struct FB::ItemAccess item;
90 static constexpr auto create_set = &FB::CreateAccessSet;
91 static constexpr auto create_policy = &FB::CreatePolicyAccess;
92 static constexpr auto create_item = &FB::CreateItemAccess;
95 uint8_t* Serializer::serialize(const ldp_xml::StorageBackendXML &db, size_t &size) {
98 auto own_set = serialize_set<PolicyOwn>();
99 auto send_set = serialize_set<PolicySend>();
100 auto receive_set = serialize_set<PolicyReceive>();
101 auto access_set = serialize_set<PolicyAccess>();
103 auto file = FB::CreateFile(m_builder,
109 m_builder.Finish(file, FB::FileIdentifier());
110 uint8_t* buf = m_builder.GetBufferPointer();
111 size = m_builder.GetSize();
116 uint8_t* Serializer::serialize(const std::string config_path, size_t &size) {
117 tslog::init(tslog::ldp_log_level::DEFAULT);
118 ldp_xml::StorageBackendXML xmlStorage;
120 if (!xmlStorage.init(config_path.c_str())) {
121 std::cout << "xmlStorage init error" << std::endl;
125 return serialize(xmlStorage, size);
128 uint8_t *Serializer::serialize(const std::string config_path, std::ostream &output) {
130 uint8_t *buf = serialize(config_path, size);
132 output.write(reinterpret_cast<char *>(buf), size);
136 template <typename T>
137 auto Serializer::get_create_set() -> decltype(type_helper<T>::create_set) {
138 return type_helper<T>::create_set;
141 template <typename T>
142 auto Serializer::get_create_policy() -> decltype(type_helper<T>::create_policy) {
143 return type_helper<T>::create_policy;
146 template <typename T>
147 auto Serializer::get_create_policy_pair() -> decltype(type_helper<T>::create_policy_pair) {
148 return type_helper<T>::create_policy_pair;
151 template <typename T>
152 auto Serializer::get_create_item() -> decltype(type_helper<T>::create_item) {
153 return type_helper<T>::create_item;
156 FbOff<FB::PolicyOwn> Serializer::serialize_tree(const OwnershipTree &tree) {
157 auto tree_item = serialize_tree(tree.getRoot());
158 auto policy = FB::CreatePolicyOwn(m_builder, tree_item);
163 FbOff<FB::PolicyOwnNode> Serializer::serialize_tree(const std::shared_ptr<TreeNode> &node) {
164 auto prefix_decision_item = serialize_decision(node->getOwnPrefixDecisionItem());
165 auto decision_item = serialize_decision(node->getOwnDecisionItem());
167 std::vector<FbOff<FB::PolicyOwnNode>> children;
169 for (const auto &subnode : node->getChildren()) {
170 auto child = serialize_tree(subnode.second);
171 children.push_back(child);
174 auto policy_own = FB::CreatePolicyOwnNode(m_builder,
175 m_builder.CreateString(node->getToken()),
176 prefix_decision_item,
178 m_builder.CreateVectorOfSortedTables(&children));
182 FbOff<FB::DecisionItem> Serializer::serialize_decision(const DecisionItem &item) {
183 return FB::CreateDecisionItem(m_builder,
184 decisions_map[item.getDecision()],
185 m_builder.CreateString(item.getPrivilege()));
189 auto Serializer::serialize_item<PolicyAccess>(const ItemAccess &item) -> FbOff<FB::ItemAccess> {
190 auto create_item = get_create_item<PolicyAccess>();
192 return create_item(m_builder,
195 serialize_decision(item.getDecision()),
196 bus_access_map[item.getType()]);
199 template <typename T, typename P>
200 auto Serializer::serialize_item(const P &item) -> FbOff<typename type_helper<T>::item> {
201 auto create_item = get_create_item<T>();
202 return create_item(m_builder,
203 serialize_decision(item.getDecision()),
204 m_builder.CreateString(item.getName()),
205 m_builder.CreateString(item.getInterface()),
206 m_builder.CreateString(item.getMember()),
207 m_builder.CreateString(item.getPath()),
208 message_type_map[item.getType()],
209 item.isNamePrefix());
212 template <typename T>
213 auto Serializer::serialize_policy(const std::vector<FbOff<typename type_helper<T>::item>> items)
214 -> FbOff<typename type_helper<T>::policy> {
215 auto create_policy = get_create_policy<T>();
216 return create_policy(m_builder, m_builder.CreateVector(items));
220 auto Serializer::serialize_policy(const PolicyOwn &policy)
221 -> FbOff<FB::PolicyOwn> {
222 return serialize_tree(policy.getTree());
226 auto Serializer::serialize_policy(const PolicySend &policy)
227 -> FbOff<FB::PolicySend> {
228 std::vector<FbOff<FB::ItemSend>> items;
230 // this maps a name to a pair (highest score + list of scores/ids for this name)
231 std::map<boost::string_ref, std::pair<uint32_t, std::vector<uint32_t>>> policyIndex;
232 // prefix index is just a list of ids
233 std::vector<uint32_t> prefixIndex;
236 for (const auto &item : policy.getItems()) {
237 items.push_back(serialize_item<PolicySend>(item));
240 if (!item.isNamePrefix()) {
241 auto &elem = policyIndex[item.getName()]; // create or get an entry
242 elem.second.push_back(cnt); // add score/id to the list
243 // we insert items in increasing score/id order, so we just update the highest score on each add
246 // just collect the prefix rules
247 prefixIndex.push_back(cnt);
252 // serialize main index
253 std::vector<FbOff<FB::NameScoresPair>> index;
255 for (auto &it: policyIndex)
256 index.push_back(FB::CreateNameScoresPairDirect(m_builder,
257 it.first.data(), // name
258 it.second.first, // best_score
259 &it.second.second)); // vector of scores/ids
261 return FB::CreatePolicySend(m_builder,
262 m_builder.CreateVector(items),
263 m_builder.CreateVector(index),
264 m_builder.CreateVector(prefixIndex));
267 template <typename T>
268 auto Serializer::serialize_policy(const T &policy) -> FbOff<typename type_helper<T>::policy> {
269 std::vector<FbOff<typename type_helper<T>::item>> items;
271 for (const auto &item : policy.getItems()) {
272 items.push_back(serialize_item<T>(item));
275 return serialize_policy<T>(items);
278 template <typename T, typename P>
279 auto Serializer::serialize_pair(const long int id, const P policy)
280 -> FbOff<typename type_helper<T>::pair> {
281 auto create_policy_pair = get_create_policy_pair<T>();
282 return create_policy_pair(m_builder, id, serialize_policy(policy));
285 template <typename TP>
286 auto Serializer::serialize_set() -> FbOff<typename type_helper<TP>::set> {
287 auto context_default = serialize_policy<TP>(m_db->getPolicyContextDefault<TP>());
288 auto context_mandatory = serialize_policy<TP>(m_db->getPolicyContextMandatory<TP>());
290 return serialize_set<TP>(context_default, context_mandatory);
294 auto Serializer::serialize_set<PolicyAccess>(FbOff<FB::PolicyAccess> context_default,
295 FbOff<FB::PolicyAccess> context_mandatory)
296 -> FbOff<typename type_helper<PolicyAccess>::set>
298 return FB::CreateAccessSet(m_builder, context_default, context_mandatory);
301 template <typename TP, typename TFP>
302 auto Serializer::serialize_set(FbOff<TFP> context_default,
303 FbOff<TFP> context_mandatory)
304 -> FbOff<typename type_helper<TP>::set>
306 std::vector<FbOff<typename type_helper<TP>::pair>> user;
307 std::vector<FbOff<typename type_helper<TP>::pair>> group;
308 std::vector<long long> uid;
309 std::vector<long long> gid;
311 for (const auto &u : m_db->getPoliciesUser<TP>())
312 user.push_back(serialize_pair<TP>(u.first, u.second));
314 for (const auto &g : m_db->getPoliciesGroup<TP>())
315 group.push_back(serialize_pair<TP>(g.first, g.second));
317 auto func = get_create_set<TP>();
318 return func(m_builder, context_default, context_mandatory,
319 m_builder.CreateVectorOfSortedTables(&user),
320 m_builder.CreateVectorOfSortedTables(&group));