diff --git a/include/pulsar/Authentication.h b/include/pulsar/Authentication.h index 7ab1e65a..7f8f7d25 100644 --- a/include/pulsar/Authentication.h +++ b/include/pulsar/Authentication.h @@ -321,6 +321,12 @@ class PULSAR_PUBLIC AuthBasic : public Authentication { */ static AuthenticationPtr create(const std::string& username, const std::string& password); + /** + * Create an AuthBasic with the required parameters + */ + static AuthenticationPtr create(const std::string& username, const std::string& password, + const std::string& method); + /** * @return “basic” */ diff --git a/lib/Authentication.cc b/lib/Authentication.cc index 8fc007db..4695a03c 100644 --- a/lib/Authentication.cc +++ b/lib/Authentication.cc @@ -130,7 +130,7 @@ AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, ParamMap& } else if (boost::iequals(pluginName, OAUTH2_TOKEN_PLUGIN_NAME) || boost::iequals(pluginName, OAUTH2_TOKEN_JAVA_PLUGIN_NAME)) { return AuthOauth2::create(paramMap); - } else if (boost::iequals(pluginName, BASIC_PLUGIN_NAME) || + } else if (boost::iequals(pluginName, DEFAULT_BASIC_METHOD_NAME) || boost::iequals(pluginName, BASIC_JAVA_PLUGIN_NAME)) { return AuthBasic::create(paramMap); } else { @@ -150,7 +150,7 @@ AuthenticationPtr tryCreateBuiltinAuth(const std::string& pluginName, const std: } else if (boost::iequals(pluginName, OAUTH2_TOKEN_PLUGIN_NAME) || boost::iequals(pluginName, OAUTH2_TOKEN_JAVA_PLUGIN_NAME)) { return AuthOauth2::create(authParamsString); - } else if (boost::iequals(pluginName, BASIC_PLUGIN_NAME) || + } else if (boost::iequals(pluginName, DEFAULT_BASIC_METHOD_NAME) || boost::iequals(pluginName, BASIC_JAVA_PLUGIN_NAME)) { return AuthBasic::create(authParamsString); } else { diff --git a/lib/auth/AuthBasic.cc b/lib/auth/AuthBasic.cc index 463e1474..ca74803a 100644 --- a/lib/auth/AuthBasic.cc +++ b/lib/auth/AuthBasic.cc @@ -38,9 +38,14 @@ std::string base64_encode(const std::string& s) { return data.append((3 - s.size() % 3) % 3, '='); } -AuthDataBasic::AuthDataBasic(const std::string& username, const std::string& password) { +AuthDataBasic::AuthDataBasic(const std::string& username, const std::string& password) + : AuthDataBasic(username, password, DEFAULT_BASIC_METHOD_NAME) {} + +AuthDataBasic::AuthDataBasic(const std::string& username, const std::string& password, + const std::string& methodName) { commandAuthToken_ = username + ":" + password; httpAuthToken_ = base64_encode(commandAuthToken_); + methodName_ = methodName; } AuthDataBasic::~AuthDataBasic() {} @@ -53,6 +58,8 @@ bool AuthDataBasic::hasDataFromCommand() { return true; } std::string AuthDataBasic::getCommandData() { return commandAuthToken_; } +const std::string& AuthDataBasic::getMethodName() const { return methodName_; } + // AuthBasic AuthBasic::AuthBasic(AuthenticationDataPtr& authDataBasic) { authDataBasic_ = authDataBasic; } @@ -64,6 +71,13 @@ AuthenticationPtr AuthBasic::create(const std::string& username, const std::stri return AuthenticationPtr(new AuthBasic(authDataBasic)); } +AuthenticationPtr AuthBasic::create(const std::string& username, const std::string& password, + const std::string& method) { + AuthenticationDataPtr authDataBasic = + AuthenticationDataPtr(new AuthDataBasic(username, password, method)); + return AuthenticationPtr(new AuthBasic(authDataBasic)); +} + ParamMap parseBasicAuthParamsString(const std::string& authParamsString) { ParamMap params; if (!authParamsString.empty()) { @@ -96,11 +110,17 @@ AuthenticationPtr AuthBasic::create(ParamMap& params) { if (passwordIt == params.end()) { throw std::runtime_error("No password provided for basic provider"); } - - return create(usernameIt->second, passwordIt->second); + auto methodIt = params.find("method"); + if (methodIt == params.end()) { + return create(usernameIt->second, passwordIt->second); + } else { + return create(usernameIt->second, passwordIt->second, methodIt->second); + } } -const std::string AuthBasic::getAuthMethodName() const { return "basic"; } +const std::string AuthBasic::getAuthMethodName() const { + return static_cast(authDataBasic_.get())->getMethodName(); +} Result AuthBasic::getAuthData(AuthenticationDataPtr& authDataBasic) { authDataBasic = authDataBasic_; diff --git a/lib/auth/AuthBasic.h b/lib/auth/AuthBasic.h index 89b995af..2bd9e11e 100644 --- a/lib/auth/AuthBasic.h +++ b/lib/auth/AuthBasic.h @@ -25,12 +25,13 @@ namespace pulsar { -const std::string BASIC_PLUGIN_NAME = "basic"; +const std::string DEFAULT_BASIC_METHOD_NAME = "basic"; const std::string BASIC_JAVA_PLUGIN_NAME = "org.apache.pulsar.client.impl.auth.AuthenticationBasic"; class AuthDataBasic : public AuthenticationDataProvider { public: AuthDataBasic(const std::string& username, const std::string& password); + AuthDataBasic(const std::string& username, const std::string& password, const std::string& methodName); ~AuthDataBasic(); bool hasDataForHttp(); @@ -38,9 +39,12 @@ class AuthDataBasic : public AuthenticationDataProvider { bool hasDataFromCommand(); std::string getCommandData(); + const std::string& getMethodName() const; + private: std::string commandAuthToken_; std::string httpAuthToken_; + std::string methodName_; }; } // namespace pulsar diff --git a/tests/AuthBasicTest.cc b/tests/AuthBasicTest.cc index 29a3ff51..29d66248 100644 --- a/tests/AuthBasicTest.cc +++ b/tests/AuthBasicTest.cc @@ -131,6 +131,16 @@ TEST(AuthPluginBasic, testLoadAuth) { ASSERT_EQ(data->hasDataForTls(), false); ASSERT_EQ(data->hasDataForHttp(), true); + auth = pulsar::AuthBasic::create( + "{\"username\":\"super-user\",\"password\":\"123789\",\"method\":\"my-method\"}"); + ASSERT_TRUE(auth != NULL); + ASSERT_EQ(auth->getAuthMethodName(), "my-method"); + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data->hasDataFromCommand(), true); + ASSERT_EQ(data->getCommandData(), "super-user:123789"); + ASSERT_EQ(data->hasDataForTls(), false); + ASSERT_EQ(data->hasDataForHttp(), true); + ParamMap p = ParamMap(); p["username"] = "super-user-2"; p["password"] = "456789"; @@ -142,6 +152,19 @@ TEST(AuthPluginBasic, testLoadAuth) { ASSERT_EQ(data->getCommandData(), "super-user-2:456789"); ASSERT_EQ(data->hasDataForTls(), false); ASSERT_EQ(data->hasDataForHttp(), true); + + p = ParamMap(); + p["username"] = "super-user-2"; + p["password"] = "456789"; + p["method"] = "my-method-2"; + auth = pulsar::AuthBasic::create(p); + ASSERT_TRUE(auth != NULL); + ASSERT_EQ(auth->getAuthMethodName(), "my-method-2"); + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data->hasDataFromCommand(), true); + ASSERT_EQ(data->getCommandData(), "super-user-2:456789"); + ASSERT_EQ(data->hasDataForTls(), false); + ASSERT_EQ(data->hasDataForHttp(), true); } TEST(AuthPluginBasic, testAuthBasicWithServiceUrlTlsWithTlsTransport) { @@ -253,3 +276,19 @@ TEST(AuthPluginBasic, testAuthBasicWithServiceUrlHttpsNoTlsTransport) { Result result = client.createProducer(topicName, producer); ASSERT_EQ(ResultLookupError, result); } + +TEST(AuthPluginBasic, testAuthBasicWithCustomMethodName) { + ClientConfiguration config = ClientConfiguration(); + + AuthenticationPtr auth = pulsar::AuthBasic::create("admin", "123456", "method-1"); + + ASSERT_TRUE(auth != NULL); + ASSERT_EQ(auth->getAuthMethodName(), "method-1"); + + pulsar::AuthenticationDataPtr data; + ASSERT_EQ(auth->getAuthData(data), pulsar::ResultOk); + ASSERT_EQ(data->hasDataFromCommand(), true); + ASSERT_EQ(data->getCommandData(), "admin:123456"); + ASSERT_EQ(data->hasDataForTls(), false); + ASSERT_EQ(data->hasDataForHttp(), true); +}