survey/src/pages/panel/campaigns/delete.rs

202 lines
5.5 KiB
Rust

// Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use actix_identity::Identity;
use serde::{Deserialize, Serialize};
use sqlx::types::Uuid;
use crate::api::v1::admin::auth::runners::{login_runner, Login, Password};
use crate::api::v1::admin::campaigns::runners;
use crate::errors::*;
//use crate::AppData;
//use crate::PAGES;
use std::cell::RefCell;
use actix_web::http::header;
use actix_web::http::header::ContentType;
use actix_web::{web, HttpResponse, Responder};
use tera::Context;
//use crate::api::v1::admin::campaigns::{runners, AddCapmaign};
use crate::AppData;
pub use super::*;
pub struct SudoDelete {
ctx: RefCell<Context>,
}
pub const SUDO_DELETE: TemplateFile =
TemplateFile::new("sudo_delete_campaign", "panel/campaigns/delete/index.html");
impl CtxError for SudoDelete {
fn with_error(&self, e: &ReadableError) -> String {
self.ctx.borrow_mut().insert(ERROR_KEY, e);
self.render()
}
}
impl SudoDelete {
pub fn new(settings: &Settings, payload: Option<CampaignDeletePayload>) -> Self {
let ctx = RefCell::new(context(settings, "Login"));
if let Some(payload) = payload {
ctx.borrow_mut().insert(PAYLOAD_KEY, &payload);
}
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(SUDO_DELETE.name, &self.ctx.borrow())
.unwrap()
}
}
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub struct CampaignDeletePayload {
pub title: String,
pub delete_url: String,
}
async fn get_title(
username: &str,
uuid: &Uuid,
data: &AppData,
) -> ServiceResult<String> {
struct Name {
name: String,
}
let campaign = sqlx::query_as!(
Name,
"SELECT name
FROM survey_campaigns
WHERE
id = $1
AND
user_id = (SELECT ID from survey_admins WHERE name = $2)",
&uuid,
&username
)
.fetch_one(&data.db)
.await?;
Ok(format!("Delete camapign \"{}\"?", campaign.name))
}
#[actix_web_codegen_const_routes::get(
path = "PAGES.panel.campaigns.delete",
wrap = "crate::pages::get_page_check_login()"
)]
pub async fn delete_campaign(
id: Identity,
path: web::Path<uuid::Uuid>,
data: AppData,
) -> PageResult<impl Responder, SudoDelete> {
let username = id.identity().unwrap();
let uuid = Uuid::parse_str(&path.to_string()).unwrap();
let title = get_title(&username, &uuid, &data)
.await
.map_err(|e| PageError::new(SudoDelete::new(&data.settings, None), e))?;
let delete_url = crate::PAGES
.panel
.campaigns
.get_delete_route(&uuid.to_string());
let payload = CampaignDeletePayload { title, delete_url };
let page = SudoDelete::new(&data.settings, Some(payload)).render();
let html = ContentType::html();
Ok(HttpResponse::Ok().content_type(html).body(page))
}
#[actix_web_codegen_const_routes::post(
path = "PAGES.panel.campaigns.delete",
wrap = "crate::pages::get_page_check_login()"
)]
pub async fn delete_campaign_submit(
id: Identity,
uuid: web::Path<uuid::Uuid>,
payload: web::Form<Password>,
data: AppData,
) -> PageResult<impl Responder, SudoDelete> {
let username = id.identity().unwrap();
let payload = payload.into_inner();
let uuid = Uuid::parse_str(&uuid.to_string()).unwrap();
let creds = Login {
login: username,
password: payload.password,
};
login_runner(&creds, &data)
.await
.map_err(|e| PageError::new(SudoDelete::new(&data.settings, None), e))?;
runners::delete(&uuid, &creds.login, &data)
.await
.map_err(|e| PageError::new(SudoDelete::new(&data.settings, None), e))?;
Ok(HttpResponse::Found()
//TODO show stats of new campaign
.insert_header((header::LOCATION, PAGES.panel.campaigns.home))
.finish())
}
pub fn services(cfg: &mut actix_web::web::ServiceConfig) {
cfg.service(delete_campaign);
cfg.service(delete_campaign_submit);
}
#[cfg(test)]
mod tests {
use actix_web::test;
use super::*;
use crate::tests::*;
use crate::*;
use actix_web::http::StatusCode;
#[actix_rt::test]
async fn new_campaign_form_works() {
const NAME: &str = "delcappageuser";
const EMAIL: &str = "delcappageuser@aaa.com";
const PASSWORD: &str = "longpassword";
const CAMPAIGN_NAME: &str = "delcappageusercamaping";
let data = get_test_data().await;
let app = get_app!(data).await;
delete_user(NAME, &data).await;
let (_, signin_resp) = register_and_signin(&data, NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let uuid =
create_new_campaign(CAMPAIGN_NAME, data.clone(), cookies.clone()).await;
let creds = Password {
password: PASSWORD.into(),
};
let new_resp = test::call_service(
&app,
post_request!(
&creds,
&PAGES.panel.campaigns.get_delete_route(&uuid.campaign_id),
FORM
)
.cookie(cookies.clone())
.to_request(),
)
.await;
assert_eq!(new_resp.status(), StatusCode::FOUND);
let headers = new_resp.headers();
assert_eq!(
headers.get(header::LOCATION).unwrap(),
PAGES.panel.campaigns.home,
);
}
}