Implement --erase option in Cyad 92/32992/6
authorAleksander Zdyb <a.zdyb@samsung.com>
Fri, 2 Jan 2015 07:04:22 +0000 (08:04 +0100)
committerAleksander Zdyb <a.zdyb@samsung.com>
Thu, 15 Jan 2015 10:16:51 +0000 (11:16 +0100)
This option runs cynara_admin_erase() API function
to erase policies from Cynara's database.

Change-Id: I3659971657ef23fcd1c27850f56f32e57938aa6d

13 files changed:
src/cyad/AdminApiWrapper.cpp
src/cyad/AdminApiWrapper.h
src/cyad/BaseAdminApiWrapper.h
src/cyad/CommandlineParser/CyadCommand.cpp
src/cyad/CommandlineParser/CyadCommand.h
src/cyad/CommandlineParser/CyadCommandlineParser.cpp
src/cyad/CommandlineParser/CyadCommandlineParser.h
src/cyad/CommandsDispatcher.cpp
src/cyad/CommandsDispatcher.h
test/cyad/FakeAdminApiWrapper.h
test/cyad/commandline.cpp
test/cyad/commandline_errors.cpp
test/cyad/commands_dispatcher.cpp

index 6a31b4b..5cfc6ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -56,4 +56,10 @@ int AdminApiWrapper::cynara_admin_check(struct cynara_admin *p_cynara_admin,
                                 result, result_extra);
 }
 
+int AdminApiWrapper::cynara_admin_erase(struct cynara_admin *p_cynara_admin,
+                                        const char *start_bucket, int recursive, const char *client,
+                                        const char *user, const char *privilege) {
+    return ::cynara_admin_erase(p_cynara_admin, start_bucket, recursive, client, user, privilege);
+}
+
 } /* namespace Cynara */
index d688271..369a0f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -45,6 +45,9 @@ public:
                                    const char *start_bucket, const int recursive,
                                    const char *client, const char *user, const char *privilege,
                                    int *result, char **result_extra);
+    virtual 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);
 };
 
 } /* namespace Cynara */
index a24aec2..e44b130 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -41,6 +41,9 @@ public:
                                    const char *start_bucket, const int recursive,
                                    const char *client, const char *user, const char *privilege,
                                    int *result, char **result_extra) = 0;
+    virtual 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) = 0;
 };
 
 } /* namespace Cynara */
index 0e482fa..e965a08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -54,4 +54,8 @@ int SetPolicyBulkCyadCommand::run(CommandsDispatcher &dispatcher) {
     return dispatcher.execute(*this);
 }
 
+int EraseCyadCommand::run(CommandsDispatcher &dispatcher) {
+    return dispatcher.execute(*this);
+}
+
 } /* namespace Cynara */
index fc2c808..8f63ee0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -153,6 +153,33 @@ private:
     std::string m_filename;
 };
 
+class EraseCyadCommand : public CyadCommand {
+public:
+    EraseCyadCommand(const PolicyBucketId &bucketId, bool recursive, const PolicyKey &policyKey)
+        : m_bucketId(bucketId), m_recursive(recursive), m_policyKey(policyKey) {}
+
+    virtual ~EraseCyadCommand() {}
+
+    virtual int run(CommandsDispatcher &dispatcher);
+
+    const PolicyBucketId &bucketId(void) const {
+        return m_bucketId;
+    }
+
+    bool recursive(void) const {
+        return m_recursive;
+    }
+
+    const PolicyKey &policyKey(void) const {
+        return m_policyKey;
+    }
+
+private:
+    PolicyBucketId m_bucketId;
+    bool m_recursive;
+    PolicyKey m_policyKey;
+};
+
 } /* namespace Cynara */
 
 #endif /* SRC_CYAD_COMMANDLINEPARSER_CYADCOMMAND_H_ */
index 835c1ed..73f3a69 100644 (file)
@@ -66,6 +66,12 @@ namespace CyadCmdlineArgs {
 
     const char BULK = 'f';
     const char * const BULK_LONG = "bulk";
+
+    const char ERASE = 'e';
+    const char * const ERASE_LONG = "erase";
+
+    const char RECURSIVE = 'r';
+    const char * const RECURSIVE_LONG = "recursive";
 }
 
 namespace CyadCmdlineErrors {
@@ -75,11 +81,14 @@ namespace CyadCmdlineErrors {
     const char * const UNKNOWN_OPTION_SET_BUCKET = "Unknown option in --set-bucket";
     const char * const UNKNOWN_OPTION_DELETE_BUCKET = "Unknown option in --delete-bucket";
     const char * const UNKNOWN_OPTION_SET_POLICY = "Unknown option in --set-policy";
+    const char * const UNKNOWN_OPTION_ERASE = "Unknown option in --erase (-e)";
     const char * const NO_POLICY = "No --policy specified";
     const char * const NO_BUCKET = "No bucket specified";
     const char * const INVALID_POLICY = "Invalid --policy option";
     const char * const OPTION_MISSING_SET_POLICY = "One or more option missing in --set-policy";
     const char * const ARGUMENT_MISSING_SET_POLICY = "One or more argument missing in --set-policy";
+    const char * const OPTION_MISSING_ERASE = "One or more option missing in --erase (-e)";
+    const char * const ARGUMENT_MISSING_ERASE = "One or more argument missing in --erase (-e)";
 }
 
 CyadCommandlineParser::CyadCommandlineParser(int argc, char * const *argv)
@@ -95,6 +104,7 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
         { Args::SET_BUCKET_LONG,    required_argument, nullptr, Args::SET_BUCKET },
         { Args::DELETE_BUCKET_LONG, required_argument, nullptr, Args::DELETE_BUCKET },
         { Args::SET_POLICY_LONG,    no_argument,       nullptr, Args::SET_POLICY },
+        { Args::ERASE_LONG,         required_argument, nullptr, Args::ERASE },
         { nullptr, 0, nullptr, 0 }
     };
 
@@ -104,7 +114,8 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
     optstr << ":" << Args::HELP
            << Args::SET_BUCKET << ":"
            << Args::DELETE_BUCKET << ":"
-           << Args::SET_POLICY;
+           << Args::SET_POLICY
+           << Args::ERASE << ":";
 
     while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
         switch (opt) {
@@ -120,6 +131,9 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
             case Args::SET_POLICY:
                 return parseSetPolicy();
 
+            case Args::ERASE:
+                return parseErase(optarg);
+
             case '?': // Unknown option
                 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
 
@@ -277,4 +291,60 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseSetPolicy(void) {
     return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_ERROR);
 }
 
+std::shared_ptr<CyadCommand> CyadCommandlineParser::parseErase(const std::string &bucketId) {
+    namespace Args = CyadCmdlineArgs;
+    namespace Errors = CyadCmdlineErrors;
+
+    const struct option long_options[] = {
+        { Args::RECURSIVE_LONG, required_argument, nullptr, Args::RECURSIVE },
+        { Args::CLIENT_LONG,    required_argument, nullptr, Args::CLIENT },
+        { Args::USER_LONG,      required_argument, nullptr, Args::USER },
+        { Args::PRIVILEGE_LONG, required_argument, nullptr, Args::PRIVILEGE },
+        { nullptr, 0, nullptr, 0 }
+    };
+
+    typedef std::map<char, std::string> OptionsValues;
+    OptionsValues values = { { Args::RECURSIVE, std::string() },
+                             { Args::CLIENT,    std::string() },
+                             { Args::USER,      std::string() },
+                             { Args::PRIVILEGE, std::string() } };
+
+    int opt;
+    std::stringstream optstr;
+    optstr << ":"
+           << Args::RECURSIVE << ":"
+           << Args::CLIENT << ":"
+           << Args::USER << ":"
+           << Args::PRIVILEGE << ":";
+
+    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
+        switch (opt) {
+        case Args::RECURSIVE:
+        case Args::CLIENT:
+        case Args::USER:
+        case Args::PRIVILEGE:
+            values[opt] = optarg;
+            break;
+        case ':': // Missing argument
+            return std::make_shared<ErrorCyadCommand>(Errors::ARGUMENT_MISSING_ERASE);
+        default:
+            return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_ERASE);
+        }
+    }
+
+    for (const auto &val : values) {
+        if (val.second.empty()) {
+            // TODO: Identify actual option
+            return std::make_shared<ErrorCyadCommand>(Errors::OPTION_MISSING_ERASE);
+        }
+    }
+
+    auto recursive = HumanReadableParser::isYes(values[Args::RECURSIVE]);
+
+
+    return std::make_shared<EraseCyadCommand>(bucketId, recursive,
+                                              PolicyKey(values[Args::CLIENT], values[Args::USER],
+                                                        values[Args::PRIVILEGE]));
+}
+
 } /* namespace Cynara */
index c4e5f8d..1915f77 100644 (file)
@@ -59,6 +59,12 @@ namespace CyadCmdlineArgs {
 
     extern const char BULK;
     extern const char * const BULK_LONG;
+
+    extern const char ERASE;
+    extern const char * const ERASE_LONG;
+
+    extern const char RECURSIVE;
+    extern const char * const RECURSIVE_LONG;
 }
 
 namespace CyadCmdlineErrors {
@@ -68,11 +74,14 @@ namespace CyadCmdlineErrors {
     extern const char * const UNKNOWN_OPTION_SET_BUCKET;
     extern const char * const UNKNOWN_OPTION_DELETE_BUCKET;
     extern const char * const UNKNOWN_OPTION_SET_POLICY;
+    extern const char * const UNKNOWN_OPTION_ERASE;
     extern const char * const NO_POLICY;
     extern const char * const NO_BUCKET;
     extern const char * const INVALID_POLICY;
     extern const char * const OPTION_MISSING_SET_POLICY;
     extern const char * const ARGUMENT_MISSING_SET_POLICY;
+    extern const char * const OPTION_MISSING_ERASE;
+    extern const char * const ARGUMENT_MISSING_ERASE;
 }
 
 class CyadCommandlineParser {
@@ -86,6 +95,7 @@ protected:
     std::shared_ptr<CyadCommand> parseSetBucket(const std::string &bucketId);
     std::shared_ptr<CyadCommand> parseDeleteBucket(const std::string &bucketId);
     std::shared_ptr<CyadCommand> parseSetPolicy(void);
+    std::shared_ptr<CyadCommand> parseErase(const std::string &bucketId);
 
 private:
     int m_argc;
index 203aab2..6b60480 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -98,4 +98,14 @@ int CommandsDispatcher::execute(SetPolicyBulkCyadCommand &result) {
     }
 }
 
+int CommandsDispatcher::execute(EraseCyadCommand &result) {
+    const auto &key = result.policyKey();
+    auto client = key.client().toString().c_str();
+    auto user = key.user().toString().c_str();
+    auto privilege = key.privilege().toString().c_str();
+
+    return m_adminApiWrapper.cynara_admin_erase(m_cynaraAdmin, result.bucketId().c_str(),
+                                                result.recursive(), client, user, privilege);
+}
+
 } /* namespace Cynara */
index 69a5ec6..a6f4b83 100644 (file)
@@ -44,6 +44,7 @@ public:
     virtual int execute(SetBucketCyadCommand &);
     virtual int execute(SetPolicyCyadCommand &);
     virtual int execute(SetPolicyBulkCyadCommand &);
+    virtual int execute(EraseCyadCommand &);
 
 private:
     // TODO: Get argv[0] instead of hardcoded name
@@ -64,6 +65,15 @@ private:
                                     "  -m, --metadata=<metadata>      metadata for policy\n"
                                     "  -f, --bulk=<filename>          path or - for stdin\n"
                                     "\n"
+                                    "Policy erase options (with -e or --erase)\n"
+                                    "  -e, --erase=<name>             name of bucket"
+                                                                     " to start from\n"
+                                    "  -r, --recursive=<yes|no>       if linked buckets should be"
+                                                                     " processed as well\n"
+                                    "  -c, --client=<client>          client value\n"
+                                    "  -u, --user=<user>              user value\n"
+                                    "  -p, --privilege=<privilege>    privilege value\n"
+                                    "\n"
                                     "Help options:\n"
                                     "  -h, --help                     print help message";
     BaseDispatcherIO &m_io;
index 8e9b86b..533b7a4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -32,16 +32,23 @@ class FakeAdminApiWrapper : public Cynara::BaseAdminApiWrapper {
 public:
     using BaseAdminApiWrapper::BaseAdminApiWrapper;
 
-    MOCK_METHOD1(cynara_admin_initialize, int(struct cynara_admin **pp_cynara_admin));
-    MOCK_METHOD1(cynara_admin_finish, int(struct cynara_admin *p_cynara_admin));
-    MOCK_METHOD2(cynara_admin_set_policies, int(struct cynara_admin *p_cynara_admin,
-                 const struct cynara_admin_policy *const *policies));
-    MOCK_METHOD4(cynara_admin_set_bucket, int(struct cynara_admin *p_cynara_admin,
-                 const char *bucket, int operation, const char *extra));
-    MOCK_METHOD8(cynara_admin_check, int(struct cynara_admin *p_cynara_admin,
-                 const char *start_bucket, const int recursive,
-                 const char *client, const char *user, const char *privilege,
-                 int *result, char **result_extra));
+    MOCK_METHOD1(cynara_admin_initialize,
+                 int(struct cynara_admin **pp_cynara_admin));
+    MOCK_METHOD1(cynara_admin_finish,
+                 int(struct cynara_admin *p_cynara_admin));
+    MOCK_METHOD2(cynara_admin_set_policies,
+                 int(struct cynara_admin *p_cynara_admin,
+                     const struct cynara_admin_policy *const *policies));
+    MOCK_METHOD4(cynara_admin_set_bucket,
+                 int(struct cynara_admin *p_cynara_admin, const char *bucket, int operation,
+                     const char *extra));
+    MOCK_METHOD8(cynara_admin_check,
+                 int(struct cynara_admin *p_cynara_admin, const char *start_bucket,
+                     const int recursive, const char *client, const char *user,
+                     const char *privilege, int *result, char **result_extra));
+    MOCK_METHOD6(cynara_admin_erase,
+                 int(struct cynara_admin *p_cynara_admin, const char *start_bucket, int recursive,
+                     const char *client, const char *user, const char *privilege));
 };
 
 #endif /* TEST_CYAD_FAKEADMINAPIWRAPPER_H_ */
index b11cc91..188a4cf 100644 (file)
@@ -182,3 +182,27 @@ TEST_F(CyadCommandlineTest, setPoliciesBulkStdin) {
     ASSERT_NE(nullptr, result);
     ASSERT_EQ("-", result->filename());
 }
+
+TEST_F(CyadCommandlineTest, eraseRecursive) {
+    prepare_argv({ "./cyad", "--erase=bucket", "--recursive=yes",
+                   "--client=client", "--user=user", "--privilege=privilege" });
+    Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+    auto result = std::dynamic_pointer_cast<Cynara::EraseCyadCommand>(parser.parseMain());
+    ASSERT_NE(nullptr, result);
+    ASSERT_EQ("bucket", result->bucketId());
+    ASSERT_TRUE(result->recursive());
+    ASSERT_EQ(Cynara::PolicyKey("client", "user", "privilege"), result->policyKey());
+}
+
+TEST_F(CyadCommandlineTest, eraseNonrecursive) {
+    prepare_argv({ "./cyad", "--erase=bucket", "--recursive=no",
+                   "--client=client", "--user=user", "--privilege=privilege" });
+    Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+    auto result = std::dynamic_pointer_cast<Cynara::EraseCyadCommand>(parser.parseMain());
+    ASSERT_NE(nullptr, result);
+    ASSERT_EQ("bucket", result->bucketId());
+    ASSERT_FALSE(result->recursive());
+    ASSERT_EQ(Cynara::PolicyKey("client", "user", "privilege"), result->policyKey());
+}
index d083665..c541187 100644 (file)
@@ -116,3 +116,10 @@ TEST_F(CyadCommandlineTest, setPolicyNoPolicy) {
     Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
     ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_SET_POLICY, parser.parseMain());
 }
+
+TEST_F(CyadCommandlineTest, eraseNoRecursive) {
+    prepare_argv({ "./cyad", "--erase=",
+                   "--client=client", "--user=user", "--privilege=privilege" });
+    Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_ERASE, parser.parseMain());
+}
index 34ff9dc..19eed43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -229,3 +229,24 @@ TEST_F(CyadCommandlineDispatcherTest, setPoliciesBulkInputError) {
 
     ASSERT_FALSE(m_io.cerrRaw().str().empty());
 }
+
+TEST_F(CyadCommandlineDispatcherTest, erase) {
+    using ::testing::_;
+    using ::testing::Return;
+    using ::testing::StrEq;
+
+    FakeAdminApiWrapper adminApi;
+
+    EXPECT_CALL(adminApi, cynara_admin_initialize(_)).WillOnce(Return(CYNARA_API_SUCCESS));
+    EXPECT_CALL(adminApi, cynara_admin_finish(_)).WillOnce(Return(CYNARA_API_SUCCESS));
+
+    Cynara::CommandsDispatcher dispatcher(m_io, adminApi);
+
+    Cynara::EraseCyadCommand command("", true, { "client", "user", "privilege" });
+
+    EXPECT_CALL(adminApi, cynara_admin_erase(_, StrEq(""), true, StrEq("client"), StrEq("user"),
+                                             StrEq("privilege")))
+        .WillOnce(Return(CYNARA_API_SUCCESS));
+
+    dispatcher.execute(command);
+}