From de16d9698db4ea851464d3f3c49f51c97dcbdf03 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 26 Feb 2019 16:44:44 +0100 Subject: [PATCH] feat: Add optional `Request::basic_auth` utility function This function adds a dependency on `base64` and is thus gated behind the (enabled by default) `basic_auth` feature. --- Cargo.toml | 4 +++- src/lib.rs | 10 ++++++++++ src/tests.rs | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 60247f3e6..175d34244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,10 +4,12 @@ version = "0.1.0" authors = ["Vincent Ambo "] [features] -default = [ "json" ] +default = [ "json", "basic_auth" ] json = [ "serde", "serde_json"] +basic_auth = [ "base64" ] [dependencies] curl = "0.4" serde = { version = "1.0", optional = true } serde_json = { version = "1.0", optional = true } +base64 = { version = "0.10", optional = true } diff --git a/src/lib.rs b/src/lib.rs index 9caedff31..9374460d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ extern crate curl; #[cfg(feature = "json")] extern crate serde; #[cfg(feature = "json")] extern crate serde_json; +#[cfg(feature = "basic_auth")] extern crate base64; use curl::easy::{Easy, Form, List, ReadError}; use std::collections::HashMap; @@ -136,6 +137,15 @@ impl <'a> Request<'a> { Ok(self) } + #[cfg(feature = "basic_auth")] + /// Set the `Authorization` header to a basic authentication value + /// from the supplied username and password. + pub fn basic_auth(mut self, username: &str, password: &str) -> Result { + let auth = base64::encode(format!("{}:{}", username, password).as_bytes()); + self.headers.append(&format!("Authorization: Basic {}", auth))?; + Ok(self) + } + /// Add a byte-array body to a request using the specified /// `Content-Type`. pub fn body(mut self, content_type: &'a str, data: &'a [u8]) -> Self { diff --git a/src/tests.rs b/src/tests.rs index cc44ca7b5..088334aa2 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -88,3 +88,19 @@ fn test_http_post_json() { "Content-Type should be `application/json`", ); } + +// Tests for different authentication methods that are supported +// out-of-the-box: + +#[cfg(feature = "basic_auth")] #[test] +fn test_basic_auth() { + let request = Request::new( + Method::Get, "https://httpbin.org/basic-auth/alan_watts/oneness" + ); + + let response = request + .basic_auth("alan_watts", "oneness").expect("failed to set auth header") + .send().expect("failed to send request"); + + assert!(response.is_success(), "authorized request should succeed"); +}