-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor Rust SDK for multiple autentication methods
. . Rust: move auth to own module . . . . . Rust: restructure again refactoring of auth module finished add docs and update deps
- Loading branch information
Showing
18 changed files
with
313 additions
and
270 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use crate::error::VResult; | ||
use async_trait::async_trait; | ||
|
||
pub static DEFAULT_TOKEN_URL: &str = | ||
"https://account.gdata.de/realms/vaas-production/protocol/openid-connect/token"; | ||
|
||
/// This trait has to be implemented by any authentication methods for VaaS. | ||
#[async_trait] | ||
pub trait Authenticator { | ||
/// Return a valid token that can be used to authenticate against the VaaS service. | ||
async fn get_token(&self) -> VResult<String>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
use crate::auth::authenticator::{Authenticator, DEFAULT_TOKEN_URL}; | ||
use crate::error::{Error, VResult}; | ||
use crate::message::OpenIdConnectTokenResponse; | ||
use async_trait::async_trait; | ||
use reqwest::StatusCode; | ||
use reqwest::Url; | ||
|
||
/// Authenticator for the VaaS service using the client credentials flow. | ||
/// Expects a client id and a client secret. | ||
pub struct ClientCredentials { | ||
client_id: String, | ||
client_secret: String, | ||
token_url: Url, | ||
} | ||
|
||
impl ClientCredentials { | ||
/// Create a new authenticator for the VaaS service using the client credentials flow. | ||
pub fn new(client_id: String, client_secret: String) -> Self { | ||
Self { | ||
client_id, | ||
client_secret, | ||
token_url: Url::parse(DEFAULT_TOKEN_URL).unwrap(), // Safe to unwrap, as this is a constant URL and will always be valid. | ||
} | ||
} | ||
/// Set the token URL to be used for authentication. | ||
pub fn with_token_url(mut self, token_url: Url) -> Self { | ||
self.token_url = token_url; | ||
self | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl Authenticator for ClientCredentials { | ||
async fn get_token(&self) -> VResult<String> { | ||
let params = [ | ||
("client_id", self.client_id.clone()), | ||
("client_secret", self.client_secret.clone()), | ||
("grant_type", "client_credentials".to_string()), | ||
]; | ||
let client = reqwest::Client::new(); | ||
let token_response = client | ||
.post(self.token_url.clone()) | ||
.form(¶ms) | ||
.send() | ||
.await?; | ||
|
||
match token_response.status() { | ||
StatusCode::OK => { | ||
let json_string = token_response.text().await?; | ||
Ok(OpenIdConnectTokenResponse::try_from(&json_string)?.access_token) | ||
} | ||
status => Err(Error::FailedAuthTokenRequest( | ||
status, | ||
token_response.text().await.unwrap_or_default(), | ||
)), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::error::Error::FailedAuthTokenRequest; | ||
|
||
#[tokio::test] | ||
async fn authenticator_returns_token() { | ||
let token_url: Url = dotenv::var("TOKEN_URL") | ||
.expect("No TOKEN_URL environment variable set to be used in the integration tests") | ||
.parse() | ||
.expect("Failed to parse TOKEN_URL environment variable"); | ||
let client_id = dotenv::var("CLIENT_ID").expect( | ||
"No VAAS_CLIENT_ID environment variable set to be used in the integration tests", | ||
); | ||
let client_secret = dotenv::var("CLIENT_SECRET").expect( | ||
"No VAAS_PASSWORD environment variable set to be used in the integration tests", | ||
); | ||
let authenticator = | ||
ClientCredentials::new(client_id, client_secret).with_token_url(token_url); | ||
|
||
let token = authenticator.get_token().await; | ||
|
||
assert!(token.is_ok()) | ||
} | ||
|
||
#[tokio::test] | ||
async fn authenticator_wrong_credentials() { | ||
let token_url: Url = dotenv::var("TOKEN_URL") | ||
.expect("No TOKEN_URL environment variable set to be used in the integration tests") | ||
.parse() | ||
.expect("Failed to parse TOKEN_URL environment variable"); | ||
let client_id = "invalid".to_string(); | ||
let client_secret = "invalid".to_string(); | ||
let authenticator = | ||
ClientCredentials::new(client_id, client_secret).with_token_url(token_url); | ||
|
||
let token = authenticator.get_token().await; | ||
|
||
assert!(token.is_err()); | ||
assert!(match token { | ||
Ok(_) => false, | ||
Err(FailedAuthTokenRequest(_, _)) => true, | ||
_ => false, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
//! # Authenticators | ||
//! | ||
//! This module contains the different **OAuth2 Grant Types** that can be used to authenticate against the VaaS service. | ||
mod client_credentials; | ||
mod password; | ||
|
||
pub use client_credentials::ClientCredentials; | ||
pub use password::Password; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
use crate::auth::Authenticator; | ||
use crate::error::{Error, VResult}; | ||
use crate::message::OpenIdConnectTokenResponse; | ||
use async_trait::async_trait; | ||
use reqwest::{StatusCode, Url}; | ||
|
||
/// Authenticator for the VaaS service using the password flow. | ||
/// Expects a client id, a user name and a password. | ||
pub struct Password { | ||
client_id: String, | ||
user_name: String, | ||
password: String, | ||
token_url: Url, | ||
} | ||
|
||
impl Password { | ||
/// Create a new authenticator for the VaaS service using the password flow. | ||
pub fn new(client_id: String, user_name: String, password: String) -> Self { | ||
Self { | ||
client_id, | ||
user_name, | ||
password, | ||
token_url: Url::parse(crate::auth::authenticator::DEFAULT_TOKEN_URL).unwrap(), // Safe to unwrap, as this is a constant URL and will always be valid. | ||
} | ||
} | ||
/// Set the token URL to be used for authentication. | ||
pub fn with_token_url(mut self, token_url: Url) -> Self { | ||
self.token_url = token_url; | ||
self | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl Authenticator for Password { | ||
async fn get_token(&self) -> VResult<String> { | ||
let params = [ | ||
("client_id", self.client_id.clone()), | ||
("username", self.user_name.clone()), | ||
("password", self.password.clone()), | ||
("grant_type", "password".to_string()), | ||
]; | ||
let client = reqwest::Client::new(); | ||
let token_response = client | ||
.post(self.token_url.clone()) | ||
.form(¶ms) | ||
.send() | ||
.await?; | ||
|
||
match token_response.status() { | ||
StatusCode::OK => { | ||
let json_string = token_response.text().await?; | ||
Ok(OpenIdConnectTokenResponse::try_from(&json_string)?.access_token) | ||
} | ||
status => Err(Error::FailedAuthTokenRequest( | ||
status, | ||
token_response.text().await.unwrap_or_default(), | ||
)), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::error::Error::FailedAuthTokenRequest; | ||
|
||
#[tokio::test] | ||
async fn authenticator_returns_token() { | ||
let token_url: Url = dotenv::var("TOKEN_URL") | ||
.expect("No TOKEN_URL environment variable set to be used in the integration tests") | ||
.parse() | ||
.expect("Failed to parse TOKEN_URL environment variable"); | ||
let client_id = dotenv::var("VAAS_CLIENT_ID").expect( | ||
"No VAAS_CLIENT_ID environment variable set to be used in the integration tests", | ||
); | ||
let user_name = dotenv::var("VAAS_USER_NAME").expect( | ||
"No VAAS_USER_NAME environment variable set to be used in the integration tests", | ||
); | ||
let password = dotenv::var("VAAS_PASSWORD").expect( | ||
"No VAAS_PASSWORD environment variable set to be used in the integration tests", | ||
); | ||
let authenticator = Password::new(client_id, user_name, password).with_token_url(token_url); | ||
|
||
let token = authenticator.get_token().await; | ||
|
||
assert!(token.is_ok()) | ||
} | ||
|
||
#[tokio::test] | ||
async fn authenticator_wrong_credentials() { | ||
let token_url: Url = dotenv::var("TOKEN_URL") | ||
.expect("No TOKEN_URL environment variable set to be used in the integration tests") | ||
.parse() | ||
.expect("Failed to parse TOKEN_URL environment variable"); | ||
let client_id = "invalid".to_string(); | ||
let user_name = "invalid".to_string(); | ||
let password = "invalid".to_string(); | ||
let authenticator = Password::new(client_id, user_name, password).with_token_url(token_url); | ||
|
||
let token = authenticator.get_token().await; | ||
|
||
assert!(token.is_err()); | ||
assert!(match token { | ||
Ok(_) => false, | ||
Err(FailedAuthTokenRequest(_, _)) => true, | ||
_ => false, | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
//! # Authentication | ||
//! | ||
//! This module contains all needed funcionality to authenticate against the VaaS service. | ||
mod authenticator; | ||
pub mod authenticators; | ||
|
||
pub use authenticator::Authenticator; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.