You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2022/10/13 16:58:30 UTC
[pulsar-client-python] branch main updated: Support auth param string for Basic authentication (#15)
This is an automated email from the ASF dual-hosted git repository.
mmerli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pulsar-client-python.git
The following commit(s) were added to refs/heads/main by this push:
new 51d3846 Support auth param string for Basic authentication (#15)
51d3846 is described below
commit 51d3846cad82a140929df725f03eb2edbb2e4e02
Author: Yunze Xu <xy...@163.com>
AuthorDate: Fri Oct 14 00:58:25 2022 +0800
Support auth param string for Basic authentication (#15)
* Support auth param string for Basic authentication
### Motivation
https://github.com/apache/pulsar/pull/17482 supported basic
authentication for Python client, but the `AuthenticationBasic` class
accepts two positional arguments as the username and password. It's not
good for extension. We should accept an auth param string like
`AuthenticationOauth2` so that no changes are needed if the upstream C++
client's implementation changed, like
https://github.com/apache/pulsar-client-cpp/pull/37.
### Modifications
To be compatible with the existing API, change the first two arguments
to keyword arguments. Then, add the 3rd keyword argument to represent
the auth param string.
### Verifications
`test_basic_auth` and `test_invalid_basic_auth` are extended for this
change.
* Add method argument and related tests
* Add type check for method arg
---
pulsar/__init__.py | 37 +++++++++++++++++++++++++++++--------
src/authentication.cc | 12 +++++++++---
tests/pulsar_test.py | 37 ++++++++++++++++++++++++++++++++-----
3 files changed, 70 insertions(+), 16 deletions(-)
diff --git a/pulsar/__init__.py b/pulsar/__init__.py
index ef17844..1d29d90 100644
--- a/pulsar/__init__.py
+++ b/pulsar/__init__.py
@@ -347,18 +347,39 @@ class AuthenticationBasic(Authentication):
"""
Basic Authentication implementation
"""
- def __init__(self, username, password):
+ def __init__(self, username=None, password=None, method='basic', auth_params_string=None):
"""
Create the Basic authentication provider instance.
- **Args**
+ For example, if you want to create a basic authentication instance whose
+ username is "my-user" and password is "my-pass", there are two ways:
- * `username`: Used to authentication as username
- * `password`: Used to authentication as password
- """
- _check_type(str, username, 'username')
- _check_type(str, password, 'password')
- self.auth = _pulsar.AuthenticationBasic(username, password)
+ ```
+ auth = AuthenticationBasic('my-user', 'my-pass')
+ auth = AuthenticationBasic(auth_params_string='{"username": "my-user", "password": "my-pass"}')
+ ```
+
+ **Args**
+ * username : str, optional
+ * password : str, optional
+ * method : str, optional
+ The authentication method name (default is 'basic')
+ * auth_params_string : str, optional
+ The JSON presentation of all fields above (default is None)
+ If it's not None, the other parameters will be ignored.
+ Here is an example JSON presentation:
+ {"username": "my-user", "password": "my-pass", "method": "oms3.0"}
+ The `username` and `password` fields are required. If the "method" field is not set,
+ it will be "basic" by default.
+ """
+ if auth_params_string is not None:
+ _check_type(str, auth_params_string, 'auth_params_string')
+ self.auth = _pulsar.AuthenticationBasic('', '', '', auth_params_string)
+ else:
+ _check_type(str, username, 'username')
+ _check_type(str, password, 'password')
+ _check_type(str, method, 'method')
+ self.auth = _pulsar.AuthenticationBasic(username, password, method, '')
class Client:
"""
diff --git a/src/authentication.cc b/src/authentication.cc
index 7917498..1bec468 100644
--- a/src/authentication.cc
+++ b/src/authentication.cc
@@ -91,9 +91,14 @@ struct AuthenticationOauth2Wrapper : public AuthenticationWrapper {
};
struct AuthenticationBasicWrapper : public AuthenticationWrapper {
- AuthenticationBasicWrapper(const std::string& username, const std::string& password)
+ AuthenticationBasicWrapper(const std::string& username, const std::string& password,
+ const std::string& method, const std::string& authParamsString)
: AuthenticationWrapper() {
- this->auth = AuthBasic::create(username, password);
+ if (authParamsString.empty()) {
+ this->auth = AuthBasic::create(username, password, method);
+ } else {
+ this->auth = AuthBasic::create(authParamsString);
+ }
}
};
@@ -115,5 +120,6 @@ void export_authentication() {
init<const std::string&>());
class_<AuthenticationBasicWrapper, bases<AuthenticationWrapper> >(
- "AuthenticationBasic", init<const std::string&, const std::string&>());
+ "AuthenticationBasic",
+ init<const std::string&, const std::string&, const std::string&, const std::string&>());
}
diff --git a/tests/pulsar_test.py b/tests/pulsar_test.py
index 86abbfe..8cc2c55 100755
--- a/tests/pulsar_test.py
+++ b/tests/pulsar_test.py
@@ -1301,12 +1301,10 @@ class PulsarTest(TestCase):
with self.assertRaises(TypeError):
fun()
- def test_basic_auth(self):
- username = "admin"
- password = "123456"
- client = Client(self.adminUrl, authentication=AuthenticationBasic(username, password))
+ def _test_basic_auth(self, id, auth):
+ client = Client(self.adminUrl, authentication=auth)
- topic = "persistent://private/auth/my-python-topic-basic-auth"
+ topic = "persistent://private/auth/my-python-topic-basic-auth-" + str(id)
consumer = client.subscribe(topic, "my-sub", consumer_type=ConsumerType.Shared)
producer = client.create_producer(topic)
producer.send(b"hello")
@@ -1316,6 +1314,28 @@ class PulsarTest(TestCase):
self.assertEqual(msg.data(), b"hello")
client.close()
+ def test_basic_auth(self):
+ username = "admin"
+ password = "123456"
+ self._test_basic_auth(0, AuthenticationBasic(username, password))
+ self._test_basic_auth(1, AuthenticationBasic(
+ auth_params_string='{{"username": "{}","password": "{}"}}'.format(username, password)
+ ))
+
+ def test_basic_auth_method(self):
+ username = "admin"
+ password = "123456"
+ self._test_basic_auth(2, AuthenticationBasic(username, password, 'basic'))
+ with self.assertRaises(pulsar.AuthorizationError):
+ self._test_basic_auth(3, AuthenticationBasic(username, password, 'unknown'))
+ self._test_basic_auth(4, AuthenticationBasic(
+ auth_params_string='{{"username": "{}","password": "{}", "method": "basic"}}'.format(username, password)
+ ))
+ with self.assertRaises(pulsar.AuthorizationError):
+ self._test_basic_auth(5, AuthenticationBasic(
+ auth_params_string='{{"username": "{}","password": "{}", "method": "unknown"}}'.format(username, password)
+ ))
+
def test_invalid_basic_auth(self):
username = "invalid"
password = "123456"
@@ -1323,6 +1343,13 @@ class PulsarTest(TestCase):
topic = "persistent://private/auth/my-python-topic-invalid-basic-auth"
with self.assertRaises(pulsar.ConnectError):
client.subscribe(topic, "my-sub", consumer_type=ConsumerType.Shared)
+ client = Client(self.adminUrl, authentication=AuthenticationBasic(
+ auth_params_string='{{"username": "{}","password": "{}"}}'.format(username, password)
+ ))
+ with self.assertRaises(pulsar.ConnectError):
+ client.subscribe(topic, "my-sub", consumer_type=ConsumerType.Shared)
+ with self.assertRaises(RuntimeError):
+ AuthenticationBasic(auth_params_string='invalid auth params')
if __name__ == "__main__":
main()