Skip to content

Commit

Permalink
fix: Edge authentication support (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
alespour authored Aug 5, 2024
1 parent 9fd9ebc commit 65d64e2
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Bug Fixes

1. [#100](https://github.com/InfluxCommunity/influxdb3-python/pull/100): InfluxDB Edge (OSS) error handling
1. [#101](https://github.com/InfluxCommunity/influxdb3-python/pull/101): Add support for InfluxDB Edge authentication

## 0.7.0 [2024-07-11]

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ from influxdb_client_3 import InfluxDBClient3, Point
## Initialization
If you are using InfluxDB Cloud, then you should note that:
1. You will need to supply your org id, this is not necessary for InfluxDB Dedicated.
2. Use a bucketname for the database argument.
2. Use bucket name for the `database` argument.

```python
client = InfluxDBClient3(token="your-token",
Expand Down
23 changes: 22 additions & 1 deletion influxdb_client_3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,28 @@ def __init__(
:type write_client_options: callable
:param flight_client_options: Function for providing additional arguments for the FlightClient.
:type flight_client_options: callable
:param kwargs: Additional arguments for the InfluxDB Client.
:key auth_scheme: token authentication scheme. Set to "Bearer" for Edge.
:key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server.
:key str ssl_ca_cert: Set this to customize the certificate file to verify the peer.
:key str cert_file: Path to the certificate that will be used for mTLS authentication.
:key str cert_key_file: Path to the file contains private key for mTLS certificate.
:key str cert_key_password: String or function which returns password for decrypting the mTLS private key.
:key ssl.SSLContext ssl_context: Specify a custom Python SSL Context for the TLS/ mTLS handshake.
Be aware that only delivered certificate/ key files or an SSL Context are
possible.
:key str proxy: Set this to configure the http proxy to be used (ex. http://localhost:3128)
:key str proxy_headers: A dictionary containing headers that will be sent to the proxy. Could be used for proxy
authentication.
:key int connection_pool_maxsize: Number of connections to save that can be reused by urllib3.
Defaults to "multiprocessing.cpu_count() * 5".
:key urllib3.util.retry.Retry retries: Set the default retry strategy that is used for all HTTP requests
except batching writes. As a default there is no one retry strategy.
:key bool auth_basic: Set this to true to enable basic authentication when talking to a InfluxDB 1.8.x that
does not use auth-enabled but is protected by a reverse proxy with basic authentication.
(defaults to false, don't set to true when talking to InfluxDB 2)
:key str username: ``username`` to authenticate via username and password credentials to the InfluxDB 2.x
:key str password: ``password`` to authenticate via username and password credentials to the InfluxDB 2.x
:key list[str] profilers: list of enabled Flux profilers
"""
self._org = org if org is not None else "default"
self._database = database
Expand Down
6 changes: 3 additions & 3 deletions influxdb_client_3/write_client/client/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class _BaseClient(object):
def __init__(self, url, token, debug=None, timeout=10_000, enable_gzip=False, org: str = None,
default_tags: dict = None, http_client_logger: str = None, **kwargs) -> None:
self.url = url
self.token = token
self.org = org

self.default_tags = default_tags
Expand Down Expand Up @@ -70,9 +69,10 @@ def __init__(self, url, token, debug=None, timeout=10_000, enable_gzip=False, or
self.auth_header_name = None
self.auth_header_value = None
# by token
if self.token:
if token:
auth_scheme = kwargs.get('auth_scheme', "Token")
self.auth_header_name = "Authorization"
self.auth_header_value = "Token " + self.token
self.auth_header_value = f"{auth_scheme} {token}"
# by HTTP basic
auth_basic = kwargs.get('auth_basic', False)
if auth_basic:
Expand Down
1 change: 1 addition & 0 deletions influxdb_client_3/write_client/client/influxdb_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self, url, token: str = None, debug=None, timeout=10_000, enable_gz
:param enable_gzip: Enable Gzip compression for http requests. Currently, only the "Write" and "Query" endpoints
supports the Gzip compression.
:param org: organization name (used as a default in Query, Write and Delete API)
:key auth_scheme: token authentication scheme. Set to "Bearer" for Edge.
:key bool verify_ssl: Set this to false to skip verifying SSL certificate when calling API from https server.
:key str ssl_ca_cert: Set this to customize the certificate file to verify the peer.
:key str cert_file: Path to the certificate that will be used for mTLS authentication.
Expand Down
21 changes: 21 additions & 0 deletions tests/test_influxdb_client_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ def test_init(self):
self.assertEqual(self.client._write_api, self.mock_write_api.return_value)
self.assertEqual(self.client._query_api, self.mock_query_api.return_value)

# test default token auth_scheme
def test_token_auth_scheme_default(self):
client = InfluxDBClient3(
host="localhost",
org="my_org",
database="my_db",
token="my_token",
)
self.assertEqual(client._client.auth_header_value, "Token my_token")

# test explicit token auth_scheme
def test_token_auth_scheme_explicit(self):
client = InfluxDBClient3(
host="localhost",
org="my_org",
database="my_db",
token="my_token",
auth_scheme="my_scheme"
)
self.assertEqual(client._client.auth_header_value, "my_scheme my_token")


if __name__ == '__main__':
unittest.main()
25 changes: 19 additions & 6 deletions tests/test_influxdb_client_3_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from influxdb_client_3 import InfluxDBClient3
from influxdb_client_3 import InfluxDBClient3, InfluxDBError


@pytest.mark.integration
Expand All @@ -21,11 +21,10 @@
class TestInfluxDBClient3Integration(unittest.TestCase):

def setUp(self):
host = os.getenv('TESTING_INFLUXDB_URL')
token = os.getenv('TESTING_INFLUXDB_TOKEN')
database = os.getenv('TESTING_INFLUXDB_DATABASE')

self.client = InfluxDBClient3(host=host, database=database, token=token)
self.host = os.getenv('TESTING_INFLUXDB_URL')
self.token = os.getenv('TESTING_INFLUXDB_TOKEN')
self.database = os.getenv('TESTING_INFLUXDB_DATABASE')
self.client = InfluxDBClient3(host=self.host, database=self.database, token=self.token)

def tearDown(self):
if self.client:
Expand All @@ -43,3 +42,17 @@ def test_write_and_query(self):
self.assertEqual(1, len(df))
self.assertEqual(test_id, df['test_id'][0])
self.assertEqual(123.0, df['value'][0])

def test_auth_error_token(self):
self.client = InfluxDBClient3(host=self.host, database=self.database, token='fake token')
test_id = time.time_ns()
with self.assertRaises(InfluxDBError) as err:
self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
self.assertEqual('unauthorized access', err.exception.message) # Cloud

def test_auth_error_auth_scheme(self):
self.client = InfluxDBClient3(host=self.host, database=self.database, token=self.token, auth_scheme='Any')
test_id = time.time_ns()
with self.assertRaises(InfluxDBError) as err:
self.client.write(f"integration_test_python,type=used value=123.0,test_id={test_id}i")
self.assertEqual('unauthorized access', err.exception.message) # Cloud

0 comments on commit 65d64e2

Please sign in to comment.