use oauth2::basic::{BasicClient, BasicErrorResponseType, BasicTokenType};
use oauth2::{
Client, ClientId, ClientSecret, EmptyExtraTokenFields, EndpointNotSet, EndpointSet,
RedirectUrl, RevocationErrorResponseType, StandardErrorResponse, StandardRevocableToken,
StandardTokenIntrospectionResponse, StandardTokenResponse,
};
use crate::builder::ClientBuilder;
use crate::config::Config;
use crate::error::{ConfigError, Error};
pub(crate) type OAuth2Client = Client<
StandardErrorResponse<BasicErrorResponseType>,
StandardTokenResponse<EmptyExtraTokenFields, BasicTokenType>,
StandardTokenIntrospectionResponse<EmptyExtraTokenFields, BasicTokenType>,
StandardRevocableToken,
StandardErrorResponse<RevocationErrorResponseType>,
EndpointSet,
EndpointNotSet,
EndpointNotSet,
EndpointNotSet,
EndpointSet,
>;
impl ClientBuilder {
pub(crate) fn setup_oauth_client(self, config: &Config) -> Result<OAuth2Client, Error> {
let client_id = match self.client_id.clone() {
Some(id) => id.clone(),
None => return Err(Error::ConfigError(ConfigError::MissingClientId)),
};
let client_secret = match self.client_secret.clone() {
Some(secret) => secret.clone(),
None => return Err(Error::ConfigError(ConfigError::MissingClientSecret)),
};
let callback_url = match self.callback_url.clone() {
Some(url) => url.clone(),
None => return Err(Error::ConfigError(ConfigError::MissingCallbackUrl)),
};
let redirect_url = match RedirectUrl::new(callback_url) {
Ok(url) => url,
Err(_) => return Err(Error::ConfigError(ConfigError::InvalidCallbackUrl)),
};
let client = BasicClient::new(ClientId::new(client_id))
.set_client_secret(ClientSecret::new(client_secret))
.set_auth_uri(config.auth_url.clone())
.set_token_uri(config.token_url.clone())
.set_redirect_uri(redirect_url);
Ok(client)
}
}
#[cfg(test)]
mod tests {
use crate::error::{ConfigError, Error};
use crate::Client;
#[test]
fn test_success() {
let result = Client::builder()
.client_id("client_id")
.client_secret("client_secret")
.callback_url("http://localhost:8080/callback")
.build();
assert!(result.is_ok())
}
#[test]
fn test_missing_client_id() {
let result = Client::builder()
.user_agent("MyApp/1.0 (contact@example.com)")
.client_secret("client_secret")
.callback_url("http://localhost:8080/callback")
.build();
assert!(result.is_err());
assert!(matches!(
result,
Err(Error::ConfigError(ConfigError::MissingClientId))
));
}
#[test]
fn test_missing_client_secret() {
let result = Client::builder()
.user_agent("MyApp/1.0 (contact@example.com)")
.client_id("client_id")
.callback_url("http://localhost:8080/callback")
.build();
assert!(result.is_err());
assert!(matches!(
result,
Err(Error::ConfigError(ConfigError::MissingClientSecret))
));
}
#[test]
fn test_missing_callback_url() {
let result = Client::builder()
.user_agent("MyApp/1.0 (contact@example.com)")
.client_id("client_id")
.client_secret("client_secret")
.build();
assert!(result.is_err());
assert!(matches!(
result,
Err(Error::ConfigError(ConfigError::MissingCallbackUrl))
));
}
#[test]
fn test_invalid_callback_url() {
let result = Client::builder()
.user_agent("MyApp/1.0 (contact@example.com)")
.client_id("client_id")
.client_secret("client_secret")
.callback_url("invalid_url") .build();
assert!(result.is_err());
assert!(matches!(
result,
Err(Error::ConfigError(ConfigError::InvalidCallbackUrl))
));
}
}