Implement --set-policy option in Cyad
[platform/core/security/cynara.git] / src / cyad / CommandlineParser / CyadCommandlineParser.cpp
index 713b506..c72967a 100644 (file)
@@ -47,6 +47,24 @@ namespace CyadCmdlineArgs {
 
     const char METADATA = 'm';
     const char * const METADATA_LONG = "metadata";
+
+    const char BUCKET = 'k';
+    const char * const BUCKET_LONG = "bucket";
+
+    const char SET_POLICY = 's';
+    const char * const SET_POLICY_LONG = "set-policy";
+
+    const char CLIENT = 'c';
+    const char * const CLIENT_LONG = "client";
+
+    const char USER = 'u';
+    const char * const USER_LONG = "user";
+
+    const char PRIVILEGE = 'r';
+    const char * const PRIVILEGE_LONG = "privilege";
+
+    const char BULK = 'f';
+    const char * const BULK_LONG = "bulk";
 }
 
 namespace CyadCmdlineErrors {
@@ -55,9 +73,12 @@ namespace CyadCmdlineErrors {
     const char * const UNKNOWN_OPTION = "Unknown option";
     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 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";
 }
 
 CyadCommandlineParser::CyadCommandlineParser(int argc, char * const *argv)
@@ -72,6 +93,7 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
         { Args::HELP_LONG,          no_argument,       nullptr, Args::HELP },
         { 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 },
         { nullptr, 0, nullptr, 0 }
     };
 
@@ -80,7 +102,8 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
     std::stringstream optstr;
     optstr << ":" << Args::HELP
            << Args::SET_BUCKET << ":"
-           << Args::DELETE_BUCKET << ":";
+           << Args::DELETE_BUCKET << ":"
+           << Args::SET_POLICY;
 
     while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
         switch (opt) {
@@ -93,6 +116,9 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
             case Args::DELETE_BUCKET:
                 return parseDeleteBucket(optarg);
 
+            case Args::SET_POLICY:
+                return parseSetPolicy();
+
             case '?': // Unknown option
                 return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
 
@@ -171,6 +197,85 @@ std::shared_ptr<CyadCommand> CyadCommandlineParser::parseDeleteBucket(const std:
     }
 }
 
+std::shared_ptr<CyadCommand> CyadCommandlineParser::parseSetPolicy(void) {
+    namespace Args = CyadCmdlineArgs;
+    namespace Errors = CyadCmdlineErrors;
+
+    const struct option long_options[] = {
+        { Args::CLIENT_LONG,    required_argument, nullptr, Args::CLIENT },
+        { Args::USER_LONG,      required_argument, nullptr, Args::USER },
+        { Args::PRIVILEGE_LONG, required_argument, nullptr, Args::PRIVILEGE },
+        { Args::BUCKET_LONG,    required_argument, nullptr, Args::BUCKET },
+        { Args::POLICY_LONG,    required_argument, nullptr, Args::POLICY },
+        { Args::METADATA_LONG,  required_argument, nullptr, Args::METADATA },
+        { Args::BULK_LONG,      required_argument, nullptr, Args::BULK },
+        { nullptr, 0, nullptr, 0 }
+    };
+
+    typedef std::map<char, std::string> OptionsValues;
+    OptionsValues values = { { Args::CLIENT,    std::string() },
+                             { Args::USER,      std::string() },
+                             { Args::PRIVILEGE, std::string() },
+                             { Args::POLICY,    std::string() } };
+
+    std::string metadata;
+    std::string bucket;
+
+    int opt;
+    std::stringstream optstr;
+    optstr << ":"
+           << Args::CLIENT << ":"
+           << Args::USER << ":"
+           << Args::PRIVILEGE << ":"
+           << Args::BUCKET << ":"
+           << Args::POLICY << ":"
+           << Args::METADATA << ":"
+           << Args::BULK << ":";
+
+    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
+        switch(opt) {
+        case Args::CLIENT:
+        case Args::USER:
+        case Args::PRIVILEGE:
+        case Args::POLICY:
+            values[opt] = optarg;
+            break;
+        case Args::BUCKET:
+            bucket = optarg;
+            break;
+        case Args::METADATA:
+            metadata = optarg;
+            break;
+        case Args::BULK:
+            return std::make_shared<SetPolicyBulkCyadCommand>(optarg);
+        case ':': // Missing argument
+            return std::make_shared<ErrorCyadCommand>(Errors::ARGUMENT_MISSING_SET_POLICY);
+        default:
+            return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_OPTION_SET_POLICY);
+        }
+    }
+
+    for (const auto &val : values) {
+        if (val.second.empty()) {
+            // TODO: Identify actual option
+            return std::make_shared<ErrorCyadCommand>(Errors::OPTION_MISSING_SET_POLICY);
+        }
+    }
+
+    try {
+        auto policyType = parsePolicyType(values[Args::POLICY]);
+        auto policyResult = PolicyResult(policyType, metadata);
+        return std::make_shared<SetPolicyCyadCommand>(bucket, policyResult,
+                                                      PolicyKey(values[Args::CLIENT],
+                                                                values[Args::USER],
+                                                                values[Args::PRIVILEGE]));
+    } catch (const PolicyParsingException &) {
+        return std::make_shared<ErrorCyadCommand>(Errors::INVALID_POLICY);
+    }
+
+    return std::make_shared<ErrorCyadCommand>(Errors::UNKNOWN_ERROR);
+}
+
 PolicyType CyadCommandlineParser::parsePolicyType(const std::string &rawPolicy) {
     if (rawPolicy == "DENY")
         return CYNARA_ADMIN_DENY;