This is an automated email from the ASF dual-hosted git repository. mmerli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-pulsar.git
The following commit(s) were added to refs/heads/master by this push: new 6451efd Enable C++ AuthFactory to parse Athenz params string (#2540) 6451efd is described below commit 6451efd6515026288ae8aa1b7118e97904eecf76 Author: massakam <massa...@yahoo-corp.jp> AuthorDate: Sun Sep 9 04:50:35 2018 +0900 Enable C++ AuthFactory to parse Athenz params string (#2540) --- pulsar-client-cpp/include/pulsar/Authentication.h | 2 + pulsar-client-cpp/lib/Authentication.cc | 43 +++++++++++------ pulsar-client-cpp/lib/auth/AuthTls.cc | 5 ++ pulsar-client-cpp/tests/AuthPluginTest.cc | 58 +++++++++++++++++++++++ 4 files changed, 94 insertions(+), 14 deletions(-) diff --git a/pulsar-client-cpp/include/pulsar/Authentication.h b/pulsar-client-cpp/include/pulsar/Authentication.h index bde4134..2ea1238 100644 --- a/pulsar-client-cpp/include/pulsar/Authentication.h +++ b/pulsar-client-cpp/include/pulsar/Authentication.h @@ -61,6 +61,7 @@ class Authentication { authDataContent = authData_; return ResultOk; } + static ParamMap parseDefaultFormatAuthParams(const std::string& authParamsString); protected: Authentication(); @@ -104,6 +105,7 @@ class AuthTls : public Authentication { AuthTls(AuthenticationDataPtr&); ~AuthTls(); static AuthenticationPtr create(ParamMap& params); + static AuthenticationPtr create(const std::string& authParamsString); static AuthenticationPtr create(const std::string& certificatePath, const std::string& privateKeyPath); const std::string getAuthMethodName() const; Result getAuthData(AuthenticationDataPtr& authDataTls) const; diff --git a/pulsar-client-cpp/lib/Authentication.cc b/pulsar-client-cpp/lib/Authentication.cc index c1025e1..b3ebf1c 100644 --- a/pulsar-client-cpp/lib/Authentication.cc +++ b/pulsar-client-cpp/lib/Authentication.cc @@ -60,6 +60,22 @@ Authentication::Authentication() {} Authentication::~Authentication() {} +ParamMap Authentication::parseDefaultFormatAuthParams(const std::string& authParamsString) { + ParamMap paramMap; + if (!authParamsString.empty()) { + std::vector<std::string> params; + boost::algorithm::split(params, authParamsString, boost::is_any_of(",")); + for (int i = 0; i < params.size(); i++) { + std::vector<std::string> kv; + boost::algorithm::split(kv, params[i], boost::is_any_of(":")); + if (kv.size() == 2) { + paramMap[kv[0]] = kv[1]; + } + } + } + return paramMap; +} + class AuthDisabledData : public AuthenticationDataProvider { public: AuthDisabledData(ParamMap& params) {} @@ -111,6 +127,17 @@ AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, ParamMap& } } +AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, const std::string& authParamsString) { + if (boost::iequals(pluginName, TLS_PLUGIN_NAME) || boost::iequals(pluginName, TLS_JAVA_PLUGIN_NAME)) { + return AuthTls::create(authParamsString); + } else if (boost::iequals(pluginName, ATHENZ_PLUGIN_NAME) || + boost::iequals(pluginName, ATHENZ_JAVA_PLUGIN_NAME)) { + return AuthAthenz::create(authParamsString); + } else { + return AuthenticationPtr(); + } +} + AuthenticationPtr AuthFactory::create(const std::string& pluginNameOrDynamicLibPath, const std::string& authParamsString) { { @@ -121,20 +148,7 @@ AuthenticationPtr AuthFactory::create(const std::string& pluginNameOrDynamicLibP } } - ParamMap paramMap; - if (!authParamsString.empty()) { - std::vector<std::string> params; - boost::algorithm::split(params, authParamsString, boost::is_any_of(",")); - for (int i = 0; i < params.size(); i++) { - std::vector<std::string> kv; - boost::algorithm::split(kv, params[i], boost::is_any_of(":")); - if (kv.size() == 2) { - paramMap[kv[0]] = kv[1]; - } - } - } - - AuthenticationPtr authPtr = tryCreateBuiltinAuth(pluginNameOrDynamicLibPath, paramMap); + AuthenticationPtr authPtr = tryCreateBuiltinAuth(pluginNameOrDynamicLibPath, authParamsString); if (authPtr) { return authPtr; } @@ -151,6 +165,7 @@ AuthenticationPtr AuthFactory::create(const std::string& pluginNameOrDynamicLibP if (createAuthentication != NULL) { auth = createAuthentication(authParamsString); } else { + ParamMap paramMap = Authentication::parseDefaultFormatAuthParams(authParamsString); return AuthFactory::create(pluginNameOrDynamicLibPath, paramMap); } } diff --git a/pulsar-client-cpp/lib/auth/AuthTls.cc b/pulsar-client-cpp/lib/auth/AuthTls.cc index f076aaf..fcf6571 100644 --- a/pulsar-client-cpp/lib/auth/AuthTls.cc +++ b/pulsar-client-cpp/lib/auth/AuthTls.cc @@ -36,6 +36,11 @@ AuthTls::AuthTls(AuthenticationDataPtr& authDataTls) { authDataTls_ = authDataTl AuthTls::~AuthTls() {} +AuthenticationPtr AuthTls::create(const std::string& authParamsString) { + ParamMap params = parseDefaultFormatAuthParams(authParamsString); + return create(params); +} + AuthenticationPtr AuthTls::create(ParamMap& params) { return create(params["tlsCertFile"], params["tlsKeyFile"]); } diff --git a/pulsar-client-cpp/tests/AuthPluginTest.cc b/pulsar-client-cpp/tests/AuthPluginTest.cc index 7576d7f..295e624 100644 --- a/pulsar-client-cpp/tests/AuthPluginTest.cc +++ b/pulsar-client-cpp/tests/AuthPluginTest.cc @@ -234,3 +234,61 @@ TEST(AuthPluginTest, testDisable) { ASSERT_EQ(data->getCommandData(), "none"); ASSERT_EQ(auth.use_count(), 1); } + +TEST(AuthPluginTest, testAuthFactoryTls) { + pulsar::AuthenticationDataPtr data; + std::string tlsCertFile = "../../pulsar-broker/src/test/resources/authentication/tls/client-cert.pem"; + std::string tlsKeyFile = "../../pulsar-broker/src/test/resources/authentication/tls/client-key.pem"; + AuthenticationPtr auth = + pulsar::AuthFactory::create("tls", "tlsCertFile:" + tlsCertFile + ",tlsKeyFile:" + tlsKeyFile); + ASSERT_EQ(auth->getAuthMethodName(), "tls"); + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data->hasDataForTls(), true); + ASSERT_EQ(data->getTlsCertificates(), tlsCertFile); + ASSERT_EQ(data->getTlsPrivateKey(), tlsKeyFile); + + ClientConfiguration config = ClientConfiguration(); + config.setAuth(auth); + config.setTlsTrustCertsFilePath("../../pulsar-broker/src/test/resources/authentication/tls/cacert.pem"); + config.setTlsAllowInsecureConnection(false); + Client client("pulsar+ssl://localhost:9886", config); + + std::string topicName = "persistent://property/cluster/namespace/test-tls-factory"; + Producer producer; + Promise<Result, Producer> producerPromise; + client.createProducerAsync(topicName, WaitForCallbackValue<Producer>(producerPromise)); + Future<Result, Producer> producerFuture = producerPromise.getFuture(); + Result result = producerFuture.get(producer); + ASSERT_EQ(ResultOk, result); +} + +TEST(AuthPluginTest, testAuthFactoryAthenz) { + boost::thread zts(&testAthenz::mockZTS); + pulsar::AuthenticationDataPtr data; + std::string params = R"({ + "tenantDomain": "pulsar.test.tenant", + "tenantService": "service", + "providerDomain": "pulsar.test.provider", + "privateKey": "file:../../pulsar-broker/src/test/resources/authentication/tls/client-key.pem", + "ztsUrl": "http://localhost:9999" + })"; + pulsar::AuthenticationPtr auth = pulsar::AuthFactory::create("athenz", params); + ASSERT_EQ(auth->getAuthMethodName(), "athenz"); + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data->hasDataForHttp(), true); + ASSERT_EQ(data->hasDataFromCommand(), true); + ASSERT_EQ(data->getHttpHeaders(), "Athenz-Role-Auth: mockToken"); + ASSERT_EQ(data->getCommandData(), "mockToken"); + zts.join(); + std::vector<std::string> kvs; + boost::algorithm::split(kvs, testAthenz::principalToken, boost::is_any_of(";")); + for (std::vector<std::string>::iterator itr = kvs.begin(); itr != kvs.end(); itr++) { + std::vector<std::string> kv; + boost::algorithm::split(kv, *itr, boost::is_any_of("=")); + if (kv[0] == "d") { + ASSERT_EQ(kv[1], "pulsar.test.tenant"); + } else if (kv[0] == "n") { + ASSERT_EQ(kv[1], "service"); + } + } +}