2021-05-01 12:39:40 +02:00
|
|
|
use actix_web::{delete, get, post, web, HttpResponse, Responder};
|
|
|
|
use serde::{Deserialize, Serialize};
|
2021-05-02 03:07:08 +02:00
|
|
|
use std::time::SystemTime;
|
2021-05-01 12:39:40 +02:00
|
|
|
|
2021-05-02 03:07:08 +02:00
|
|
|
use crate::note::{generate_id, Note, NoteInfo, NotePublic};
|
2021-12-22 13:10:08 +01:00
|
|
|
use crate::size::LIMIT;
|
2021-05-02 12:32:03 +02:00
|
|
|
use crate::store;
|
2021-05-02 03:07:08 +02:00
|
|
|
|
2021-12-22 14:46:06 +01:00
|
|
|
pub fn now() -> u32 {
|
2021-05-02 03:07:08 +02:00
|
|
|
SystemTime::now()
|
|
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
|
|
.unwrap()
|
2021-12-22 14:46:06 +01:00
|
|
|
.as_secs() as u32
|
2021-05-02 03:07:08 +02:00
|
|
|
}
|
2021-05-01 12:39:40 +02:00
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
struct NotePath {
|
|
|
|
id: String,
|
|
|
|
}
|
|
|
|
|
2021-12-22 13:10:08 +01:00
|
|
|
#[get("/{id}")]
|
2021-05-01 12:39:40 +02:00
|
|
|
async fn one(path: web::Path<NotePath>) -> impl Responder {
|
|
|
|
let p = path.into_inner();
|
2021-05-02 12:32:03 +02:00
|
|
|
let note = store::get(&p.id);
|
2021-05-01 12:39:40 +02:00
|
|
|
match note {
|
|
|
|
None => return HttpResponse::NotFound().finish(),
|
2021-05-03 12:21:51 +02:00
|
|
|
Some(_) => return HttpResponse::Ok().json(NoteInfo {}),
|
2021-05-01 12:39:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
struct CreateResponse {
|
|
|
|
id: String,
|
|
|
|
}
|
|
|
|
|
2021-12-22 13:10:08 +01:00
|
|
|
#[post("/")]
|
2021-05-01 12:39:40 +02:00
|
|
|
async fn create(note: web::Json<Note>) -> impl Responder {
|
2021-05-02 03:07:08 +02:00
|
|
|
let mut n = note.into_inner();
|
2021-05-01 12:39:40 +02:00
|
|
|
let id = generate_id();
|
2021-05-02 03:07:08 +02:00
|
|
|
let bad_req = HttpResponse::BadRequest().finish();
|
|
|
|
if n.views == None && n.expiration == None {
|
|
|
|
return bad_req;
|
|
|
|
}
|
|
|
|
match n.views {
|
|
|
|
Some(v) => {
|
|
|
|
if v > 100 {
|
|
|
|
return bad_req;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
match n.expiration {
|
|
|
|
Some(e) => {
|
|
|
|
if e > 360 {
|
|
|
|
return bad_req;
|
|
|
|
}
|
2021-05-08 21:47:08 +02:00
|
|
|
let expiration = now() + (e * 60);
|
|
|
|
n.expiration = Some(expiration);
|
2021-05-02 03:07:08 +02:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2021-05-02 12:32:03 +02:00
|
|
|
store::set(&id.clone(), &n.clone());
|
2021-05-01 12:39:40 +02:00
|
|
|
return HttpResponse::Ok().json(CreateResponse { id: id });
|
|
|
|
}
|
|
|
|
|
2021-12-22 13:10:08 +01:00
|
|
|
#[delete("/{id}")]
|
2021-05-01 12:39:40 +02:00
|
|
|
async fn delete(path: web::Path<NotePath>) -> impl Responder {
|
|
|
|
let p = path.into_inner();
|
2021-05-02 12:32:03 +02:00
|
|
|
let note = store::get(&p.id);
|
2021-05-01 12:39:40 +02:00
|
|
|
match note {
|
|
|
|
None => return HttpResponse::NotFound().finish(),
|
|
|
|
Some(note) => {
|
|
|
|
let mut changed = note.clone();
|
|
|
|
if changed.views == None && changed.expiration == None {
|
|
|
|
return HttpResponse::BadRequest().finish();
|
2021-05-02 03:07:08 +02:00
|
|
|
}
|
|
|
|
match changed.views {
|
|
|
|
Some(v) => {
|
|
|
|
changed.views = Some(v - 1);
|
|
|
|
let id = p.id.clone();
|
|
|
|
if v <= 1 {
|
2021-05-02 12:32:03 +02:00
|
|
|
store::del(&id);
|
2021-05-02 03:07:08 +02:00
|
|
|
} else {
|
2021-05-02 12:32:03 +02:00
|
|
|
store::set(&id, &changed.clone());
|
2021-05-02 03:07:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
2021-12-22 14:46:06 +01:00
|
|
|
|
|
|
|
let n = now();
|
2021-05-02 03:07:08 +02:00
|
|
|
match changed.expiration {
|
|
|
|
Some(e) => {
|
2021-12-22 14:46:06 +01:00
|
|
|
if e < n {
|
|
|
|
store::del(&p.id.clone());
|
2021-05-02 03:07:08 +02:00
|
|
|
return HttpResponse::BadRequest().finish();
|
2021-05-01 12:39:40 +02:00
|
|
|
}
|
|
|
|
}
|
2021-05-02 03:07:08 +02:00
|
|
|
_ => {}
|
2021-05-01 12:39:40 +02:00
|
|
|
}
|
2021-05-02 03:07:08 +02:00
|
|
|
return HttpResponse::Ok().json(NotePublic {
|
|
|
|
contents: changed.contents,
|
2021-12-21 00:15:04 +01:00
|
|
|
meta: changed.meta,
|
2021-05-02 03:07:08 +02:00
|
|
|
});
|
2021-05-01 12:39:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-22 13:10:08 +01:00
|
|
|
#[derive(Serialize, Deserialize)]
|
|
|
|
struct Status {
|
2021-12-22 15:20:30 +01:00
|
|
|
version: String,
|
2021-12-22 13:10:08 +01:00
|
|
|
max_size: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[get("/status")]
|
|
|
|
async fn status() -> impl Responder {
|
|
|
|
println!("Limit: {}", *LIMIT);
|
2021-12-22 15:20:30 +01:00
|
|
|
return HttpResponse::Ok().json(Status {
|
|
|
|
version: option_env!("CARGO_PKG_VERSION")
|
|
|
|
.unwrap_or("Unknown")
|
|
|
|
.to_string(),
|
|
|
|
max_size: *LIMIT,
|
|
|
|
});
|
2021-12-22 13:10:08 +01:00
|
|
|
}
|
|
|
|
|
2021-05-01 12:39:40 +02:00
|
|
|
pub fn init(cfg: &mut web::ServiceConfig) {
|
2021-05-02 14:02:40 +02:00
|
|
|
cfg.service(
|
|
|
|
web::scope("/api")
|
2021-12-22 13:10:08 +01:00
|
|
|
.service(
|
|
|
|
web::scope("/notes")
|
|
|
|
.service(one)
|
|
|
|
.service(create)
|
|
|
|
.service(delete)
|
|
|
|
.service(status),
|
|
|
|
)
|
|
|
|
.service(status),
|
2021-05-02 14:02:40 +02:00
|
|
|
);
|
2021-05-01 12:39:40 +02:00
|
|
|
}
|