From: Adrian Szyndela Date: Mon, 25 Feb 2019 13:42:33 +0000 (+0100) Subject: serialization: extract xml-based db implementation X-Git-Tag: accepted/tizen/unified/20190322.075526~29 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F54%2F200554%2F3;p=platform%2Fcore%2Fsystem%2Flibdbuspolicy.git serialization: extract xml-based db implementation Change-Id: I84ef422a5451192fe18762c16bc14aa7ed4b9d02 --- diff --git a/Makefile.am b/Makefile.am index beb20b7..28d274e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -63,7 +63,8 @@ COMMON_SRC =\ src/internal/tslog.cpp \ src/internal/serializer.cpp \ src/internal/print_content.cpp \ - src/internal/storage_backend_serialized.cpp + src/internal/storage_backend_serialized.cpp \ + src/internal/storage_backend_xml.cpp src_libdbuspolicy1_la_SOURCES =\ $(COMMON_SRC) \ diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index 7ce3b4e..cf53c10 100644 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -5,6 +5,7 @@ #include "print_content.hpp" #include "tslog.hpp" #include "type_list.h" +#include "storage_backend_xml.hpp" #include #include @@ -16,260 +17,6 @@ namespace ldp_xml_parser { -/* The following two are building blocks for PolicySet class. - * They specify if a given PolicySet class supports user and group policies. - */ -/****************** UserAndGroupContext ************************/ -template -class UserAndGroupContext { -protected: - /** Map with policies for different users */ - std::map user; - /** Map with policies for different groups */ - std::map group; - - template - void addItemUser(uid_t uid, T &item) { user[uid].addItem(item); } - - template - void addItemGroup(gid_t gid, T &item) { group[gid].addItem(item); } - - void printContent() const { - for (const auto& i : user) { - std::cerr << "user: " << i.first << std::endl; - i.second.printContent(); - } - - for (const auto& i : group) { - std::cerr << "group: " << i.first << std::endl; - i.second.printContent(); - } - } - - size_t getSize() const { - size_t size = user.size() * sizeof(typename decltype(user)::value_type); - for (const auto& i : user) - size += i.second.getSize(); - - size += group.size() * sizeof(typename decltype(group)::value_type); - for (const auto& i : group) - size += i.second.getSize(); - return size; - } - -public: - const P *getPolicyUser(uid_t uid) const { - tslog::log("---policy_type = USER =", uid, "\n"); - - auto it = user.find(uid); - if (it == user.end()) { - tslog::log_verbose("GetPolicy: Out of Range exception\n"); - return nullptr; - } - return &(it->second); - } - - const P *getPolicyGroup(gid_t gid) const { - tslog::log("---policy_type = GROUP = ", gid, "\n"); - - auto it = group.find(gid); - if (it == group.end()) { - tslog::log_verbose("GetPolicy: Out of Range exception\n"); - return nullptr; - } - return &(it->second); - } - - const std::map &getPoliciesUser() const { return user; } - const std::map &getPoliciesGroup() const { return group; } -}; - -/****************** NoUserAndGroupContext ************************/ -class NoUserAndGroupContext { -protected: - template - void addItemUser(uid_t, T &) { assert(false); } - - template - void addItemGroup(gid_t, T &) { assert(false); } - - void printContent() const {} - size_t getSize() const { return 0; } -}; - -template> -class PolicySet : public UG { - /** Policies for all contexts */ - P contextMandatory; - P contextDefault; - - P &getPolicyContext(ContextType type) { - if (ContextType::MANDATORY == type) - return contextMandatory; - - assert(ContextType::DEFAULT == type); - return contextDefault; - } - -public: - typedef P policy_type; - /** Adds given item to policy - * \param[in] policy_type Policy type - * \param[in] policy_type_value Policy type value - * \param[in] item Item to add - */ - template - void addItem(const PolicyType policy_type, - const PolicyTypeValue policy_type_value, - T &item) { - switch (policy_type) { - case PolicyType::CONTEXT: - getPolicyContext(policy_type_value.context).addItem(item); - break; - case PolicyType::USER: - UG::addItemUser(policy_type_value.user, item); - break; - case PolicyType::GROUP: - UG::addItemGroup(policy_type_value.group, item); - break; - case PolicyType::NONE: - assert(false); - break; - } - } - - const P &getRefPolicyContextMandatory() const { return contextMandatory; } - const P &getRefPolicyContextDefault() const { return contextDefault; } - - const P *getPolicyContextMandatory() const { - tslog::log("---policy_type = CONTEXT = MANDATORY\n"); - return &contextMandatory; - } - - const P *getPolicyContextDefault() const { - tslog::log("---policy_type = CONTEXT = DEFAULT\n"); - return &contextDefault; - } - - void printSet() const { - std::cerr << "context default" << std::endl; - contextDefault.printContent(); - std::cerr << "context mandatory" << std::endl; - contextMandatory.printContent(); - - UG::printContent(); - - std::cerr << "Memory consumption: " << getSetSize() << " B" << std::endl; - } - - size_t getSetSize() const { - size_t size = sizeof(*this); - - size += contextMandatory.getSize(); - size += contextDefault.getSize(); - - size += UG::getSize(); - return size; - } -}; - -/****************** NaivePolicyDbImpl ************************/ -class NaivePolicyDb::NaivePolicyDbImpl { -public: - /** Set of ownership policies */ - PolicySet m_own_set; - /** Set of send policies */ - PolicySet m_send_set; - /** Set of receive policies */ - PolicySet m_receive_set; - /** Set of bus access policies */ - PolicySet m_access_set; - - template - struct MatchPolicy; // provide policy_type in specializations - - template - const typename MatchPolicy::policy_set_type &getPolicySet() const; - template - typename MatchPolicy::policy_set_type &getPolicySet(); - - template ::policy_type, - typename PS = typename MatchPolicy::policy_set_type, - typename ...Args> - DecisionItem getDecisionItem(const T &item, - const P *(PS::*f)(Args ... args) const, - Args ...args) const; -}; - -/* Tie MatchItems with proper policy sets. - * Parameters: T - MatchItem* type - * field - one of m_*_set fields from NaivePolicyDb - * - * The below DEF_GET_POLICY_SET defines specialization for MatchPolicy template, - * and a specialization of NaivePolicyDb::getPolicySet template function - * - * Specialization for MatchPolicy provides field 'policy_type' which specifies - * a type of policy used within 'field' parameter, and field 'policy_set_type' - * which specifies a type of the 'field' parameter. - * Specialization of NaivePolicyDb::getPolicySet returns the 'field'. - * - * For example: DEF_GET_POLICY_SET(MatchItemOwn, m_own_set) defines equivalent to - * MatchPolicy { - * typedef PolicyOwn policy_type; - * typedef PolicySet policy_set_type; - * } - * PolicySet &getPolicySet const; - * - * Thanks to this construction we do not need to manually specify PolicyOwn in functions that - * know MatchItemOwn - it is inferred. - * - */ -#define DEF_GET_POLICY_SET(T, field) \ - template <> struct NaivePolicyDb::NaivePolicyDbImpl::MatchPolicy { \ - typedef decltype(field)::policy_type policy_type; \ - typedef decltype(field) policy_set_type; \ - }; \ - template <> struct NaivePolicyDb::NaivePolicyDbImpl::MatchPolicy { \ - typedef decltype(field) policy_set_type; \ - }; \ - template <> \ - auto NaivePolicyDb::NaivePolicyDbImpl::getPolicySet() const -> decltype((field)) { \ - return field; \ - } \ - template <> \ - auto NaivePolicyDb::NaivePolicyDbImpl::getPolicySet() -> decltype((field)) { \ - return field; \ - } \ - template <> \ - auto NaivePolicyDb::NaivePolicyDbImpl::getPolicySet() -> decltype((field)) { \ - return field; \ - } - -DEF_GET_POLICY_SET(MatchItemOwn, m_own_set) -DEF_GET_POLICY_SET(MatchItemSend, m_send_set) -DEF_GET_POLICY_SET(MatchItemReceive, m_receive_set) -DEF_GET_POLICY_SET(MatchItemAccess, m_access_set) - -#undef DEF_GET_POLICY_SET - -template -DecisionItem NaivePolicyDb::NaivePolicyDbImpl::getDecisionItem(const T &item, - const P *(PS::*f)(Args ... args) const, - Args ...args) const -{ - const auto &policySet = getPolicySet(); - typedef typename std::remove_reference::type PolicySetType; - - auto policy = (policySet.*f)(args...); - if (nullptr == policy) - return Decision::ANY; - - tslog::log_verbose("Checking ", PolicySetType::policy_type::name, " policy for: ", item, "\n"); - - return policy->getDecisionItem(item); -} - void NaivePolicyDb::updateSupplementaryGroups(const VGid &groups, uid_t uid, gid_t gid) const { auto &vsend = getMapGroup(uid); auto &vrecv = getMapGroup(uid); @@ -284,9 +31,9 @@ void NaivePolicyDb::updateSupplementaryGroups(const VGid &groups, uid_t uid, gid /* insert supplementary group */ for (const auto group : groups) { - if (pimpl->getPolicySet().getPolicyGroup(group) != nullptr) + if (backend.existsPolicyForGroup(group)) vsend.push_back(group); - if (pimpl->getPolicySet().getPolicyGroup(group) != nullptr) + if (backend.existsPolicyForGroup(group)) vrecv.push_back(group); vaccess.push_back(group); // no filtering, it will be used once } @@ -303,7 +50,7 @@ void NaivePolicyDb::updateSupplementaryGroupsOwn(const VGid &groups, uid_t uid, vown.push_back(gid); } else { for (const auto group : groups) { - if (pimpl->getPolicySet().getPolicyGroup(group) != nullptr) + if (backend.existsPolicyForGroup(group)) vown.push_back(group); } } @@ -315,21 +62,12 @@ void NaivePolicyDb::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, T &item) { tslog::log("Add item: ", item, ", decision: ", item.getDecision(), "\n"); - pimpl->getPolicySet().addItem(policy_type, policy_type_value, item); + backend.addItem(policy_type, policy_type_value, item); } void NaivePolicyDb::printContent() const { - #define PRINT_SET(x) \ - std::cerr << std::endl << "----" #x "----" << std::endl; \ - (x).printSet(); - - PRINT_SET(pimpl->m_own_set) - PRINT_SET(pimpl->m_send_set) - PRINT_SET(pimpl->m_receive_set) - PRINT_SET(pimpl->m_access_set) - - #undef PRINT_SET + backend.printContent(); for (const auto &mapGroup : mapGroups) { std::cerr << std::endl << "---- mapGroup ----" << std::endl; @@ -347,30 +85,6 @@ void NaivePolicyDb::printContent() const } } -template -DecisionItem NaivePolicyDb::getDecisionItemContextMandatory(const T &item) const -{ - return pimpl->getDecisionItem(item, &NaivePolicyDbImpl::MatchPolicy::policy_set_type::getPolicyContextMandatory); -} - -template -DecisionItem NaivePolicyDb::getDecisionItemContextDefault(const T &item) const -{ - return pimpl->getDecisionItem(item, &NaivePolicyDbImpl::MatchPolicy::policy_set_type::getPolicyContextDefault); -} - -template -DecisionItem NaivePolicyDb::getDecisionItemUser(uid_t uid, const T &item) const -{ - return pimpl->getDecisionItem(item, &NaivePolicyDbImpl::MatchPolicy::policy_set_type::getPolicyUser, uid); -} - -template -DecisionItem NaivePolicyDb::getDecisionItemGroup(gid_t gid, const T &item) const -{ - return pimpl->getDecisionItem(item, &NaivePolicyDbImpl::MatchPolicy::policy_set_type::getPolicyGroup, gid); -} - template <> const VGid *NaivePolicyDb::getGroups(uid_t uid, gid_t) const { @@ -423,83 +137,52 @@ VGid &NaivePolicyDb::getMapGroup(uid_t uid) const } void NaivePolicyDb::clear() { - pimpl = std::unique_ptr{new NaivePolicyDbImpl}; + backend.clear(); } template const T &NaivePolicyDb::getPolicyContextMandatory() const { - return pimpl->getPolicySet().getRefPolicyContextMandatory(); + return backend.getPolicyContextMandatory(); } template const T &NaivePolicyDb::getPolicyContextDefault() const { - return pimpl->getPolicySet().getRefPolicyContextDefault(); + return backend.getPolicyContextDefault(); } template const std::map &NaivePolicyDb::getPoliciesUser() const { - return pimpl->getPolicySet().getPoliciesUser(); + return backend.getPoliciesUser(); } template const std::map &NaivePolicyDb::getPoliciesGroup() const { - return pimpl->getPolicySet().getPoliciesGroup(); + return backend.getPoliciesGroup(); } -NaivePolicyDb::NaivePolicyDb() : pimpl{new NaivePolicyDbImpl} { -} - -NaivePolicyDb::~NaivePolicyDb() = default; - /* Explicit instantiation is needed for used public template methods defined in this file. */ #define T_INSTANTIATION(T) \ - template DecisionItem NaivePolicyDb::getDecisionItemContextMandatory(const T &) const; \ - template DecisionItem NaivePolicyDb::getDecisionItemContextDefault(const T &) const; \ - template const VGid *NaivePolicyDb::getGroups(uid_t, gid_t) const; - -T_INSTANTIATION(MatchItemOwn) -T_INSTANTIATION(MatchItemSend) -T_INSTANTIATION(MatchItemReceive) -T_INSTANTIATION(MatchItemAccess) - -#define T_INSTANTIATION2(T) \ - template DecisionItem NaivePolicyDb::getDecisionItemUser(uid_t, const T &) const; \ - template DecisionItem NaivePolicyDb::getDecisionItemGroup(gid_t, const T &) const; - -T_INSTANTIATION2(MatchItemOwn) -T_INSTANTIATION2(MatchItemSend) -T_INSTANTIATION2(MatchItemReceive) + template const VGid *NaivePolicyDb::getGroups(uid_t, gid_t) const; \ + template void NaivePolicyDb::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, Item##T &item); \ + template const Policy##T &NaivePolicyDb::getPolicyContextMandatory() const; \ + template const Policy##T &NaivePolicyDb::getPolicyContextDefault() const; -#define T_INSTANTIATION3(T) \ - template void NaivePolicyDb::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, T &item); +T_INSTANTIATION(Own) +T_INSTANTIATION(Send) +T_INSTANTIATION(Receive) +T_INSTANTIATION(Access) -T_INSTANTIATION3(ItemOwn) -T_INSTANTIATION3(ItemSend) -T_INSTANTIATION3(ItemReceive) -T_INSTANTIATION3(ItemAccess) - -#define T_INSTANTIATION4(T) \ - template const T &NaivePolicyDb::getPolicyContextMandatory() const; \ - template const T &NaivePolicyDb::getPolicyContextDefault() const; - -T_INSTANTIATION4(PolicyOwn) -T_INSTANTIATION4(PolicySend) -T_INSTANTIATION4(PolicyReceive) -T_INSTANTIATION4(PolicyAccess) +#undef T_INSTANTIATION -#define T_INSTANTIATION5(T) \ - template const std::map &NaivePolicyDb::getPoliciesGroup() const; \ - template const std::map &NaivePolicyDb::getPoliciesUser() const; +#define T_INSTANTIATION(T) \ + template const std::map &NaivePolicyDb::getPoliciesGroup() const; \ + template const std::map &NaivePolicyDb::getPoliciesUser() const; -T_INSTANTIATION5(PolicyOwn) -T_INSTANTIATION5(PolicySend) -T_INSTANTIATION5(PolicyReceive) +T_INSTANTIATION(Own) +T_INSTANTIATION(Send) +T_INSTANTIATION(Receive) #undef T_INSTANTIATION -#undef T_INSTANTIATION2 -#undef T_INSTANTIATION3 -#undef T_INSTANTIATION4 -#undef T_INSTANTIATION5 } // namespace ldp_xml_parser diff --git a/src/internal/naive_policy_db.hpp b/src/internal/naive_policy_db.hpp index 7db549e..9137dfc 100644 --- a/src/internal/naive_policy_db.hpp +++ b/src/internal/naive_policy_db.hpp @@ -16,6 +16,7 @@ #ifndef _NAIVE_DB_H #define _NAIVE_DB_H +#include "storage_backend_xml.hpp" #include #include #include @@ -34,9 +35,7 @@ namespace ldp_xml_parser /** Database class, contains policies for ownership and send/receive */ class NaivePolicyDb { private: - class NaivePolicyDbImpl; - - std::unique_ptr pimpl; + ldp_xml::StorageBackendXML backend; mutable std::map mapGroups[MatchItemTypes::count]; /* A mutex for mapGroups */ @@ -47,27 +46,36 @@ namespace ldp_xml_parser void updateSupplementaryGroups(const VGid &groups, uid_t uid, gid_t gid) const; void updateSupplementaryGroupsOwn(const VGid &groups, uid_t uid, gid_t gid) const; - public: - - NaivePolicyDb(); - ~NaivePolicyDb(); + public: + /***** Common interface for all backends ******/ void printContent() const; template - DecisionItem getDecisionItemContextMandatory(const T &item) const; + DecisionItem getDecisionItemContextMandatory(const T &item) const + { return backend.getDecisionItemContextMandatory(item); } + template - DecisionItem getDecisionItemContextDefault(const T &item) const; + DecisionItem getDecisionItemContextDefault(const T &item) const + { return backend.getDecisionItemContextDefault(item); } + template - DecisionItem getDecisionItemUser(uid_t uid, const T &item) const; + DecisionItem getDecisionItemUser(uid_t uid, const T &item) const + { return backend.getDecisionItemUser(uid, item); } + template - DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const; + DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const + { return backend.getDecisionItemGroup(gid, item); } + /******* Common interface for group maps management **********/ template const VGid *getGroups(uid_t uid, gid_t gid) const; void initializeGroups(uid_t uid, gid_t gid); + /******* Interface for read-write backends (e.g. XML-based) */ + /* This will be probably moved from here */ + /** Adds item to a policy * \param[in] policy_type Policy type * \param[in] policy_type_value Policy type value diff --git a/src/internal/storage_backend_xml.cpp b/src/internal/storage_backend_xml.cpp new file mode 100644 index 0000000..5cfb9cb --- /dev/null +++ b/src/internal/storage_backend_xml.cpp @@ -0,0 +1,366 @@ +#include "storage_backend_xml.hpp" +#include "policy_containers.hpp" + +using namespace ldp_xml_parser; + +namespace ldp_xml { + +/* The following two are building blocks for PolicySet class. + * They specify if a given PolicySet class supports user and group policies. + */ +/****************** UserAndGroupContext ************************/ +template +class UserAndGroupContext { +protected: + /** Map with policies for different users */ + std::map user; + /** Map with policies for different groups */ + std::map group; + + template + void addItemUser(uid_t uid, T &item) { user[uid].addItem(item); } + + template + void addItemGroup(gid_t gid, T &item) { group[gid].addItem(item); } + + void printContent() const { + for (const auto& i : user) { + std::cerr << "user: " << i.first << std::endl; + i.second.printContent(); + } + + for (const auto& i : group) { + std::cerr << "group: " << i.first << std::endl; + i.second.printContent(); + } + } + + size_t getSize() const { + size_t size = user.size() * sizeof(typename decltype(user)::value_type); + for (const auto& i : user) + size += i.second.getSize(); + + size += group.size() * sizeof(typename decltype(group)::value_type); + for (const auto& i : group) + size += i.second.getSize(); + return size; + } + +public: + const P *getPolicyUser(uid_t uid) const { + tslog::log("---policy_type = USER =", uid, "\n"); + + auto it = user.find(uid); + if (it == user.end()) { + tslog::log_verbose("GetPolicy: Out of Range exception\n"); + return nullptr; + } + return &(it->second); + } + + const P *getPolicyGroup(gid_t gid) const { + tslog::log("---policy_type = GROUP = ", gid, "\n"); + + auto it = group.find(gid); + if (it == group.end()) { + tslog::log_verbose("GetPolicy: Out of Range exception\n"); + return nullptr; + } + return &(it->second); + } + + const std::map &getPoliciesUser() const { return user; } + const std::map &getPoliciesGroup() const { return group; } +}; + +/****************** NoUserAndGroupContext ************************/ +class NoUserAndGroupContext { +protected: + template + void addItemUser(uid_t, T &) { assert(false); } + + template + void addItemGroup(gid_t, T &) { assert(false); } + + void printContent() const {} + size_t getSize() const { return 0; } +}; + +/****************** PolicySet ************************/ +template> +class PolicySet : public UG { + /** Policies for all contexts */ + P contextMandatory; + P contextDefault; + + P &getPolicyContext(ContextType type) { + if (ContextType::MANDATORY == type) + return contextMandatory; + + assert(ContextType::DEFAULT == type); + return contextDefault; + } + +public: + typedef P policy_type; + /** Adds given item to policy + * \param[in] policy_type Policy type + * \param[in] policy_type_value Policy type value + * \param[in] item Item to add + */ + template + void addItem(const PolicyType policy_type, + const PolicyTypeValue policy_type_value, + T &item) { + switch (policy_type) { + case PolicyType::CONTEXT: + getPolicyContext(policy_type_value.context).addItem(item); + break; + case PolicyType::USER: + UG::addItemUser(policy_type_value.user, item); + break; + case PolicyType::GROUP: + UG::addItemGroup(policy_type_value.group, item); + break; + case PolicyType::NONE: + assert(false); + break; + } + } + + const P &getRefPolicyContextMandatory() const { return contextMandatory; } + const P &getRefPolicyContextDefault() const { return contextDefault; } + + const P *getPolicyContextMandatory() const { + tslog::log("---policy_type = CONTEXT = MANDATORY\n"); + return &contextMandatory; + } + + const P *getPolicyContextDefault() const { + tslog::log("---policy_type = CONTEXT = DEFAULT\n"); + return &contextDefault; + } + + void printSet() const { + std::cerr << "context default" << std::endl; + contextDefault.printContent(); + std::cerr << "context mandatory" << std::endl; + contextMandatory.printContent(); + + UG::printContent(); + + std::cerr << "Memory consumption: " << getSetSize() << " B" << std::endl; + } + + size_t getSetSize() const { + size_t size = sizeof(*this); + + size += contextMandatory.getSize(); + size += contextDefault.getSize(); + + size += UG::getSize(); + return size; + } +}; + +/****************** StorageBackendXML ************************/ +class StorageBackendXML::StorageBackendXMLImpl { +public: + /** Set of ownership policies */ + PolicySet m_own_set; + /** Set of send policies */ + PolicySet m_send_set; + /** Set of receive policies */ + PolicySet m_receive_set; + /** Set of bus access policies */ + PolicySet m_access_set; + + template + struct MatchPolicy; // provide policy_type in specializations + + template + const typename MatchPolicy::policy_set_type &getPolicySet() const; + template + typename MatchPolicy::policy_set_type &getPolicySet(); + + template ::policy_type, + typename PS = typename MatchPolicy::policy_set_type, + typename ...Args> + DecisionItem getDecisionItem(const T &item, + const P *(PS::*f)(Args ... args) const, + Args ...args) const; +}; + +/* Tie MatchItems with proper policy sets. + * Parameters: T - MatchItem* type + * field - one of m_*_set fields from StorageBackendXMLImpl + * + * The below DEF_GET_POLICY_SET defines specialization for MatchPolicy template, + * and a specialization of StorageBackendXMLImpl::getPolicySet template function + * + * Specialization for MatchPolicy provides field 'policy_type' which specifies + * a type of policy used within 'field' parameter, and field 'policy_set_type' + * which specifies a type of the 'field' parameter. + * Specialization of StorageBackendXMLImpl::getPolicySet returns the 'field'. + * + * For example: DEF_GET_POLICY_SET(MatchItemOwn, m_own_set) defines equivalent to + * MatchPolicy { + * typedef PolicyOwn policy_type; + * typedef PolicySet policy_set_type; + * } + * PolicySet &getPolicySet const; + * + * Thanks to this construction we do not need to manually specify PolicyOwn in functions that + * know MatchItemOwn - it is inferred. + * + */ +#define DEF_GET_POLICY_SET(T, field) \ + template <> struct StorageBackendXML::StorageBackendXMLImpl::MatchPolicy { \ + typedef decltype(field)::policy_type policy_type; \ + typedef decltype(field) policy_set_type; \ + }; \ + template <> struct StorageBackendXML::StorageBackendXMLImpl::MatchPolicy { \ + typedef decltype(field) policy_set_type; \ + }; \ + template <> \ + auto StorageBackendXML::StorageBackendXMLImpl::getPolicySet() const -> decltype((field)) { \ + return field; \ + } \ + template <> \ + auto StorageBackendXML::StorageBackendXMLImpl::getPolicySet() -> decltype((field)) { \ + return field; \ + } \ + template <> \ + auto StorageBackendXML::StorageBackendXMLImpl::getPolicySet() -> decltype((field)) { \ + return field; \ + } + +DEF_GET_POLICY_SET(MatchItemOwn, m_own_set) +DEF_GET_POLICY_SET(MatchItemSend, m_send_set) +DEF_GET_POLICY_SET(MatchItemReceive, m_receive_set) +DEF_GET_POLICY_SET(MatchItemAccess, m_access_set) + +#undef DEF_GET_POLICY_SET + +template +DecisionItem StorageBackendXML::StorageBackendXMLImpl::getDecisionItem(const T &item, + const P *(PS::*f)(Args ... args) const, + Args ...args) const +{ + const auto &policySet = getPolicySet(); + typedef typename std::remove_reference::type PolicySetType; + + auto policy = (policySet.*f)(args...); + if (nullptr == policy) + return Decision::ANY; + + tslog::log_verbose("Checking ", PolicySetType::policy_type::name, " policy for: ", item, "\n"); + + return policy->getDecisionItem(item); +} + +template +void StorageBackendXML::addItem(const ldp_xml_parser::PolicyType policy_type, + const ldp_xml_parser::PolicyTypeValue policy_type_value, + T &item) { + pimpl->getPolicySet().addItem(policy_type, policy_type_value, item); +} + +void StorageBackendXML::clear() { + pimpl.reset(new StorageBackendXMLImpl); +} + +void StorageBackendXML::printContent() const { + #define PRINT_SET(x) \ + std::cerr << std::endl << "----" #x "----" << std::endl; \ + (x).printSet(); + + PRINT_SET(pimpl->m_own_set) + PRINT_SET(pimpl->m_send_set) + PRINT_SET(pimpl->m_receive_set) + PRINT_SET(pimpl->m_access_set) + + #undef PRINT_SET +} + +template +const T &StorageBackendXML::getPolicyContextMandatory() const { + return pimpl->getPolicySet().getRefPolicyContextMandatory(); +} + +template +const T &StorageBackendXML::getPolicyContextDefault() const { + return pimpl->getPolicySet().getRefPolicyContextDefault(); +} + +template +const std::map &StorageBackendXML::getPoliciesUser() const { + return pimpl->getPolicySet().getPoliciesUser(); +} + +template +const std::map &StorageBackendXML::getPoliciesGroup() const { + return pimpl->getPolicySet().getPoliciesGroup(); +} + +template +bool StorageBackendXML::existsPolicyForGroup(gid_t gid) const { + return pimpl->getPolicySet().getPolicyGroup(gid) != nullptr; +} + +template +ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextMandatory(const T &item) const { + return pimpl->getDecisionItem(item, &StorageBackendXMLImpl::MatchPolicy::policy_set_type::getPolicyContextMandatory); +} + +template +ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextDefault(const T &item) const { + return pimpl->getDecisionItem(item, &StorageBackendXMLImpl::MatchPolicy::policy_set_type::getPolicyContextDefault); +} + +template +ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemUser(uid_t uid, const T &item) const { + return pimpl->getDecisionItem(item, &StorageBackendXMLImpl::MatchPolicy::policy_set_type::getPolicyUser, uid); +} + +template +ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemGroup(gid_t gid, const T &item) const { + return pimpl->getDecisionItem(item, &StorageBackendXMLImpl::MatchPolicy::policy_set_type::getPolicyGroup, gid); +} + +StorageBackendXML::StorageBackendXML() : pimpl{new StorageBackendXMLImpl} { +} + +StorageBackendXML::~StorageBackendXML() = default; + +/* Explicit instantiation is needed for used public template methods defined in this file. + */ +#define T_INSTANTIATION(T) \ + template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextMandatory(const MatchItem##T &item) const; \ + template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemContextDefault(const MatchItem##T &item) const; \ + template void StorageBackendXML::addItem(const PolicyType policy_type, const PolicyTypeValue policy_type_value, Item##T &item); \ + template const Policy##T &StorageBackendXML::getPolicyContextMandatory() const; \ + template const Policy##T &StorageBackendXML::getPolicyContextDefault() const; + +T_INSTANTIATION(Own) +T_INSTANTIATION(Send) +T_INSTANTIATION(Receive) +T_INSTANTIATION(Access) + +#undef T_INSTANTIATION + +#define T_INSTANTIATION(T) \ + template bool StorageBackendXML::existsPolicyForGroup(gid_t gid) const; \ + template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemUser(uid_t uid, const MatchItem##T &item) const; \ + template ldp_xml_parser::DecisionItem StorageBackendXML::getDecisionItemGroup(gid_t gid, const MatchItem##T &item) const; \ + template const std::map &StorageBackendXML::getPoliciesGroup() const; \ + template const std::map &StorageBackendXML::getPoliciesUser() const; + +T_INSTANTIATION(Own) +T_INSTANTIATION(Send) +T_INSTANTIATION(Receive) + +#undef T_INSTANTIATION + +} // namespace ldp_xml diff --git a/src/internal/storage_backend_xml.hpp b/src/internal/storage_backend_xml.hpp new file mode 100644 index 0000000..dd4cffc --- /dev/null +++ b/src/internal/storage_backend_xml.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include "policy.hpp" +#include +#include +#include + +namespace ldp_xml { + +class StorageBackendXML { + class StorageBackendXMLImpl; + std::unique_ptr pimpl; +public: + StorageBackendXML(); + ~StorageBackendXML(); + + // This works with T set to MatchItemOwn, MatchItemSend, MatchItemReceive or MatchItemAccess + template + void addItem(const ldp_xml_parser::PolicyType policy_type, + const ldp_xml_parser::PolicyTypeValue policy_type_value, + T &item); + + void clear(); + + void printContent() const; + + // The getPolicy*() methods are intended for Serializers to get + // access to policy structures. + // Supported template parameters are: PolicyOwn, PolicySend, PolicyReceive + // and for PolicyAccess only getPolicyContext*() + template + const T &getPolicyContextMandatory() const; + template + const T &getPolicyContextDefault() const; + template + const std::map &getPoliciesUser() const; + template + const std::map &getPoliciesGroup() const; + + // This works with T set to MatchItemOwn, MatchItemSend or MatchItemReceive + // This is needed for filtering mapGroups. Check NaivePolicyDb. + template + bool existsPolicyForGroup(gid_t gid) const; + + // These work with T set to MatchItemOwn, MatchItemSend, MatchItemReceive or MatchItemAccess + template + ldp_xml_parser::DecisionItem getDecisionItemContextMandatory(const T &item) const; + template + ldp_xml_parser::DecisionItem getDecisionItemContextDefault(const T &item) const; + template + ldp_xml_parser::DecisionItem getDecisionItemUser(uid_t uid, const T &item) const; + template + ldp_xml_parser::DecisionItem getDecisionItemGroup(gid_t gid, const T &item) const; +}; + +}