2022-11-28 16:16:33 -08:00
|
|
|
use std::collections::HashMap;
|
2022-11-27 22:03:15 -08:00
|
|
|
use std::sync::RwLock;
|
|
|
|
|
|
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
use tokio::sync::oneshot::Sender;
|
2022-12-02 22:59:13 -08:00
|
|
|
use sqlx::{SqlitePool, sqlite::SqlitePoolOptions, sqlite::SqliteConnectOptions};
|
2022-11-27 22:03:15 -08:00
|
|
|
|
|
|
|
use crate::ipc;
|
2022-11-28 16:16:33 -08:00
|
|
|
use crate::errors::*;
|
2022-11-27 22:03:15 -08:00
|
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
2022-11-28 16:16:33 -08:00
|
|
|
#[serde(rename_all = "PascalCase")]
|
|
|
|
#[serde(untagged)]
|
2022-11-27 22:03:15 -08:00
|
|
|
pub enum Credentials {
|
|
|
|
LongLived {
|
2022-11-28 16:16:33 -08:00
|
|
|
access_key_id: String,
|
|
|
|
secret_access_key: String,
|
2022-11-27 22:03:15 -08:00
|
|
|
},
|
|
|
|
ShortLived {
|
2022-11-28 16:16:33 -08:00
|
|
|
access_key_id: String,
|
|
|
|
secret_access_key: String,
|
|
|
|
token: String,
|
|
|
|
expiration: String,
|
2022-11-27 22:03:15 -08:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
2022-11-28 16:16:33 -08:00
|
|
|
pub enum SessionStatus {
|
|
|
|
Unlocked,
|
2022-11-27 22:03:15 -08:00
|
|
|
Locked,
|
|
|
|
Empty,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct AppState {
|
2022-11-28 16:16:33 -08:00
|
|
|
status: RwLock<SessionStatus>,
|
|
|
|
credentials: RwLock<Option<Credentials>>,
|
2022-11-27 22:03:15 -08:00
|
|
|
request_count: RwLock<u64>,
|
2022-11-28 16:16:33 -08:00
|
|
|
open_requests: RwLock<HashMap<u64, Sender<ipc::Approval>>>,
|
2022-12-02 22:59:13 -08:00
|
|
|
pool: SqlitePool,
|
2022-11-27 22:03:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AppState {
|
2022-12-02 22:59:13 -08:00
|
|
|
pub fn new(status: SessionStatus, creds: Option<Credentials>) -> Result<Self, sqlx::error::Error> {
|
|
|
|
let conn_opts = SqliteConnectOptions::new()
|
|
|
|
.filename("creddy.db")
|
|
|
|
.create_if_missing(true);
|
|
|
|
let pool_opts = SqlitePoolOptions::new();
|
|
|
|
|
|
|
|
let pool: SqlitePool = tauri::async_runtime::block_on(pool_opts.connect_with(conn_opts))?;
|
|
|
|
tauri::async_runtime::block_on(sqlx::migrate!().run(&pool))?;
|
|
|
|
|
|
|
|
let state = AppState {
|
2022-11-28 16:16:33 -08:00
|
|
|
status: RwLock::new(status),
|
|
|
|
credentials: RwLock::new(creds),
|
|
|
|
request_count: RwLock::new(0),
|
|
|
|
open_requests: RwLock::new(HashMap::new()),
|
2022-12-02 22:59:13 -08:00
|
|
|
pool,
|
|
|
|
};
|
|
|
|
Ok(state)
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn _load_from_db(&self) -> Result<(), sqlx::error::Error> {
|
|
|
|
let row: (i32,) = sqlx::query_as("SELECT COUNT(*) FROM credentials")
|
|
|
|
.fetch_one(&self.pool)
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
let mut status = self.status.write().unwrap();
|
|
|
|
if row.0 > 0 {
|
|
|
|
*status = SessionStatus::Locked;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*status = SessionStatus::Empty;
|
2022-11-27 22:03:15 -08:00
|
|
|
}
|
2022-12-02 22:59:13 -08:00
|
|
|
Ok(())
|
2022-11-27 22:03:15 -08:00
|
|
|
}
|
|
|
|
|
2022-11-28 16:16:33 -08:00
|
|
|
pub fn register_request(&self, chan: Sender<ipc::Approval>) -> u64 {
|
2022-11-27 22:03:15 -08:00
|
|
|
let count = {
|
2022-11-29 16:13:09 -08:00
|
|
|
let mut c = self.request_count.write().unwrap();
|
2022-11-27 22:03:15 -08:00
|
|
|
*c += 1;
|
|
|
|
c
|
|
|
|
};
|
|
|
|
|
2022-11-29 16:13:09 -08:00
|
|
|
let mut open_requests = self.open_requests.write().unwrap();
|
2022-11-28 16:16:33 -08:00
|
|
|
open_requests.insert(*count, chan);
|
|
|
|
*count
|
2022-11-27 22:03:15 -08:00
|
|
|
}
|
|
|
|
|
2022-11-28 16:16:33 -08:00
|
|
|
pub fn send_response(&self, response: ipc::RequestResponse) -> Result<(), SendResponseError> {
|
2022-11-27 22:03:15 -08:00
|
|
|
let mut open_requests = self.open_requests.write().unwrap();
|
2022-11-28 16:16:33 -08:00
|
|
|
let chan = open_requests
|
|
|
|
.remove(&response.id)
|
2022-11-27 22:03:15 -08:00
|
|
|
.ok_or(SendResponseError::NotFound)
|
|
|
|
?;
|
|
|
|
|
2022-11-28 16:16:33 -08:00
|
|
|
chan.send(response.approval)
|
2022-11-27 22:03:15 -08:00
|
|
|
.map_err(|_e| SendResponseError::Abandoned)
|
|
|
|
}
|
|
|
|
|
2022-11-29 16:13:09 -08:00
|
|
|
pub fn set_creds(&self, new_creds: Credentials) {
|
|
|
|
let mut current_creds = self.credentials.write().unwrap();
|
|
|
|
*current_creds = Some(new_creds);
|
|
|
|
let mut status = self.status.write().unwrap();
|
|
|
|
*status = SessionStatus::Unlocked;
|
|
|
|
}
|
|
|
|
|
2022-11-28 16:16:33 -08:00
|
|
|
pub fn get_creds_serialized(&self) -> String {
|
2022-11-29 16:13:09 -08:00
|
|
|
let creds_option = self.credentials.read().unwrap();
|
2022-11-28 16:16:33 -08:00
|
|
|
// fix this at some point
|
2022-11-29 16:13:09 -08:00
|
|
|
let creds = creds_option.as_ref().unwrap();
|
|
|
|
serde_json::to_string(creds).unwrap()
|
2022-11-28 16:16:33 -08:00
|
|
|
}
|
2022-11-27 22:03:15 -08:00
|
|
|
}
|