Add api side implementation of plugin descriptions listing 30/32630/4
authorZofia Abramowska <z.abramowska@samsung.com>
Fri, 19 Dec 2014 09:52:22 +0000 (10:52 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Tue, 23 Dec 2014 16:30:24 +0000 (17:30 +0100)
Add:
* description of api function cynara_admin_list_policies_descriptions
* implementation in admin-api
* utilities for creating null terminated array

Change-Id: I4b7d56757e22fab4cce81665f16ceef61f3a0e2c

src/admin/api/ApiInterface.h
src/admin/api/admin-api.cpp
src/admin/logic/Logic.cpp
src/admin/logic/Logic.h
src/admin/logic/OfflineLogic.cpp
src/admin/logic/OfflineLogic.h
src/admin/logic/OnlineLogic.cpp
src/admin/logic/OnlineLogic.h
src/admin/logic/Utility.h [new file with mode: 0644]
src/include/cynara-admin-types.h
src/include/cynara-admin.h

index 89ac978..9484b7f 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <types/Policy.h>
 #include <types/PolicyBucketId.h>
+#include <types/PolicyDescription.h>
 #include <types/PolicyKey.h>
 #include <types/PolicyResult.h>
 
@@ -56,6 +57,7 @@ public:
                              std::vector<Policy> &policies) = 0;
     virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive,
                               const PolicyKey &filter) = 0;
+    virtual int listDescriptions(std::vector<PolicyDescription> &descriptions) = 0;
 
 };
 
index d3b6a36..10077df 100644 (file)
 
 #include <functional>
 #include <map>
-#include <memory>
-#include <new>
 #include <stdexcept>
 #include <string>
-#include <string.h>
+#include <cstring>
 #include <vector>
 
 #include <common.h>
@@ -36,6 +34,7 @@
 #include <types/Policy.h>
 #include <types/PolicyBucket.h>
 #include <types/PolicyBucketId.h>
+#include <types/PolicyDescription.h>
 #include <types/PolicyKey.h>
 #include <types/PolicyResult.h>
 #include <types/PolicyType.h>
@@ -45,6 +44,8 @@
 
 #include <api/ApiInterface.h>
 #include <logic/Logic.h>
+#include <logic/OnlineLogic.h>
+#include <logic/Utility.h>
 
 struct cynara_admin {
     Cynara::ApiInterface *impl;
@@ -228,59 +229,40 @@ int cynara_admin_check(struct cynara_admin *p_cynara_admin,
     });
 }
 
-static int createPoliciesArray(const char *bucket,
-                               const std::vector<Cynara::Policy> &policiesVector,
-                               struct cynara_admin_policy ***policies) {
-    typedef struct cynara_admin_policy Elem;
-    size_t elems = policiesVector.size();
-
-    Elem **tab = reinterpret_cast<Elem**>(calloc(elems + 1U, sizeof(Elem*)));
-    if (!tab)
+static int copyPolicy(const char *bucket, const Cynara::Policy &from, cynara_admin_policy *&to) {
+    to = reinterpret_cast<cynara_admin_policy*>(calloc(1, sizeof(cynara_admin_policy)));
+    if (!to)
         return CYNARA_API_OUT_OF_MEMORY;
-    std::unique_ptr<Elem*, std::function<void(Elem**)>> plumber(tab,
-        [](Elem **tab) {
-            for (int i = 0; tab[i] != nullptr; i++) {
-                free(tab[i]->bucket);
-                free(tab[i]->client);
-                free(tab[i]->user);
-                free(tab[i]->privilege);
-                free(tab[i]->result_extra);
-                free(tab[i]);
-            }
-            free(tab);
-        });
-
-    for (size_t i = 0U; i < elems; ++i) {
-        tab[i] = reinterpret_cast<Elem*>(calloc(1U, sizeof(Elem)));
-        if (!tab[i])
-            return CYNARA_API_OUT_OF_MEMORY;
-
-        tab[i]->bucket = strdup(bucket);
-        if (!tab[i]->bucket)
+    to->bucket = strdup(bucket);
+    if (!to->bucket)
+        return CYNARA_API_OUT_OF_MEMORY;
+    to->client = strdup(from.key().client().value().c_str());
+    if (!to->client)
             return CYNARA_API_OUT_OF_MEMORY;
-
-        tab[i]->client = strdup(policiesVector[i].key().client().value().c_str());
-        if (!tab[i]->client)
+    to->user = strdup(from.key().user().value().c_str());
+    if (!to->user)
             return CYNARA_API_OUT_OF_MEMORY;
-        tab[i]->user = strdup(policiesVector[i].key().user().value().c_str());
-        if (!tab[i]->user)
+    to->privilege = strdup(from.key().privilege().value().c_str());
+    if (!to->privilege)
             return CYNARA_API_OUT_OF_MEMORY;
-        tab[i]->privilege = strdup(policiesVector[i].key().privilege().value().c_str());
-        if (!tab[i]->privilege)
+    to->result = static_cast<int>(from.result().policyType());
+    if (!from.result().metadata().empty()) {
+        to->result_extra = strdup(from.result().metadata().c_str());
+        if (!to->result_extra)
             return CYNARA_API_OUT_OF_MEMORY;
-
-        tab[i]->result = static_cast<int>(policiesVector[i].result().policyType());
-        if (!policiesVector[i].result().metadata().empty()) {
-            tab[i]->result_extra = strdup(policiesVector[i].result().metadata().c_str());
-            if (!tab[i]->result_extra)
-                return CYNARA_API_OUT_OF_MEMORY;
-        }
     }
-    *policies = tab;
-    plumber.release();
     return CYNARA_API_SUCCESS;
 }
 
+static void freeElem(struct cynara_admin_policy *policyPtr) {
+    free(policyPtr->bucket);
+    free(policyPtr->client);
+    free(policyPtr->user);
+    free(policyPtr->privilege);
+    free(policyPtr->result_extra);
+    free(policyPtr);
+}
+
 CYNARA_API
 int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *bucket,
                                const char *client, const char *user, const char *privilege,
@@ -313,7 +295,45 @@ int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *
         if (ret != CYNARA_API_SUCCESS)
             return ret;
 
-        return createPoliciesArray(bucket, policiesVector, policies);
+        auto copyFun = std::bind(copyPolicy, bucket, std::placeholders::_1, std::placeholders::_2);
+        return Cynara::createNullTerminatedArray<Cynara::Policy, cynara_admin_policy>
+                            (policiesVector, policies, copyFun);
+    });
+}
+
+static int copyDescr(const Cynara::PolicyDescription &from, cynara_admin_policy_descr *&to) {
+    to = reinterpret_cast<cynara_admin_policy_descr*>(calloc(1, sizeof(cynara_admin_policy_descr)));
+    if (!to)
+        return CYNARA_API_OUT_OF_MEMORY;
+    to->result = static_cast<int>(from.type);
+    to->name = strdup(from.name.c_str());
+    if (!to->name)
+        return CYNARA_API_OUT_OF_MEMORY;
+    return CYNARA_API_SUCCESS;
+}
+
+static void freeElem(struct cynara_admin_policy_descr *descrPtr) {
+    free(descrPtr->name);
+    free(descrPtr);
+}
+
+CYNARA_API
+int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin,
+                                            struct cynara_admin_policy_descr ***descriptions) {
+    if (!p_cynara_admin || !p_cynara_admin->impl)
+        return CYNARA_API_INVALID_PARAM;
+    if (!descriptions)
+        return CYNARA_API_INVALID_PARAM;
+
+    return Cynara::tryCatch([&p_cynara_admin, &descriptions] () {
+        std::vector<Cynara::PolicyDescription> descriptionsVector;
+        int ret = p_cynara_admin->impl->listDescriptions(descriptionsVector);
+
+        if (ret != CYNARA_API_SUCCESS)
+            return ret;
+        return Cynara::createNullTerminatedArray<Cynara::PolicyDescription,
+                                                 cynara_admin_policy_descr>
+                (descriptionsVector, descriptions, copyDescr);
     });
 }
 
index 57fc0b5..3f23370 100644 (file)
@@ -66,6 +66,11 @@ int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const P
                            recursive, std::cref(key), std::ref(result)));
 }
 
+int Logic::listDescriptions(std::vector<PolicyDescription> &descriptions) {
+    using std::placeholders::_1;
+    return callApiFunction(std::bind(&ApiInterface::listDescriptions, _1, std::ref(descriptions)));
+}
+
 int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
                         std::vector<Policy> &policies) {
     using std::placeholders::_1;
index 9a24de7..e9c7774 100644 (file)
@@ -48,6 +48,7 @@ public:
     virtual int removeBucket(const PolicyBucketId &bucket);
     virtual int adminCheck(const PolicyBucketId &startBucket, bool recursive,
                            const PolicyKey &key, PolicyResult &result);
+    virtual int listDescriptions(std::vector<PolicyDescription> &descriptions);
     virtual int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
                              std::vector<Policy> &policies);
     virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive,
index a52a0fe..c860ad8 100644 (file)
@@ -103,6 +103,11 @@ int OfflineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive,
     return CYNARA_API_SUCCESS;
 }
 
+int OfflineLogic::listDescriptions(std::vector<PolicyDescription> &descriptions) {
+    (void) descriptions;
+    return CYNARA_API_SUCCESS;
+}
+
 int OfflineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
                                std::vector<Policy> &policies) {
     try {
index ec180f2..fc04d5e 100644 (file)
@@ -47,6 +47,7 @@ public:
     int removeBucket(const PolicyBucketId &bucket);
     int adminCheck(const PolicyBucketId &startBucket, bool recursive,
                    const PolicyKey &key, PolicyResult &result);
+    int listDescriptions(std::vector<PolicyDescription> &descriptions);
     int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter,
                      std::vector<Policy> &policies);
     int erasePolicies(const PolicyBucketId &startBucket, bool recursive,
index 9aa1831..6626a77 100644 (file)
@@ -205,4 +205,9 @@ int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive
     return askCynaraAndInterpreteCodeResponse<EraseRequest>(startBucket, recursive, filter);
 }
 
+int OnlineLogic::listDescriptions(std::vector<PolicyDescription> &descriptions) {
+    (void) descriptions;
+    return CYNARA_API_SUCCESS;
+}
+
 } // namespace Cynara
index 19e3304..84becd7 100644 (file)
@@ -52,7 +52,7 @@ public:
                              std::vector<Policy> &policies);
     virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive,
                               const PolicyKey &filter);
-
+    virtual int listDescriptions(std::vector<PolicyDescription> &descriptions);
 };
 
 } // namespace Cynara
diff --git a/src/admin/logic/Utility.h b/src/admin/logic/Utility.h
new file mode 100644 (file)
index 0000000..10e62da
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/**
+ * @file        src/admin/logic/Utility.h
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
+ * @version     1.0
+ * @brief       This file contains implementation of utility function for managing null pointer
+ *              terminated lists.
+ */
+
+#ifndef SRC_ADMIN_LOGIC_UTILITY_H_
+#define SRC_ADMIN_LOGIC_UTILITY_H_
+
+#include <cstdlib>
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include <cynara-error.h>
+
+namespace Cynara {
+
+//This function requires proper freeElem function for given type T.
+template<typename T>
+static void freeNullTerminatedList(T **list) {
+    for (int i = 0; list[i]; i++) {
+        freeElem(list[i]);
+    }
+    free(list);
+}
+
+template<typename V, typename T>
+static int createNullTerminatedArray(const std::vector<V> &vectorized, T ***array,
+                                     std::function<int(const V&, T*&)> copyFun) {
+    size_t elems = vectorized.size();
+
+    T **tab = reinterpret_cast<T**>(calloc(elems + 1U, sizeof(T*)));
+    if (!tab)
+        return CYNARA_API_OUT_OF_MEMORY;
+
+    std::unique_ptr<T*, std::function<void(T**)>> plumber(tab, freeNullTerminatedList<T>);
+
+    for (size_t i = 0; i < elems; i++) {
+        int ret = copyFun(vectorized[i], tab[i]);
+        if (ret != CYNARA_API_SUCCESS)
+            return ret;
+    }
+
+    *array = tab;
+    plumber.release();
+    return CYNARA_API_SUCCESS;
+}
+
+} // namespace Cynara
+
+#endif /* SRC_ADMIN_LOGIC_UTILITY_H_ */
index b83c81d..bb4c1bf 100644 (file)
@@ -17,6 +17,7 @@
  * \file        src/include/cynara-admin-types.h
  * \author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  * \author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * \author      Zofia Abramowska <z.abramowska@samsung.com>
  * \version     1.0
  * \brief       This file contains structs and consts for cynara admin.
  */
@@ -49,6 +50,18 @@ struct cynara_admin_policy {
 };
 
 /**
+ * \name cynara_admin_policy_descr
+ * describes policy of type given with result
+ * result - result of policy to describe
+ * name - name of given policy result
+ */
+
+struct cynara_admin_policy_descr {
+    int result;
+    char *name;
+};
+
+/**
  * \name Wildcard
  * definition of WILDCARD, that can replace client, user or privilege name.
  * WILDCARD matches any string during check procedure from libcynara-client.
index bb1b8d1..0d958f8 100644 (file)
@@ -16,6 +16,7 @@
 /**
  * @file        src/include/cynara-admin.h
  * \author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * \author      Zofia Abramowska <z.abramowska@samsung.com>
  * \version     1.0
  * \brief       This file contains administration APIs of cynara available with libcynara-admin.
  */
@@ -358,6 +359,54 @@ int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *
 int cynara_admin_erase(struct cynara_admin *p_cynara_admin,
                        const char *start_bucket, int recursive,
                        const char *client, const char *user, const char *privilege);
+
+/**
+ * \par Description:
+ *
+ * Lists available cynara policy results with name description.
+ *
+ * \par Purpose:
+ * This API should be used to list all available policy results
+ * (also from cynara extension plugins).
+ *
+ * \par Typical use case:
+ * Gathering information about possible policy results and presenting them to user (using name
+ * attribute of description). Result can be passed to cynara_admin_set_policies().
+ *
+ * \par Method of function operation:
+ * Policies are based on policy result number. Policies can be built in (like primitives: ALLOW,
+ * DENY...) or can be loaded from cynara plugin extensions. This API gives possibility of checking,
+ * which of these result exist in current cynara server and can be presented to user in a readable
+ * way (of course additional translation may be needed).
+ *
+ * Descriptions of existing policy results are returned as NULL terminated array of pointers of
+ * cynara_admin_policy_descr structures.
+ *
+ * Example output could be {{0, "Deny"}, {11, "AskUser"}, {65535, "Allow"}, NULL}
+ *
+ * In case of successful call CYNARA_API_SUCCESS is returned and *descriptions points
+ * to newly created array of pointers to struct cynara_admin_policy_descr. It is responsibility
+ * of caller to release:
+ * * all non-NULL char* pointers in all cynara_admin_policy_descr structures;
+ * * all pointers to cynara_admin_policy_descr structures kept in *descriptions array;
+ * * *descriptions array itself.
+ * All allocation made by cynara admin library are done with malloc(3) function and must be released
+ * with free(3) function.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \param[in] p_cynara_admin cynara admin structure.
+ * \param[out] descriptions placeholder for NULL terminated array of pointers of
+ *             description structures.
+ *
+ * \return CYNARA_API_SUCCESS on success, or error code otherwise.
+ *
+ * \brief Lists available policies with their name description.
+ */
+int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin,
+                                            struct cynara_admin_policy_descr ***descriptions);
+
 #ifdef __cplusplus
 }
 #endif