auth0 0.3.0

Auth0 API library
Documentation
use crate::authentication::Api;
use reqwest::header::{HeaderMap, HeaderValue};
use reqwest::RequestBuilder;
pub use serde::{Deserialize, Serialize};

pub mod add_authenticator;
pub mod challenge_request;
pub mod delete_authenticator;
pub mod list_authenticators;
pub mod one_time_password;
pub mod out_of_band;
pub mod recovery_code;

pub trait MultiFactorAuthentication {
    fn challenge_request(&self, request: challenge_request::RequestParameters) -> RequestBuilder;
    fn verify_with_otp(&self, request: one_time_password::RequestParameters) -> RequestBuilder;
    fn verify_with_oob(&self, request: out_of_band::RequestParameters) -> RequestBuilder;
    fn verify_with_recovery_code(
        &self,
        request: recovery_code::RequestParameters,
    ) -> RequestBuilder;
    fn add_authenticator(&self, request: add_authenticator::RequestParameters) -> RequestBuilder;
    fn list_authenticators(
        &self,
        request: list_authenticators::RequestParameters,
    ) -> RequestBuilder;
    fn delete_authenticator(
        &self,
        request: delete_authenticator::RequestParameters,
    ) -> RequestBuilder;
}

impl MultiFactorAuthentication for Api {
    fn challenge_request(&self, request: challenge_request::RequestParameters) -> RequestBuilder {
        let endpoint = String::from("/mfa/challenge");
        let url = self.base_url.join(&endpoint).unwrap();
        self.client.post(url).json(&request)
    }
    fn verify_with_otp(&self, request: one_time_password::RequestParameters) -> RequestBuilder {
        let endpoint = String::from("/oauth/token");
        let url = self.base_url.join(&endpoint).unwrap();
        self.client.post(url).form(&request)
    }
    fn verify_with_oob(&self, request: out_of_band::RequestParameters) -> RequestBuilder {
        let endpoint = String::from("/oauth/token");
        let url = self.base_url.join(&endpoint).unwrap();
        self.client.post(url).form(&request)
    }
    fn verify_with_recovery_code(
        &self,
        request: recovery_code::RequestParameters,
    ) -> RequestBuilder {
        let endpoint = String::from("/oauth/token");
        let url = self.base_url.join(&endpoint).unwrap();
        self.client.post(url).form(&request)
    }
    fn add_authenticator(&self, request: add_authenticator::RequestParameters) -> RequestBuilder {
        let endpoint = String::from("/mfa/associate");
        let url = self.base_url.join(&endpoint).unwrap();
        self.client.post(url).json(&request)
    }
    fn list_authenticators(
        &self,
        request: list_authenticators::RequestParameters,
    ) -> RequestBuilder {
        let endpoint = String::from("/mfa/authenticators");
        let url = self.base_url.join(&endpoint).unwrap();
        let mut headers = HeaderMap::new();
        let auth_value = format!("Bearer {}", &request.access_token);
        let json_header = String::from("application/json");
        headers.insert(
            reqwest::header::AUTHORIZATION,
            HeaderValue::from_str(&auth_value).unwrap(),
        );
        headers.insert(
            reqwest::header::CONTENT_TYPE,
            HeaderValue::from_str(&json_header).unwrap(),
        );
        self.client.get(url).headers(headers)
    }
    fn delete_authenticator(
        &self,
        request: delete_authenticator::RequestParameters,
    ) -> RequestBuilder {
        let endpoint = String::from("/mfa/authenticators/");
        let base_url = self.base_url.join(&endpoint).unwrap();
        let url = base_url.join(&request.authenticator_id).unwrap();
        let mut headers = HeaderMap::new();
        let auth_value = format!("Bearer {}", &request.access_token);
        let json_header = String::from("application/json");
        headers.insert(
            reqwest::header::AUTHORIZATION,
            HeaderValue::from_str(&auth_value).unwrap(),
        );
        headers.insert(
            reqwest::header::CONTENT_TYPE,
            HeaderValue::from_str(&json_header).unwrap(),
        );
        self.client.delete(url).headers(headers)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::authentication::*;

    #[test]
    fn challenge_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::challenge_request::RequestParameters {
            mfa_token: String::from("some_awesome_mfa_token"),
            client_id: String::from("some_awesome_client_id"),
            client_secret: None,
            challenge_type: None,
            oob_channel: None,
            authenticator_id: None,
        };
        let request = mfa.challenge_request(parameters).build().unwrap();
        let test_url = String::from("https://your_domain/mfa/challenge");
        let test_body = String::from(
            "{\"mfa_token\":\"some_awesome_mfa_token\",\
            \"client_id\":\"some_awesome_client_id\"}",
        );
        assert_eq!(request.method().as_str(), reqwest::Method::POST);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 1);
        assert_eq!(
            request.body().unwrap().as_bytes().unwrap(),
            test_body.as_bytes(),
        );
    }

    #[test]
    fn one_time_password_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::one_time_password::RequestParameters {
            grant_type: String::from("some_awesome_grant_type"),
            client_id: String::from("some_awesome_client_id"),
            client_secret: None,
            mfa_token: String::from("some_awesome_mfa_token"),
            otp: String::from("some_awesome_otp"),
        };
        let request = mfa.verify_with_otp(parameters).build().unwrap();
        let test_url = String::from("https://your_domain/oauth/token");
        let test_body = String::from(
            "grant_type=some_awesome_grant_type&\
            client_id=some_awesome_client_id&\
            mfa_token=some_awesome_mfa_token&\
            otp=some_awesome_otp",
        );
        assert_eq!(request.method().as_str(), reqwest::Method::POST);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 1);
        assert_eq!(
            request.body().unwrap().as_bytes().unwrap(),
            test_body.as_bytes(),
        );
    }

    #[test]
    fn out_of_band_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::out_of_band::RequestParameters {
            grant_type: String::from("some_awesome_grant_type"),
            client_id: String::from("some_awesome_client_id"),
            client_secret: None,
            mfa_token: String::from("some_awesome_mfa_token"),
            oob_code: String::from("some_awesome_oob_code"),
            binding_code: None,
        };
        let request = mfa.verify_with_oob(parameters).build().unwrap();
        let test_url = String::from("https://your_domain/oauth/token");
        let test_body = String::from(
            "grant_type=some_awesome_grant_type&\
            client_id=some_awesome_client_id&\
            mfa_token=some_awesome_mfa_token&\
            oob_code=some_awesome_oob_code",
        );
        assert_eq!(request.method().as_str(), reqwest::Method::POST);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 1);
        assert_eq!(
            request.body().unwrap().as_bytes().unwrap(),
            test_body.as_bytes(),
        );
    }

    #[test]
    fn recovery_code_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::recovery_code::RequestParameters {
            grant_type: String::from("some_awesome_grant_type"),
            client_id: String::from("some_awesome_client_id"),
            client_secret: None,
            mfa_token: String::from("some_awesome_mfa_token"),
            recovery_code: String::from("some_awesome_mfa_token"),
        };
        let request = mfa.verify_with_recovery_code(parameters).build().unwrap();
        let test_url = String::from("https://your_domain/oauth/token");
        let test_body = String::from(
            "grant_type=some_awesome_grant_type&\
            client_id=some_awesome_client_id&\
            mfa_token=some_awesome_mfa_token&\
            recovery_code=some_awesome_mfa_token",
        );
        assert_eq!(request.method().as_str(), reqwest::Method::POST);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 1);
        assert_eq!(
            request.body().unwrap().as_bytes().unwrap(),
            test_body.as_bytes(),
        );
    }

    #[test]
    fn add_authenticator_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::add_authenticator::RequestParameters {
            client_id: String::from("some_awesome_client_id"),
            client_secret: None,
            authenticator_types: String::from("some_awesome_authenticator_type"),
            oob_channel: None,
            phone_number: None,
        };
        let request = mfa.add_authenticator(parameters).build().unwrap();
        let test_url = String::from("https://your_domain/mfa/associate");
        let test_body = String::from(
            "{\"client_id\":\"some_awesome_client_id\",\
            \"authenticator_types\":\"some_awesome_authenticator_type\"}",
        );
        assert_eq!(request.method().as_str(), reqwest::Method::POST);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 1);
        assert_eq!(
            request.body().unwrap().as_bytes().unwrap(),
            test_body.as_bytes(),
        );
    }

    #[test]
    fn list_authenticators_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::list_authenticators::RequestParameters {
            access_token: String::from("some_awesome_access_token"),
        };
        let request = mfa.list_authenticators(parameters).build().unwrap();
        let test_url = String::from("https://your_domain/mfa/authenticators");
        assert_eq!(request.method().as_str(), reqwest::Method::GET);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 2);
        assert_eq!(request.body().is_none(), true);
    }

    #[test]
    fn delete_authenticator_build_request() {
        let base_url = Url::parse("https://YOUR_DOMAIN").unwrap();
        let authentication = AuthenicationMethod::OAuth2Token(String::from("some_awesome_token"));
        let mfa = Api::init(base_url, authentication);
        let parameters = mfa::delete_authenticator::RequestParameters {
            access_token: String::from("some_awesome_access_token"),
            authenticator_id: String::from("some_awesome_authenticator_id"),
        };
        let request = mfa.delete_authenticator(parameters).build().unwrap();
        let test_url =
            String::from("https://your_domain/mfa/authenticators/some_awesome_authenticator_id");
        assert_eq!(request.method().as_str(), reqwest::Method::DELETE);
        assert_eq!(request.url().as_str(), test_url);
        assert_eq!(request.headers().len(), 2);
        assert_eq!(request.body().is_none(), true);
    }
}