From 9d2f5358901d8a982ac138982c0c1938adbbcaad Mon Sep 17 00:00:00 2001 From: Michal Eljasiewicz Date: Mon, 26 Jan 2015 12:27:03 +0100 Subject: [PATCH] Wrapper for cynara_admin_list_policies_descriptions Change-Id: I6b07e4fb0b8e1395a3d867bcdecf1e79b3839772 Signed-off-by: Michal Eljasiewicz --- src/common/cynara.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++ src/common/include/cynara.h | 51 +++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/src/common/cynara.cpp b/src/common/cynara.cpp index 39b7e05..156ff26 100644 --- a/src/common/cynara.cpp +++ b/src/common/cynara.cpp @@ -205,7 +205,11 @@ static bool checkCynaraError(int result, const std::string &msg) } } +CynaraAdmin::TypeToDescriptionMap CynaraAdmin::TypeToDescription; +CynaraAdmin::DescriptionToTypeMap CynaraAdmin::DescriptionToType; + CynaraAdmin::CynaraAdmin() + : m_policyDescriptionsInitialized(false) { checkCynaraError( cynara_admin_initialize(&m_CynaraAdmin), @@ -380,6 +384,67 @@ void CynaraAdmin::EmptyBucket(const std::string &bucketName, bool recursive, con client + ", " + user + ", " + privilege); } +void CynaraAdmin::FetchCynaraPolicyDescriptions(bool forceRefresh) +{ + struct cynara_admin_policy_descr **descriptions = nullptr; + + if (!forceRefresh && m_policyDescriptionsInitialized) + return; + + // fetch + checkCynaraError( + cynara_admin_list_policies_descriptions(m_CynaraAdmin, &descriptions), + "Error while getting list of policies descriptions from Cynara."); + + if (descriptions[0] == nullptr) { + LogError("Fetching policies levels descriptions from Cynara returned empty list. " + "There should be at least 2 entries - Allow and Deny"); + return; + } + + // reset the state + m_policyDescriptionsInitialized = false; + DescriptionToType.clear(); + TypeToDescription.clear(); + + // extract strings + for (int i = 0; descriptions[i] != nullptr; i++) { + std::string descriptionName(descriptions[i]->name); + + DescriptionToType[descriptionName] = descriptions[i]->result; + TypeToDescription[descriptions[i]->result] = std::move(descriptionName); + + free(descriptions[i]->name); + free(descriptions[i]); + } + + free(descriptions); + + m_policyDescriptionsInitialized = true; +} + +void CynaraAdmin::ListPoliciesDescriptions(std::vector &policiesDescriptions) +{ + FetchCynaraPolicyDescriptions(false); + + for (auto it = TypeToDescription.rbegin(); it != TypeToDescription.rend(); ++it) + policiesDescriptions.push_back(it->second); +} + +std::string CynaraAdmin::convertToPolicyDescription(const int policyType, bool forceRefresh) +{ + FetchCynaraPolicyDescriptions(forceRefresh); + + return TypeToDescription.at(policyType); +} + +int CynaraAdmin::convertToPolicyType(const std::string &policy, bool forceRefresh) +{ + FetchCynaraPolicyDescriptions(forceRefresh); + + return DescriptionToType.at(policy); +} + Cynara::Cynara() { checkCynaraError( diff --git a/src/common/include/cynara.h b/src/common/include/cynara.h index ce103f0..1f37f96 100644 --- a/src/common/include/cynara.h +++ b/src/common/include/cynara.h @@ -91,6 +91,9 @@ public: typedef std::map BucketsMap; static BucketsMap Buckets; + typedef std::map TypeToDescriptionMap; + typedef std::map DescriptionToTypeMap; + virtual ~CynaraAdmin(); static CynaraAdmin &getInstance(); @@ -159,6 +162,43 @@ public: const std::string &privilege, std::vector &policies); + /** + * Wrapper for Cynara API function cynara_admin_list_policies_descriptions. + * It collects all policies descriptions, extracts names + * of policies and returns as std strings. Caller is responsible for clearing + * vector passed as argument. + * + * @param policiesDescriptions empty vector for policies descriptions. + */ + void ListPoliciesDescriptions(std::vector &policiesDescriptions); + + /** + * Function translates internal Cynara policy type integer to string + * description. Descriptions are retrieved from Cynara using + * ListPoliciesDescriptions() function. Caller can force refetching of + * descriptions list from Cynara on each call. + * + * @throws std::out_of_range + * + * @param policyType Cynara policy result type. + * @param forceRefresh switch to force refetching of descriptions from Cynara. + */ + std::string convertToPolicyDescription(const int policyType, bool forceRefresh = false); + + /** + * Function translates Cynara policy result string + * description to internal Cynara policy type integer. + * Descriptions are retrieved from Cynara using + * ListPoliciesDescriptions() function. Caller can force refetching of + * descriptions list from Cynara on each call. + * + * @throws std::out_of_range + * + * @param policy Cynara policy result string description. + * @param forceRefresh switch to force refetching of descriptions from Cynara. + */ + int convertToPolicyType(const std::string &policy, bool forceRefresh = false); + private: CynaraAdmin(); @@ -174,7 +214,18 @@ private: void EmptyBucket(const std::string &bucketName, bool recursive, const std::string &client, const std::string &user, const std::string &privilege); + /** + * Get Cynara policies result descriptions and cache them in std::map + * + * @param forceRefresh true if you want to reinitialize mappings + */ + void FetchCynaraPolicyDescriptions(bool forceRefresh = false); + struct cynara_admin *m_CynaraAdmin; + + static TypeToDescriptionMap TypeToDescription; + static DescriptionToTypeMap DescriptionToType; + bool m_policyDescriptionsInitialized; }; class Cynara -- 2.7.4