103 lines
3.7 KiB
Rust
103 lines
3.7 KiB
Rust
use std::sync::Arc;
|
|
|
|
use actix_web::{http::header, HttpResponse};
|
|
use url::Url;
|
|
|
|
use crate::auth::application::port::input::ui::{errors::*, login::RequestAuthorizationInterface};
|
|
use crate::auth::application::port::out::db::save_oauth_state::SaveOAuthState;
|
|
use crate::auth::application::port::out::forge::oauth_auth_req_uri::OAuthAuthReqUri;
|
|
use crate::auth::application::services::request_authorization::{
|
|
command::RequestAuthorizationCommand, service::RequestAuthorizationService,
|
|
RequestAuthorizationUserCase,
|
|
};
|
|
use crate::utils::random_string::GenerateRandomStringInterface;
|
|
|
|
pub struct RequestAuthorizationHandler {
|
|
save_oauth_state_adapter: Arc<dyn SaveOAuthState>,
|
|
oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
|
|
generate_random_string: Arc<dyn GenerateRandomStringInterface>,
|
|
process_authorization_response_redirect_uri: Url,
|
|
}
|
|
|
|
impl RequestAuthorizationHandler {
|
|
pub fn new(
|
|
save_oauth_state_adapter: Arc<dyn SaveOAuthState>,
|
|
oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
|
|
generate_random_string: Arc<dyn GenerateRandomStringInterface>,
|
|
process_authorization_response_redirect_uri: Url,
|
|
) -> Self {
|
|
Self {
|
|
save_oauth_state_adapter,
|
|
oauth_auth_req_uri_adapter,
|
|
process_authorization_response_redirect_uri,
|
|
generate_random_string,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait::async_trait]
|
|
impl RequestAuthorizationInterface for RequestAuthorizationHandler {
|
|
#[tracing::instrument(name = "web adapter request_oauth_authorization", skip(self))]
|
|
async fn request_oauth_authorization(&self, forge_name: String) -> InUIResult<HttpResponse> {
|
|
let service = RequestAuthorizationService::new(
|
|
self.save_oauth_state_adapter.clone(),
|
|
self.oauth_auth_req_uri_adapter.clone(),
|
|
self.process_authorization_response_redirect_uri.clone(),
|
|
self.generate_random_string.clone(),
|
|
);
|
|
|
|
let cmd = RequestAuthorizationCommand::new_command(forge_name)?;
|
|
let auth_page = service.request_authorization(cmd).await?;
|
|
Ok(HttpResponse::Found()
|
|
.insert_header((header::LOCATION, auth_page.as_str()))
|
|
.finish())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use actix_web::http::{header, StatusCode};
|
|
|
|
use super::*;
|
|
use crate::auth::application::port::out::{
|
|
db::save_oauth_state::tests::*, forge::oauth_auth_req_uri::tests::*,
|
|
};
|
|
use crate::tests::bdd::IS_CALLED_ONLY_ONCE;
|
|
use crate::utils::random_string::tests::*;
|
|
|
|
#[actix_web::test]
|
|
async fn test_adapter() {
|
|
let random_string = "foorand";
|
|
let url = Url::parse("http://test_ui_req_auth_interface_adapter").unwrap();
|
|
let oauth_provider = "test_ui_req_auth_interface_adapter";
|
|
let mut redirect_uri = url.clone();
|
|
redirect_uri.set_query(Some(&format!("state={random_string}")));
|
|
|
|
let mock_random_generate_string =
|
|
mock_generate_random_string(IS_CALLED_ONLY_ONCE, random_string.into());
|
|
let mock_oauth_req_uri = mock_oauth_auth_req_uri(IS_CALLED_ONLY_ONCE, redirect_uri.clone());
|
|
let mock_save_oauth_state = mock_save_oauth_state(IS_CALLED_ONLY_ONCE);
|
|
|
|
let adapter = RequestAuthorizationHandler::new(
|
|
mock_save_oauth_state,
|
|
mock_oauth_req_uri,
|
|
mock_random_generate_string,
|
|
url.clone(),
|
|
);
|
|
|
|
let res = adapter
|
|
.request_oauth_authorization(oauth_provider.into())
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(res.status(), StatusCode::FOUND);
|
|
assert_eq!(
|
|
res.headers()
|
|
.get(header::LOCATION)
|
|
.unwrap()
|
|
.to_str()
|
|
.unwrap(),
|
|
redirect_uri.as_str()
|
|
);
|
|
}
|
|
}
|