Skip to content

Added support for token auth #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
rust_release: [1.45, stable, nightly]
rust_release: [1.46, stable, nightly]
os: [ubuntu-latest, windows-latest, macOS-latest]

steps:
Expand All @@ -45,8 +45,24 @@ jobs:
- name: Build
run: cargo build --verbose

unit_test:
name: Unit test (${{ matrix.rust_release }}/${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
rust_release: [1.46, stable, nightly]
os: [ubuntu-latest, windows-latest, macOS-latest]

steps:
- uses: actions/checkout@v1
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust_release }}
- name: test
run: cargo test --lib

integration_test:
name: Integration Tests (stable/ubuntu-latest)
name: Integration Tests for Influxdb 1.x (stable/ubuntu-latest)
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -66,11 +82,32 @@ jobs:
INFLUXDB_ADMIN_PASSWORD: password
INFLUXDB_USER: nopriv_user
INFLUXDB_USER_PASSWORD: password
steps:
- uses: actions/checkout@v1
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --manifest-path=./influxdb/Cargo.toml --no-default-features --features 'use-serde derive ${{ matrix.http-backend }}' --no-fail-fast --test integration_tests

integration_test_v2:
name: Integration Tests for Influxdb 2.0 (stable/ubuntu-latest)
runs-on: ubuntu-latest
strategy:
matrix:
http-backend: [curl-client, h1-client, h1-client-rustls, hyper-client]
services:
influxdbv2:
image: influxdb:2.0
ports:
- 9086:8086
env:
DOCKER_INFLUXDB_INIT_USERNAME: admin
DOCKER_INFLUXDB_INIT_PASSWORD: password
DOCKER_INFLUXDB_INIT_ORG: testing
DOCKER_INFLUXDB_INIT_BUCKET: mydb
DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: admintoken
steps:
- uses: actions/checkout@v1
- uses: dtolnay/rust-toolchain@stable
- run: cargo test --manifest-path=./influxdb/Cargo.toml --no-default-features --features 'use-serde derive ${{ matrix.http-backend }}' --no-fail-fast
- run: cargo test --manifest-path=./influxdb/Cargo.toml --no-default-features --features 'use-serde derive ${{ matrix.http-backend }}' --no-fail-fast --test integration_tests_v2

coverage:
name: Code Coverage (stable/ubuntu-20.04)
Expand Down
2 changes: 1 addition & 1 deletion benches/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async fn main() {
async fn prepare_influxdb(client: &Client, db_name: &str) {
let create_db_stmt = format!("CREATE DATABASE {}", db_name);
client
.query(&Query::raw_read_query(create_db_stmt))
.query(&<dyn Query>::raw_read_query(create_db_stmt))
.await
.expect("failed to create database");
}
Expand Down
35 changes: 32 additions & 3 deletions influxdb/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//! ```

use futures::prelude::*;
use surf::{self, Client as SurfClient, StatusCode};
use surf::{self, Client as SurfClient, RequestBuilder, StatusCode};

use crate::query::QueryType;
use crate::Error;
Expand All @@ -30,6 +30,7 @@ pub struct Client {
pub(crate) url: Arc<String>,
pub(crate) parameters: Arc<HashMap<&'static str, String>>,
pub(crate) client: SurfClient,
pub(crate) token: Option<String>,
}

impl Client {
Expand Down Expand Up @@ -58,6 +59,7 @@ impl Client {
url: Arc::new(url.into()),
parameters: Arc::new(parameters),
client: SurfClient::new(),
token: None,
}
}

Expand Down Expand Up @@ -87,6 +89,19 @@ impl Client {
self
}

/// Add authorization token to [`Client`](crate::Client)
///
/// This is designed for influxdb 2.0's backward-compatible API which
/// requires authrozation by default. You can create such token from
/// console of influxdb 2.0 .
pub fn with_token<S>(mut self, token: S) -> Self
where
S: Into<String>,
{
self.token = Some(token.into());
self
}

/// Returns the name of the database the client is using
pub fn database_name(&self) -> &str {
// safe to unwrap: we always set the database name in `Self::new`
Expand Down Expand Up @@ -164,11 +179,11 @@ impl Client {
error: err.to_string(),
})?;

let mut parameters = self.parameters.as_ref().clone();
let request_builder = match q.get_type() {
QueryType::ReadQuery => {
let read_query = query.get();
let url = &format!("{}/query", &self.url);
let mut parameters = self.parameters.as_ref().clone();
parameters.insert("q", read_query.clone());

if read_query.contains("SELECT") || read_query.contains("SHOW") {
Expand All @@ -189,7 +204,7 @@ impl Client {
error: err.to_string(),
})?;

let request = request_builder.build();
let request = self.auth_if_needed(request_builder).build();
let mut res = self
.client
.send(request)
Expand Down Expand Up @@ -220,6 +235,14 @@ impl Client {

Ok(s)
}

fn auth_if_needed(&self, rb: RequestBuilder) -> RequestBuilder {
if let Some(ref token) = self.token {
rb.header("Authorization", format!("Token {}", token))
} else {
rb
}
}
}

#[cfg(test)]
Expand All @@ -244,5 +267,11 @@ mod tests {
assert_eq!(with_auth.parameters.get("db").unwrap(), "database");
assert_eq!(with_auth.parameters.get("u").unwrap(), "username");
assert_eq!(with_auth.parameters.get("p").unwrap(), "password");

let client = Client::new("http://localhost:8068", "database");
let with_auth = client.with_token("token");
assert_eq!(with_auth.parameters.len(), 1);
assert_eq!(with_auth.parameters.get("db").unwrap(), "database");
assert_eq!(with_auth.token.unwrap(), "token");
}
}
6 changes: 3 additions & 3 deletions influxdb/src/query/read_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ mod tests {

#[test]
fn test_read_builder_single_query() {
let query = Query::raw_read_query("SELECT * FROM aachen").build();
let query = <dyn Query>::raw_read_query("SELECT * FROM aachen").build();

assert_eq!(query.unwrap(), "SELECT * FROM aachen");
}

#[test]
fn test_read_builder_multi_query() {
let query = Query::raw_read_query("SELECT * FROM aachen")
let query = <dyn Query>::raw_read_query("SELECT * FROM aachen")
.add_query("SELECT * FROM cologne")
.build();

Expand All @@ -63,7 +63,7 @@ mod tests {

#[test]
fn test_correct_query_type() {
let query = Query::raw_read_query("SELECT * FROM aachen");
let query = <dyn Query>::raw_read_query("SELECT * FROM aachen");

assert_eq!(query.get_type(), QueryType::ReadQuery);
}
Expand Down
5 changes: 3 additions & 2 deletions influxdb/tests/derive_integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,9 @@ async fn test_write_and_read_option() {
.query(&weather_reading.into_query("weather_reading".to_string()))
.await;
assert_result_ok(&write_result);
let query =
Query::raw_read_query("SELECT time, pressure, wind_strength FROM weather_reading");
let query = <dyn Query>::raw_read_query(
"SELECT time, pressure, wind_strength FROM weather_reading",
);
let result = client.json_query(query).await.and_then(|mut db_result| {
println!("{:?}", db_result);
db_result.deserialize_next::<WeatherReadingWithoutIgnored>()
Expand Down
41 changes: 22 additions & 19 deletions influxdb/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async fn test_connection_error() {
let test_name = "test_connection_error";
let client =
Client::new("http://127.0.0.1:10086", test_name).with_auth("nopriv_user", "password");
let read_query = Query::raw_read_query("SELECT * FROM weather");
let read_query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let read_result = client.query(&read_query).await;
assert_result_err(&read_result);
match read_result {
Expand All @@ -78,7 +78,7 @@ async fn test_authed_write_and_read() {
Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
let query = format!("CREATE DATABASE {}", TEST_NAME);
client
.query(&Query::raw_read_query(query))
.query(&<dyn Query>::raw_read_query(query))
.await
.expect("could not setup db");

Expand All @@ -90,7 +90,7 @@ async fn test_authed_write_and_read() {
let write_result = client.query(&write_query).await;
assert_result_ok(&write_result);

let read_query = Query::raw_read_query("SELECT * FROM weather");
let read_query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let read_result = client.query(&read_query).await;
assert_result_ok(&read_result);
assert!(
Expand All @@ -104,7 +104,7 @@ async fn test_authed_write_and_read() {
let query = format!("DROP DATABASE {}", TEST_NAME);

client
.query(&Query::raw_read_query(query))
.query(&<dyn Query>::raw_read_query(query))
.await
.expect("could not clean up db");
},
Expand All @@ -126,7 +126,7 @@ async fn test_wrong_authed_write_and_read() {
Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
let query = format!("CREATE DATABASE {}", TEST_NAME);
client
.query(&Query::raw_read_query(query))
.query(&<dyn Query>::raw_read_query(query))
.await
.expect("could not setup db");

Expand All @@ -145,7 +145,7 @@ async fn test_wrong_authed_write_and_read() {
),
}

let read_query = Query::raw_read_query("SELECT * FROM weather");
let read_query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let read_result = client.query(&read_query).await;
assert_result_err(&read_result);
match read_result {
Expand All @@ -158,7 +158,7 @@ async fn test_wrong_authed_write_and_read() {

let client = Client::new("http://127.0.0.1:9086", TEST_NAME)
.with_auth("nopriv_user", "password");
let read_query = Query::raw_read_query("SELECT * FROM weather");
let read_query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let read_result = client.query(&read_query).await;
assert_result_err(&read_result);
match read_result {
Expand All @@ -174,7 +174,7 @@ async fn test_wrong_authed_write_and_read() {
Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
let query = format!("DROP DATABASE {}", TEST_NAME);
client
.query(&Query::raw_read_query(query))
.query(&<dyn Query>::raw_read_query(query))
.await
.expect("could not clean up db");
},
Expand All @@ -196,7 +196,7 @@ async fn test_non_authed_write_and_read() {
Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
let query = format!("CREATE DATABASE {}", TEST_NAME);
client
.query(&Query::raw_read_query(query))
.query(&<dyn Query>::raw_read_query(query))
.await
.expect("could not setup db");
let non_authed_client = Client::new("http://127.0.0.1:9086", TEST_NAME);
Expand All @@ -213,7 +213,7 @@ async fn test_non_authed_write_and_read() {
),
}

let read_query = Query::raw_read_query("SELECT * FROM weather");
let read_query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let read_result = non_authed_client.query(&read_query).await;
assert_result_err(&read_result);
match read_result {
Expand All @@ -229,7 +229,7 @@ async fn test_non_authed_write_and_read() {
Client::new("http://127.0.0.1:9086", TEST_NAME).with_auth("admin", "password");
let query = format!("DROP DATABASE {}", TEST_NAME);
client
.query(&Query::raw_read_query(query))
.query(&<dyn Query>::raw_read_query(query))
.await
.expect("could not clean up db");
},
Expand All @@ -255,7 +255,7 @@ async fn test_write_and_read_field() {
let write_result = client.query(&write_query).await;
assert_result_ok(&write_result);

let read_query = Query::raw_read_query("SELECT * FROM weather");
let read_query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let read_result = client.query(&read_query).await;
assert_result_ok(&read_result);
assert!(
Expand Down Expand Up @@ -304,8 +304,9 @@ async fn test_write_and_read_option() {
temperature: i32,
}

let query =
Query::raw_read_query("SELECT time, temperature, wind_strength FROM weather");
let query = <dyn Query>::raw_read_query(
"SELECT time, temperature, wind_strength FROM weather",
);
let result = client
.json_query(query)
.await
Expand Down Expand Up @@ -361,7 +362,7 @@ async fn test_json_query() {
temperature: i32,
}

let query = Query::raw_read_query("SELECT * FROM weather");
let query = <dyn Query>::raw_read_query("SELECT * FROM weather");
let result = client
.json_query(query)
.await
Expand Down Expand Up @@ -419,7 +420,7 @@ async fn test_json_query_tagged() {
temperature: i32,
}

let query = Query::raw_read_query("SELECT * FROM weather GROUP BY location");
let query = <dyn Query>::raw_read_query("SELECT * FROM weather GROUP BY location");
let result = client.json_query(query).await.and_then(|mut db_result| {
db_result.deserialize_next_tagged::<WeatherMeta, Weather>()
});
Expand Down Expand Up @@ -485,7 +486,7 @@ async fn test_json_query_vec() {
temperature: i32,
}

let query = Query::raw_read_query("SELECT * FROM temperature_vec");
let query = <dyn Query>::raw_read_query("SELECT * FROM temperature_vec");
let result = client
.json_query(query)
.await
Expand Down Expand Up @@ -542,7 +543,7 @@ async fn test_serde_multi_query() {

let result = client
.json_query(
Query::raw_read_query("SELECT * FROM temperature")
<dyn Query>::raw_read_query("SELECT * FROM temperature")
.add_query("SELECT * FROM humidity"),
)
.await
Expand Down Expand Up @@ -586,7 +587,9 @@ async fn test_serde_multi_query() {
async fn test_wrong_query_errors() {
let client = create_client("test_name");
let result = client
.json_query(Query::raw_read_query("CREATE DATABASE this_should_fail"))
.json_query(<dyn Query>::raw_read_query(
"CREATE DATABASE this_should_fail",
))
.await;
assert!(
result.is_err(),
Expand Down
Loading