1818use futures_util:: TryFutureExt ;
1919use http:: StatusCode ;
2020#[ cfg( feature = "reqwest" ) ]
21- use reqwest:: { Client as HttpClient , Response as HttpResponse } ;
21+ use reqwest:: { Client as HttpClient , RequestBuilder , Response as HttpResponse } ;
2222use std:: collections:: { BTreeMap , HashMap } ;
2323use std:: fmt:: { self , Debug , Formatter } ;
2424use std:: sync:: Arc ;
2525#[ cfg( feature = "surf" ) ]
26- use surf:: { Client as HttpClient , Response as HttpResponse } ;
26+ use surf:: { Client as HttpClient , RequestBuilder , Response as HttpResponse } ;
2727
2828use crate :: query:: QueryType ;
2929use crate :: Error ;
@@ -34,6 +34,7 @@ use crate::Query;
3434pub struct Client {
3535 pub ( crate ) url : Arc < String > ,
3636 pub ( crate ) parameters : Arc < HashMap < & ' static str , String > > ,
37+ pub ( crate ) token : Option < String > ,
3738 pub ( crate ) client : HttpClient ,
3839}
3940
@@ -89,6 +90,7 @@ impl Client {
8990 url : Arc :: new ( url. into ( ) ) ,
9091 parameters : Arc :: new ( parameters) ,
9192 client : HttpClient :: new ( ) ,
93+ token : None ,
9294 }
9395 }
9496
@@ -126,6 +128,19 @@ impl Client {
126128 self
127129 }
128130
131+ /// Add authorization token to [`Client`](crate::Client)
132+ ///
133+ /// This is designed for influxdb 2.0's backward-compatible API which
134+ /// requires authrozation by default. You can create such token from
135+ /// console of influxdb 2.0 .
136+ pub fn with_token < S > ( mut self , token : S ) -> Self
137+ where
138+ S : Into < String > ,
139+ {
140+ self . token = Some ( token. into ( ) ) ;
141+ self
142+ }
143+
129144 /// Returns the name of the database the client is using
130145 pub fn database_name ( & self ) -> & str {
131146 // safe to unwrap: we always set the database name in `Self::new`
@@ -218,11 +233,11 @@ impl Client {
218233 error : err. to_string ( ) ,
219234 } ) ?;
220235
236+ let mut parameters = self . parameters . as_ref ( ) . clone ( ) ;
221237 let request_builder = match q. get_type ( ) {
222238 QueryType :: ReadQuery => {
223239 let read_query = query. get ( ) ;
224240 let url = & format ! ( "{}/query" , & self . url) ;
225- let mut parameters = self . parameters . as_ref ( ) . clone ( ) ;
226241 parameters. insert ( "q" , read_query. clone ( ) ) ;
227242
228243 if read_query. contains ( "SELECT" ) || read_query. contains ( "SHOW" ) {
@@ -245,7 +260,8 @@ impl Client {
245260 error : err. to_string ( ) ,
246261 } ) ?;
247262
248- let res = request_builder
263+ let res = self
264+ . auth_if_needed ( request_builder)
249265 . send ( )
250266 . map_err ( |err| Error :: ConnectionError {
251267 error : err. to_string ( ) ,
@@ -273,6 +289,14 @@ impl Client {
273289
274290 Ok ( s)
275291 }
292+
293+ fn auth_if_needed ( & self , rb : RequestBuilder ) -> RequestBuilder {
294+ if let Some ( ref token) = self . token {
295+ rb. header ( "Authorization" , format ! ( "Token {}" , token) )
296+ } else {
297+ rb
298+ }
299+ }
276300}
277301
278302pub ( crate ) fn check_status ( res : & HttpResponse ) -> Result < ( ) , Error > {
@@ -327,5 +351,11 @@ mod tests {
327351 assert_eq ! ( with_auth. parameters. get( "db" ) . unwrap( ) , "database" ) ;
328352 assert_eq ! ( with_auth. parameters. get( "u" ) . unwrap( ) , "username" ) ;
329353 assert_eq ! ( with_auth. parameters. get( "p" ) . unwrap( ) , "password" ) ;
354+
355+ let client = Client :: new ( "http://localhost:8068" , "database" ) ;
356+ let with_auth = client. with_token ( "token" ) ;
357+ assert_eq ! ( with_auth. parameters. len( ) , 1 ) ;
358+ assert_eq ! ( with_auth. parameters. get( "db" ) . unwrap( ) , "database" ) ;
359+ assert_eq ! ( with_auth. token. unwrap( ) , "token" ) ;
330360 }
331361}
0 commit comments