Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
view.rs 6.07 KiB
Newer Older
Pierre Jarriges's avatar
Pierre Jarriges committed
use crate::{
    middleware::AuthenticatedAdminMiddleware, view_resource::ViewResourceManager, AppState,
};
use actix_web::{
    get,
    web::{Data, Path},
    HttpRequest, Responder,
};

/// Returns the content of a ViewResource after retrieving it by name.
/// If the resource is not found (has not been registered), it returns the 404 ViewResource.
/// The regex matches uris with more than 3 characters so we don't match the /fr /es etc urls used for the websites translation directories
#[get("/{resource_name:.{3,}}")]
pub async fn get_view<'a>(
    app_state: Data<AppState>,
    resource_manager: Data<ViewResourceManager>,
    auth_middleware: Data<AuthenticatedAdminMiddleware<'a>>,
    req: HttpRequest,
    resource_name: Path<String>,
) -> impl Responder {
    resource_manager
        .get_resource_as_http_response(
            &app_state,
            &auth_middleware,
            &req,
            None,
            &resource_name.into_inner(),
        )
        .await
}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
 *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
 *  _______   ______    ______   _______   *@@
 * |__   __@ |  ____@  /  ____@ |__   __@  *@@
 *    |  @   |  @__    \_ @_       |  @    *@@
 *    |  @   |   __@     \  @_     |  @    *@@
 *    |  @   |  @___   ____\  @    |  @    *@@
 *    |__@   |______@  \______@    |__@    *@@
 *                                         *@@
 *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
 *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@*/

#[cfg(test)]
mod test_views {
    use super::*;
    use crate::{
        middleware::get_auth_cookie,
        model::{AdminAuthCredentials, Administrator},
        view_resource::ViewResourceDescriptor,
    };
    use actix_web::{
        http::StatusCode,
        test,
        web::{Bytes, Data},
        App,
    };

    fn get_views_manager() -> ViewResourceManager {
        ViewResourceManager::with_views(vec![
            ViewResourceDescriptor {
                path_str: "test-view",
                index_file_name: "index.html",
                resource_name: "test-view",
                apply_auth_middleware: false,
            },
            ViewResourceDescriptor {
                path_str: "test-view-auth",
                index_file_name: "index.html",
                resource_name: "test-view-auth",
                apply_auth_middleware: true,
            },
        ])
    }

    async fn get_authenticated_admin(app_state: &AppState) -> Administrator {
        Administrator::authenticated(
            app_state,
            AdminAuthCredentials {
                username: app_state.env.default_admin_username.to_owned(),
                password: app_state.env.default_admin_password.to_owned(),
            },
        )
        .await
        .unwrap()
    }

    #[tokio::test]
    async fn test_get_view() {
        dotenv::dotenv().ok();

        let app_state = AppState::for_test().await;

        let mut app = test::init_service(
            App::new()
                .app_data(Data::new(app_state.clone()))
                .app_data(Data::new(AuthenticatedAdminMiddleware::new(
                    "kuadrado-admin-auth",
                )))
                .app_data(Data::new(get_views_manager()))
                .service(get_view),
        )
        .await;

        let req = test::TestRequest::with_uri("/test-view").to_request();
        let resp = test::call_service(&mut app, req).await;
        assert_eq!(resp.status(), StatusCode::OK);

        let body = test::read_body(resp).await;
        assert_eq!(body, Bytes::from("<h1>TEST</h1>"));
    }

    #[tokio::test]
    async fn test_get_view_auth() {
        dotenv::dotenv().ok();

        let app_state = AppState::for_test().await;

        let mut app = test::init_service(
            App::new()
                .app_data(Data::new(app_state.clone()))
                .app_data(Data::new(AuthenticatedAdminMiddleware::new(
                    "kuadrado-admin-auth",
                )))
                .app_data(Data::new(get_views_manager()))
                .service(get_view),
        )
        .await;
        let admin_user = get_authenticated_admin(&app_state).await;

        let req = test::TestRequest::with_uri("/test-view-auth")
            .cookie(get_auth_cookie(
                "kuadrado-admin-auth",
                app_state
                    .encryption
                    .decrypt(&admin_user.auth_token.unwrap())
                    .to_owned(),
            ))
            .to_request();

        let resp = test::call_service(&mut app, req).await;
        assert_eq!(resp.status(), StatusCode::OK);

        let body = test::read_body(resp).await;
        assert_eq!(body, Bytes::from("<h1>TEST AUTH</h1>"));
    }

    #[tokio::test]
    async fn test_get_view_auth_unauthorized() {
        dotenv::dotenv().ok();

        let app_state = AppState::for_test().await;

        let mut app = test::init_service(
            App::new()
                .app_data(Data::new(app_state.clone()))
                .app_data(Data::new(AuthenticatedAdminMiddleware::new(
                    "kuadrado-admin-auth",
                )))
                .app_data(Data::new(get_views_manager()))
                .service(get_view),
        )
        .await;

        let req = test::TestRequest::with_uri("/test-view-auth").to_request();
        let resp = test::call_service(&mut app, req).await;
        assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
    }

    #[tokio::test]
    async fn test_get_view_not_found() {
        dotenv::dotenv().ok();

        let app_state = AppState::for_test().await;

        let mut app = test::init_service(
            App::new()
                .app_data(Data::new(app_state.clone()))
                .app_data(Data::new(AuthenticatedAdminMiddleware::new(
                    "kuadrado-admin-auth",
                )))
                .app_data(Data::new(get_views_manager()))
                .service(get_view),
        )
        .await;

        let req = test::TestRequest::with_uri("/whatever").to_request();
        let resp = test::call_service(&mut app, req).await;
        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
    }
}