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
admin_auth.rs 3.95 KiB
Newer Older
  • Learn to ignore specific revisions
  • Pierre Jarriges's avatar
    Pierre Jarriges committed
    use crate::{middleware::AuthenticatedAdminMiddleware, model::AdminAuthCredentials, AppState};
    use actix_web::{
        post,
        web::{Data, Form},
        HttpMessage, HttpRequest, HttpResponse, Responder,
    };
    
    /// Performs administrator authentication from form data
    /// If the authentication succeed, a cookie with an auth token is returned
    /// If not, 401 is returned and if an auth cookie is found it is deleted.
    #[post("/admin-auth")]
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
    pub async fn admin_authentication<'a>(
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
        app_state: Data<AppState>,
        auth_mw: Data<AuthenticatedAdminMiddleware<'a>>,
        req: HttpRequest,
        form_data: Form<AdminAuthCredentials>,
    ) -> impl Responder {
        let cookie_opt = auth_mw.exec(&app_state, &req, Some(form_data)).await;
        match cookie_opt {
            Ok(cookie) => HttpResponse::Accepted().cookie(cookie).finish(),
            Err(_) => {
                return match req.cookie(auth_mw.cookie_name) {
                    Some(c) => {
                        // Invalidate auth_cookie if auth failed in any way
                        HttpResponse::Unauthorized().del_cookie(&c).finish()
                    }
                    None => HttpResponse::Unauthorized().finish(),
                };
            }
        }
    }
    
    /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
     *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
     *  _______   ______    ______   _______   *@@
     * |__   __@ |  ____@  /  ____@ |__   __@  *@@
     *    |  @   |  @__    \_ @_       |  @    *@@
     *    |  @   |   __@     \  @_     |  @    *@@
     *    |  @   |  @___   ____\  @    |  @    *@@
     *    |__@   |______@  \______@    |__@    *@@
     *                                         *@@
     *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@
     *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@*/
    
    #[cfg(test)]
    mod test_admin_auth {
        use super::*;
        use crate::model::Administrator;
        use actix_web::{
            http::{Method, StatusCode},
            test,
            web::Data,
            App,
        };
        use futures::stream::StreamExt;
        use wither::prelude::Model;
    
        #[tokio::test]
        async fn test_admin_auth() {
            dotenv::dotenv().ok();
    
            let app_state = AppState::for_test().await;
            let admin_user = Administrator::find(&app_state.db, None, None)
                .await
                .unwrap()
                .next()
                .await
                .unwrap()
                .unwrap(); // Get the first admin user we find. At least one should exist.
    
            let password = app_state.encryption.decrypt(&admin_user.password_hash);
            let username = admin_user.username.to_owned();
    
            let mut app = test::init_service(
                App::new()
                    .app_data(Data::new(app_state.clone()))
                    .app_data(Data::new(AuthenticatedAdminMiddleware::new(
                        "kuadrado-admin-auth",
                    )))
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
                    .service(admin_authentication),
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
            )
            .await;
    
            let req = test::TestRequest::with_uri("/admin-auth")
                .method(Method::POST)
                .set_form(&AdminAuthCredentials { username, password })
                .to_request();
    
            let resp = test::call_service(&mut app, req).await;
    
            assert_eq!(resp.status(), StatusCode::ACCEPTED);
        }
    
        #[tokio::test]
        async fn test_admin_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",
                    )))
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
                    .service(admin_authentication),
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
            )
            .await;
    
            let req = test::TestRequest::with_uri("/admin-auth")
                .method(Method::POST)
                .set_form(&AdminAuthCredentials {
                    username: String::from("whatever"),
                    password: String::from("whatever"),
                })
                .to_request();
    
            let resp = test::call_service(&mut app, req).await;
    
            assert_eq!(resp.status(), StatusCode::UNAUTHORIZED);
        }
    }