diff --git a/migrations/2020-10-30-150242_handler-config/down.sql b/migrations/2020-10-30-150242_handler-config/down.sql new file mode 100644 index 0000000..291a97c --- /dev/null +++ b/migrations/2020-10-30-150242_handler-config/down.sql @@ -0,0 +1 @@ +-- This file should undo anything in `up.sql` \ No newline at end of file diff --git a/migrations/2020-10-30-150242_handler-config/up.sql b/migrations/2020-10-30-150242_handler-config/up.sql new file mode 100644 index 0000000..8aac745 --- /dev/null +++ b/migrations/2020-10-30-150242_handler-config/up.sql @@ -0,0 +1,16 @@ +CREATE TABLE IF NOT EXISTS handler_config + ( key_name VARCHAR NOT NULL + , value_contents VARCHAR NOT NULL + , handler_id UUID NOT NULL + , created_at TIMESTAMP NOT NULL DEFAULT NOW() + , updated_at TIMESTAMP NOT NULL DEFAULT NOW() + , PRIMARY KEY (key_name, handler_id) + , CONSTRAINT fk_handler_id + FOREIGN KEY (handler_id) + REFERENCES handlers(id) + ); + +CREATE TRIGGER set_timestamp_handler_config + BEFORE UPDATE ON handler_config + FOR EACH ROW + EXECUTE PROCEDURE trigger_set_timestamp(); diff --git a/src/api/handler.rs b/src/api/handler.rs index 9501987..cd780ca 100644 --- a/src/api/handler.rs +++ b/src/api/handler.rs @@ -3,6 +3,7 @@ use crate::{models, schema, MainDatabase}; use chrono::prelude::*; use diesel::prelude::*; use rocket_contrib::{json::Json, uuid::Uuid}; +use schema::handlers::dsl::*; use serde::Deserialize; #[derive(Debug, Eq, PartialEq, Deserialize)] @@ -38,8 +39,6 @@ pub fn create( #[instrument(skip(conn), err)] #[get("/handler")] pub fn list(user: models::User, conn: MainDatabase) -> Result>> { - use schema::handlers::dsl::*; - Ok(Json( handlers .filter(user_id.eq(user.id)) @@ -51,7 +50,6 @@ pub fn list(user: models::User, conn: MainDatabase) -> Result")] pub fn get(user: models::User, uuid: Uuid, conn: MainDatabase) -> Result> { - use schema::handlers::dsl::*; let uuid = uuid.into_inner(); let handler = handlers .find(uuid) @@ -68,7 +66,6 @@ pub fn get(user: models::User, uuid: Uuid, conn: MainDatabase) -> Result")] pub fn delete(user: models::User, uuid: Uuid, conn: MainDatabase) -> Result { - use schema::handlers::dsl::*; let uuid = uuid.into_inner(); let hdl: models::Handler = handlers @@ -86,3 +83,78 @@ pub fn delete(user: models::User, uuid: Uuid, conn: MainDatabase) -> Result { Ok(()) } + +#[instrument(skip(conn), err)] +#[get("/handler//config")] +pub fn get_config( + user: models::User, + handler_id_str: Uuid, + conn: MainDatabase, +) -> Result>> { + let uuid = handler_id_str.into_inner(); + { + use schema::handler_config::dsl::{handler_config, handler_id}; + + let handler = handlers + .find(uuid) + .get_result::(&*conn) + .map_err(Error::Database)?; + + if handler.user_id != user.id { + return Err(Error::LackPermissions); + } + + let config = handler_config + .filter(handler_id.eq(handler.id)) + .load::(&*conn) + .map_err(Error::Database)?; + + Ok(Json(config)) + } +} + +#[derive(Deserialize, Debug, Clone)] +pub struct Cfg { + pub key: String, + pub value: String, +} + +#[instrument(skip(conn, cfg), err)] +#[post("/handler//config", format = "json", data = "")] +pub fn create_config( + user: models::User, + handler_id_str: Uuid, + cfg: Json>, + conn: MainDatabase, +) -> Result { + use schema::handler_config::table; + let uuid = handler_id_str.into_inner(); + + let handler = handlers + .find(uuid) + .get_result::(&*conn) + .map_err(Error::Database)?; + + if handler.user_id != user.id { + return Err(Error::LackPermissions); + } + + let cfg: Vec = cfg + .into_inner() + .iter() + .map(|kv| models::NewHandlerConfig { + key_name: kv.key.clone(), + value_contents: kv.value.clone(), + handler_id: handler.id.clone(), + }) + .collect(); + + diesel::insert_into(table) + .values(&cfg) + .get_result::(&*conn) + .map_err(Error::Database)?; + + let _ = cfg.iter().inspect(|kv| info!(name = kv.key_name.as_str(), "config created")); + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 3868979..9e74af1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,6 +44,8 @@ fn main() -> Result<()> { api::handler::list, api::handler::get, api::handler::delete, + api::handler::get_config, + api::handler::create_config, api::user::whoami, api::user::get, api::token::list, diff --git a/src/models.rs b/src/models.rs index ea1081f..5c990d8 100644 --- a/src/models.rs +++ b/src/models.rs @@ -1,4 +1,4 @@ -use crate::schema::{gitea_tokens, handlers, tokens, users}; +use crate::schema::*; use chrono::NaiveDateTime; use serde::Serialize; use std::fmt; @@ -85,3 +85,20 @@ pub struct Handler { pub updated_at: NaiveDateTime, pub deleted_at: Option, } + +#[derive(Insertable)] +#[table_name = "handler_config"] +pub struct NewHandlerConfig { + pub key_name: String, + pub value_contents: String, + pub handler_id: Uuid, +} + +#[derive(Queryable, Debug, Clone, Serialize)] +pub struct HandlerConfig { + pub key_name: String, + pub value_contents: String, + pub handler_id: Uuid, + pub created_at: NaiveDateTime, + pub updated_at: NaiveDateTime, +} diff --git a/src/schema.rs b/src/schema.rs index 61b1056..8a669fd 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -9,6 +9,16 @@ table! { } } +table! { + handler_config (key_name, handler_id) { + key_name -> Varchar, + value_contents -> Varchar, + handler_id -> Uuid, + created_at -> Timestamp, + updated_at -> Timestamp, + } +} + table! { handlers (id) { id -> Uuid, @@ -45,8 +55,11 @@ table! { } } +joinable!(handler_config -> handlers (handler_id)); + allow_tables_to_appear_in_same_query!( gitea_tokens, + handler_config, handlers, tokens, users,