auto-decrypt/src/api/consent.rs

94 lines
2.8 KiB
Rust

use log::Level;
use rocket_dyn_templates::{Template, context};
use crate::{api::helpers::{execute_action, find_provider_by_name}, app_config::CONFIG, orm::{DbConn, types::RecordStates}};
use rocket::{State, form::Form};
use serde::Serialize;
use crate::orm::types::AuthMethod;
use crate::orm::structures::ProviderRecord;
// Helper function for rendering
fn render_consent(record: &ProviderRecord, msg: Option<UserMessage>) -> Template {
Template::render("consent", context! {
service: record,
message: msg
})
}
#[get("/<consent_id>", rank = 1)]
pub(crate) fn consent(consent_id: i32, db_conn: &State<DbConn>) -> Result<Template, String> {
let record = db_conn.get_record(consent_id);
if record.is_none() {
return Err("Record not found".to_string());
}
Ok(Template::render("consent", context! {
service: record.unwrap(),
}))
}
#[derive(FromForm)]
pub(crate) struct ConsentInput {
key: Option<String>,
rejected: bool,
}
#[derive(serde::Serialize)]
enum MessageType {
Warn,
Danger,
Success
}
#[derive(serde::Serialize)]
struct UserMessage {
level: MessageType,
message: String
}
#[post("/<consent_id>", data = "<consent_input>", rank = 1)]
pub(crate) async fn consent_post<'a>(
consent_id: i32,
consent_input: Form<ConsentInput>,
db_conn: &State<DbConn>,
) -> Result<Template, String> {
let mut record = db_conn
.get_record(consent_id)
.ok_or("Record not found".to_string())?;
// Determine acceptance
let accept = match record.auth_methode {
AuthMethod::Password => Some(!consent_input.rejected), // TODO: Add decryption check
_ => Some(!consent_input.rejected),
};
if accept != Some(true) {
let state = if accept == Some(false) { RecordStates::Rejected } else { RecordStates::Failed };
record = db_conn.update_provider_state(record.id, state);
let msg = if accept == Some(false) {
"The unlock request was rejected."
} else {
"The unlock request failed, wrong credentials!"
};
return Ok(render_consent(&record, Some(UserMessage {
level: MessageType::Danger,
message: msg.to_string()
})));
}
let (_, provider) = find_provider_by_name(&record.service_name)
.ok_or("Service has been deleted.".to_string())?;
let (new_state, message) = match execute_action(provider, consent_input.key.as_deref()).await {
Ok(msg) => (RecordStates::Accepted, UserMessage { level: MessageType::Success, message: msg }),
Err(err) => (RecordStates::Failed, UserMessage { level: MessageType::Danger, message: err.to_string() }),
};
println!("{:?}", message.message);
record = db_conn.update_provider_state(record.id, new_state);
Ok(render_consent(&record, Some(message)))
}