dbui-controllers 0.0.64

HTTP controllers for the dbui server
Documentation
use crate::forms::project_form::ProjectForm;
use crate::util::ctx::add_flash;

use actix_session::Session;
use actix_web::web::{Data, Form, Path};
use actix_web::{HttpRequest, HttpResponse};
use serde::Deserialize;

use dbui_core::database::conn::{ConnectionParams, DatabaseEngine};
use dbui_core::Project;

use dbui_service::AppConfig;

/// Available at `/project/new`
pub fn new_project(session: Session, cfg: Data<AppConfig>, req: HttpRequest) -> HttpResponse {
  crate::act(&session, &cfg, req, |ctx, router| {
    let p = dbui_core::Project::new("".into(), "New".into(), dbui_core::database::conn::ConnectionParams::default());
    dbui_templates::project::project_edit::edit(&ctx, router, &p, true)
  })
}

/// Available by posting to `/project/new`
pub fn create(session: Session, cfg: Data<AppConfig>, form: Option<Form<ProjectForm>>, req: HttpRequest) -> HttpResponse {
  match form {
    Some(f) => crate::redir(&session, &cfg, req, |ctx, router| {
      let p = f.as_project();
      add_flash(&session, ctx.log(), "success", &format!("Project [{}] changes saved", p.key()));
      cfg.set_project(&p)?;
      router.route("home", &[&f.key()])
    }),
    None => crate::redir(&session, &cfg, req, |ctx, router| {
      add_flash(&session, ctx.log(), "error", "Invalid form (details soon)");
      router.route("project.detail", &[&"ERROR"])
    })
  }
}

/// Available at `/project/{key}`
pub fn detail(session: Session, cfg: Data<AppConfig>, key: Path<String>, req: HttpRequest) -> HttpResponse {
  crate::act(&session, &cfg, req, |ctx, router| {
    let p = ctx.app().get_project(&key)?;
    dbui_templates::project::project_detail::detail(&ctx, router, &p)
  })
}

/// Available at `/project/{key}/edit`
pub fn edit(session: Session, cfg: Data<AppConfig>, key: Path<String>, req: HttpRequest) -> HttpResponse {
  crate::act(&session, &cfg, req, |ctx, router| {
    let p = ctx.app().get_project(&key)?;
    dbui_templates::project::project_edit::edit(&ctx, router, &p, false)
  })
}

/// Available by posting to `/project/{key}/edit`
pub fn save(session: Session, cfg: Data<AppConfig>, key: Path<String>, form: Option<Form<ProjectForm>>, req: HttpRequest) -> HttpResponse {
  match form {
    Some(f) => crate::redir(&session, &cfg, req, |ctx, router| {
      let p = encrypt_pw(f.as_project());
      add_flash(&session, ctx.log(), "success", &format!("Project [{}] changes saved", p.key()));
      let k: &str = &key;
      if p.key() != k {
        cfg.remove_project(k)?;
      }
      cfg.set_project(&p)?;
      router.route("home", &[&p.key()])
    }),
    None => crate::redir(&session, &cfg, req, |ctx, router| {
      add_flash(&session, ctx.log(), "error", "Invalid form (details soon)");
      router.route("home", &[&key])
    })
  }
}

fn encrypt_pw(p: Project) -> Project {
  match p.conn().password() {
    Some(pw) if pw.starts_with("=/=") => p,
    Some(pw) => {
      let enc = dbui_database::crypto::encrypt("dbui", pw);
      let conn = ConnectionParams::new(
        DatabaseEngine::Postgres,
        p.conn().server().into(),
        *p.conn().port(),
        p.conn().database().into(),
        p.conn().user().into(),
        Some(format!("=/={}", enc)),
        p.conn().tls()
      );
      Project::new(p.key().into(), p.name().into(), conn)
    }
    None => p
  }
}

#[derive(Debug, Deserialize)]
struct SqlRequest {
  sql: String
}