Policies can be added or altered one by one or in bulk mode.
Option --bulk accepts file name as an argument.
The "-" value means standard input.
Change-Id: I479a29fd5ff43463f6f78d7865468bd84e1642ee
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;
extern const char METADATA;
extern const char * const METADATA_LONG;
+
+ extern const char BUCKET;
+ extern const char * const BUCKET_LONG;
+
+ extern const char CLIENT;
+ extern const char * const CLIENT_LONG;
+
+ extern const char USER;
+ extern const char * const USER_LONG;
+
+ extern const char PRIVILEGE;
+ extern const char * const PRIVILEGE_LONG;
+
+ extern const char BULK;
+ extern const char * const BULK_LONG;
}
namespace CyadCmdlineErrors {
extern const char * const UNKNOWN_OPTION;
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 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;
}
class CyadCommandlineParser {
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);
private:
int m_argc;
" -d, --delete-bucket=<name> name of bucket to delete\n"
"\n"
"Policy set options (with -s or --set-policy)\n"
- " -l, --client=<client> client value\n"
+ " -c, --client=<client> client value\n"
" -u, --user=<user> user value\n"
" -r, --privilege=<privilege> privilege value\n"
" -p, --policy=<policy> policy\n"
ASSERT_EQ(ultimateAnswer, result->policyResult().metadata());
}
+TEST_F(CyadCommandlineTest, setPolicy) {
+ prepare_argv({ "./cyad", "--set-policy", "--bucket=some-bucket",
+ "--client=client", "--user=user", "--privilege=privilege",
+ "--policy=42" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+ auto result = std::dynamic_pointer_cast<Cynara::SetPolicyCyadCommand>(parser.parseMain());
+ ASSERT_NE(nullptr, result);
+ ASSERT_EQ("some-bucket", result->bucketId());
+
+ ASSERT_EQ(Cynara::PolicyKey("client", "user", "privilege"), result->policyKey());
+ ASSERT_EQ(42, result->policyResult().policyType());
+ ASSERT_TRUE(result->policyResult().metadata().empty());
+}
+
+TEST_F(CyadCommandlineTest, setPolicyWithMetadata) {
+ prepare_argv({ "./cyad", "--set-policy", "--bucket=some-bucket",
+ "--client=client", "--user=user", "--privilege=privilege",
+ "--policy=42", "--metadata=some-metadata" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+ auto result = std::dynamic_pointer_cast<Cynara::SetPolicyCyadCommand>(parser.parseMain());
+ ASSERT_NE(nullptr, result);
+ ASSERT_EQ("some-bucket", result->bucketId());
+
+ ASSERT_EQ(Cynara::PolicyKey("client", "user", "privilege"), result->policyKey());
+ ASSERT_EQ(42, result->policyResult().policyType());
+ ASSERT_EQ("some-metadata", result->policyResult().metadata());
+}
+
+TEST_F(CyadCommandlineTest, setPolicyInDefaultBucket) {
+ prepare_argv({ "./cyad", "--set-policy", "--bucket=",
+ "--client=client", "--user=user", "--privilege=privilege",
+ "--policy=ALLOW", "--metadata=some-metadata" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+ auto result = std::dynamic_pointer_cast<Cynara::SetPolicyCyadCommand>(parser.parseMain());
+ ASSERT_NE(nullptr, result);
+ ASSERT_EQ("", result->bucketId());
+ ASSERT_EQ(Cynara::PolicyKey("client", "user", "privilege"), result->policyKey());
+ ASSERT_EQ(CYNARA_ADMIN_ALLOW, result->policyResult().policyType());
+ ASSERT_EQ("some-metadata", result->policyResult().metadata());
+}
+
+TEST_F(CyadCommandlineTest, setPolicyInDefaultBucketNoOption) {
+ prepare_argv({ "./cyad", "--set-policy",
+ "--client=client", "--user=user", "--privilege=privilege",
+ "--policy=ALLOW", "--metadata=some-metadata" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+ auto result = std::dynamic_pointer_cast<Cynara::SetPolicyCyadCommand>(parser.parseMain());
+ ASSERT_NE(nullptr, result);
+ ASSERT_EQ("", result->bucketId());
+ ASSERT_EQ(Cynara::PolicyKey("client", "user", "privilege"), result->policyKey());
+ ASSERT_EQ(CYNARA_ADMIN_ALLOW, result->policyResult().policyType());
+ ASSERT_EQ("some-metadata", result->policyResult().metadata());
+}
+
TEST_F(CyadCommandlineTest, parsePolicyTypeBase10) {
auto parsePolicyType = [] (const char *rawPolicy) -> Cynara::PolicyType {
return Cynara::CyadCommandlineParser::parsePolicyType(rawPolicy);
ASSERT_EQ(CYNARA_ADMIN_BUCKET, parsePolicyType("BUCKET"));
ASSERT_EQ(CYNARA_ADMIN_ALLOW, parsePolicyType("ALLOW"));
}
+
+TEST_F(CyadCommandlineTest, setPoliciesBulkFilename) {
+ prepare_argv({ "./cyad", "--set-policy", "--bulk=/tmp/input_file" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+ auto result = std::dynamic_pointer_cast<Cynara::SetPolicyBulkCyadCommand>(parser.parseMain());
+ ASSERT_NE(nullptr, result);
+ ASSERT_EQ("/tmp/input_file", result->filename());
+}
+
+TEST_F(CyadCommandlineTest, setPoliciesBulkStdin) {
+ prepare_argv({ "./cyad", "--set-policy", "--bulk=-" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+ auto result = std::dynamic_pointer_cast<Cynara::SetPolicyBulkCyadCommand>(parser.parseMain());
+ ASSERT_NE(nullptr, result);
+ ASSERT_EQ("-", result->filename());
+}
Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_POLICY, parser.parseMain());
}
+
+TEST_F(CyadCommandlineTest, setPolicyNoOption) {
+ prepare_argv({ "./cyad", "--set-policy" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+ ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_SET_POLICY, parser.parseMain());
+}
+
+TEST_F(CyadCommandlineTest, setPolicyUnknownOption) {
+ prepare_argv({ "./cyad", "--set-policy", "--unknown-option" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+ ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::UNKNOWN_OPTION_SET_POLICY, parser.parseMain());
+}
+
+TEST_F(CyadCommandlineTest, setPolicyArgumentMissing) {
+ prepare_argv({ "./cyad", "--set-policy", "--bucket" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+ ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::ARGUMENT_MISSING_SET_POLICY, parser.parseMain());
+}
+
+TEST_F(CyadCommandlineTest, setPolicyNoPolicy) {
+ // TODO: In the future, we can identify actual options being missed
+ prepare_argv({ "./cyad", "--set-policy", "--bucket=some-bucket",
+ "--client=client", "--user=user", "--privilege=privilege" });
+ Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+ ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::OPTION_MISSING_SET_POLICY, parser.parseMain());
+}