1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
use self::diesel::prelude::*;
use rocket::http::{ContentType, Status};
use rocket::request::Request;
use rocket::response;
use rocket::response::{Responder, Response};
use rocket_contrib::databases::diesel;
use rocket_contrib::json::{Json, JsonValue};
use super::database::AtuinDbConn;
use super::models::{NewHistory, User};
use crate::schema::history;
#[derive(Debug)]
pub struct ApiResponse {
pub json: JsonValue,
pub status: Status,
}
impl<'r> Responder<'r> for ApiResponse {
fn respond_to(self, req: &Request) -> response::Result<'r> {
Response::build_from(self.json.respond_to(req).unwrap())
.status(self.status)
.header(ContentType::JSON)
.ok()
}
}
#[get("/")]
pub const fn index() -> &'static str {
"\"Through the fathomless deeps of space swims the star turtle Great A\u{2019}Tuin, bearing on its back the four giant elephants who carry on their shoulders the mass of the Discworld.\"\n\t-- Sir Terry Pratchett"
}
#[catch(500)]
pub fn internal_error(_req: &Request) -> ApiResponse {
ApiResponse {
status: Status::InternalServerError,
json: json!({"status": "error", "message": "an internal server error has occured"}),
}
}
#[catch(400)]
pub fn bad_request(_req: &Request) -> ApiResponse {
ApiResponse {
status: Status::InternalServerError,
json: json!({"status": "error", "message": "bad request. don't do that."}),
}
}
#[derive(Deserialize)]
pub struct AddHistory {
id: String,
timestamp: i64,
data: String,
mac: String,
}
#[post("/history", data = "<add_history>")]
#[allow(
clippy::clippy::cast_sign_loss,
clippy::cast_possible_truncation,
clippy::clippy::needless_pass_by_value
)]
pub fn add_history(conn: AtuinDbConn, user: User, add_history: Json<AddHistory>) -> ApiResponse {
let secs: i64 = add_history.timestamp / 1_000_000_000;
let nanosecs: u32 = (add_history.timestamp - (secs * 1_000_000_000)) as u32;
let datetime = chrono::NaiveDateTime::from_timestamp(secs, nanosecs);
let new_history = NewHistory {
client_id: add_history.id.as_str(),
user_id: user.id,
mac: add_history.mac.as_str(),
timestamp: datetime,
data: add_history.data.as_str(),
};
match diesel::insert_into(history::table)
.values(&new_history)
.execute(&*conn)
{
Ok(_) => ApiResponse {
status: Status::Ok,
json: json!({"status": "ok", "message": "history added", "id": new_history.client_id}),
},
Err(_) => ApiResponse {
status: Status::BadRequest,
json: json!({"status": "error", "message": "failed to add history"}),
},
}
}
|