f5cee57e2d55ed66f017840a159f7191d30cb721
[platform/core/system/libdbuspolicy.git] / src / internal / serializer.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15 */
16 #include "include/fb_generated.h"
17 #include "include/flatbuffers/flatbuffers.h"
18 #include "serializer.hpp"
19 #include "tslog.hpp"
20 #include <iostream>
21 #include <string>
22
23 namespace ldp_xml_parser {
24
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 }
30 };
31
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 },
37 };
38
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 }
45 };
46
47 template <>
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;
56 };
57
58 template <>
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;
69 };
70
71 template <>
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;
82 };
83
84 template <>
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;
93 };
94
95 uint8_t* Serializer::serialize(const ldp_xml::StorageBackendXML &db, size_t &size) {
96         m_db = &db;
97
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>();
102
103         auto file = FB::CreateFile(m_builder,
104                                    own_set,
105                                    send_set,
106                                    receive_set,
107                                    access_set);
108
109         m_builder.Finish(file, FB::FileIdentifier());
110         uint8_t* buf = m_builder.GetBufferPointer();
111         size = m_builder.GetSize();
112
113         return buf;
114 }
115
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;
119
120         if (!xmlStorage.init(config_path.c_str())) {
121                 std::cout << "xmlStorage init error" << std::endl;
122                 return nullptr;
123         }
124
125         return serialize(xmlStorage, size);
126 }
127
128 uint8_t *Serializer::serialize(const std::string config_path, std::ostream &output) {
129         size_t size = 0;
130         uint8_t *buf = serialize(config_path, size);
131
132         output.write(reinterpret_cast<char *>(buf), size);
133         return buf;
134 }
135
136 template <typename T>
137 auto Serializer::get_create_set() -> decltype(type_helper<T>::create_set) {
138         return type_helper<T>::create_set;
139 }
140
141 template <typename T>
142 auto Serializer::get_create_policy() -> decltype(type_helper<T>::create_policy) {
143         return type_helper<T>::create_policy;
144 }
145
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;
149 }
150
151 template <typename T>
152 auto Serializer::get_create_item() -> decltype(type_helper<T>::create_item) {
153         return type_helper<T>::create_item;
154 }
155
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);
159
160         return policy;
161 }
162
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());
166
167         std::vector<FbOff<FB::PolicyOwnNode>> children;
168
169         for (const auto &subnode : node->getChildren()) {
170                 auto child = serialize_tree(subnode.second);
171                 children.push_back(child);
172         }
173
174         auto policy_own = FB::CreatePolicyOwnNode(m_builder,
175                                                   m_builder.CreateString(node->getToken()),
176                                                   prefix_decision_item,
177                                                   decision_item,
178                                                   m_builder.CreateVectorOfSortedTables(&children));
179         return policy_own;
180 }
181
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()));
186 }
187
188 template <>
189 auto Serializer::serialize_item<PolicyAccess>(const ItemAccess &item) -> FbOff<FB::ItemAccess> {
190         auto create_item = get_create_item<PolicyAccess>();
191
192         return create_item(m_builder,
193                            item.getUid(),
194                            item.getGid(),
195                            serialize_decision(item.getDecision()),
196                            bus_access_map[item.getType()]);
197 }
198
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());
210 }
211
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));
217 }
218
219 template <>
220 auto Serializer::serialize_policy(const PolicyOwn &policy)
221                                     -> FbOff<FB::PolicyOwn> {
222         return serialize_tree(policy.getTree());
223 }
224
225 template <>
226 auto Serializer::serialize_policy(const PolicySend &policy)
227                                     -> FbOff<FB::PolicySend> {
228         std::vector<FbOff<FB::ItemSend>> items;
229
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;
234         uint32_t cnt = 1;
235
236         for (const auto &item : policy.getItems()) {
237                 items.push_back(serialize_item<PolicySend>(item));
238
239                 // create indexes
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
244                         elem.first = cnt;
245                 } else {
246                         // just collect the prefix rules
247                         prefixIndex.push_back(cnt);
248                 }
249                 ++cnt;
250         }
251
252         // serialize main index
253         std::vector<FbOff<FB::NameScoresPair>> index;
254
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
260
261         return FB::CreatePolicySend(m_builder,
262                         m_builder.CreateVector(items),
263                         m_builder.CreateVector(index),
264                         m_builder.CreateVector(prefixIndex));
265 }
266
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;
270
271         for (const auto &item : policy.getItems()) {
272                 items.push_back(serialize_item<T>(item));
273         }
274
275         return serialize_policy<T>(items);
276 }
277
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));
283 }
284
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>());
289
290         return serialize_set<TP>(context_default, context_mandatory);
291 }
292
293 template <>
294 auto Serializer::serialize_set<PolicyAccess>(FbOff<FB::PolicyAccess> context_default,
295                                              FbOff<FB::PolicyAccess> context_mandatory)
296                                                -> FbOff<typename type_helper<PolicyAccess>::set>
297 {
298         return FB::CreateAccessSet(m_builder, context_default, context_mandatory);
299 }
300
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>
305 {
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;
310
311         for (const auto &u : m_db->getPoliciesUser<TP>())
312                 user.push_back(serialize_pair<TP>(u.first, u.second));
313
314         for (const auto &g : m_db->getPoliciesGroup<TP>())
315                 group.push_back(serialize_pair<TP>(g.first, g.second));
316
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));
321 }
322
323 }