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 {
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)
{ 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 }
};
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) {
case Args::DELETE_BUCKET:
return parseDeleteBucket(optarg);
+ case Args::SET_POLICY:
+ return parseSetPolicy();
+
case '?': // Unknown option
return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
}
}
+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;