cryptgeon/packages/backend/src/note/routes.rs

144 lines
4.2 KiB
Rust
Raw Normal View History

2022-03-01 00:53:47 +01:00
use actix_web::{delete, get, post, web, HttpResponse, Responder, Scope};
2021-05-01 12:39:40 +02:00
use serde::{Deserialize, Serialize};
2021-05-02 03:07:08 +02:00
use std::time::SystemTime;
2021-05-01 12:39:40 +02:00
2022-03-01 16:16:02 +01:00
use crate::config;
2021-05-02 03:07:08 +02:00
use crate::note::{generate_id, Note, NoteInfo, NotePublic};
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 {
2022-03-12 14:07:33 +01:00
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.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 {
2022-03-12 14:07:33 +01:00
id: String,
2021-05-01 12:39:40 +02:00
}
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 {
2022-03-12 14:07:33 +01:00
let p = path.into_inner();
let note = store::get(&p.id);
2022-03-12 14:07:33 +01:00
match note {
2023-05-23 09:38:23 +02:00
Ok(Some(n)) => HttpResponse::Ok().json(NoteInfo { meta: n.meta }),
Ok(None) => HttpResponse::NotFound().finish(),
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
2022-03-12 14:07:33 +01:00
}
2021-05-01 12:39:40 +02:00
}
#[derive(Serialize, Deserialize)]
struct CreateResponse {
2022-03-12 14:07:33 +01:00
id: String,
2021-05-01 12:39:40 +02:00
}
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 {
2022-03-12 14:07:33 +01:00
let mut n = note.into_inner();
let id = generate_id();
let bad_req = HttpResponse::BadRequest().finish();
if n.views == None && n.expiration == None {
2021-05-02 03:07:08 +02:00
return bad_req;
}
2022-03-12 14:07:33 +01:00
if !*config::ALLOW_ADVANCED {
n.views = Some(1);
n.expiration = None;
2021-05-02 03:07:08 +02:00
}
2022-03-12 14:07:33 +01:00
match n.views {
2021-05-02 03:07:08 +02:00
Some(v) => {
2022-11-12 13:42:09 +01:00
if v > *config::MAX_VIEWS || v < 1 {
2022-03-12 14:07:33 +01:00
return bad_req;
}
n.expiration = None; // views overrides expiration
2021-05-02 03:07:08 +02:00
}
_ => {}
2022-03-12 14:07:33 +01:00
}
match n.expiration {
2021-05-02 03:07:08 +02:00
Some(e) => {
2022-03-12 14:07:33 +01:00
if e > *config::MAX_EXPIRATION {
return bad_req;
}
let expiration = now() + (e * 60);
n.expiration = Some(expiration);
2021-05-01 12:39:40 +02:00
}
2021-05-02 03:07:08 +02:00
_ => {}
2021-05-01 12:39:40 +02:00
}
match store::set(&id.clone(), &n.clone()) {
Ok(_) => return HttpResponse::Ok().json(CreateResponse { id: id }),
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
}
2022-03-12 14:07:33 +01:00
}
#[delete("/{id}")]
async fn delete(path: web::Path<NotePath>) -> impl Responder {
let p = path.into_inner();
let note = store::get(&p.id);
match note {
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
Ok(None) => return HttpResponse::NotFound().finish(),
Ok(Some(note)) => {
2022-03-12 14:07:33 +01:00
let mut changed = note.clone();
if changed.views == None && changed.expiration == None {
return HttpResponse::BadRequest().finish();
}
match changed.views {
Some(v) => {
changed.views = Some(v - 1);
let id = p.id.clone();
if v <= 1 {
match store::del(&id) {
Err(e) => {
return HttpResponse::InternalServerError().body(e.to_string())
}
_ => {}
}
2022-03-12 14:07:33 +01:00
} else {
match store::set(&id, &changed.clone()) {
Err(e) => {
return HttpResponse::InternalServerError().body(e.to_string())
}
_ => {}
}
2022-03-12 14:07:33 +01:00
}
}
_ => {}
}
let n = now();
match changed.expiration {
Some(e) => {
if e < n {
match store::del(&p.id.clone()) {
Ok(_) => return HttpResponse::BadRequest().finish(),
Err(e) => {
return HttpResponse::InternalServerError().body(e.to_string())
}
}
2022-03-12 14:07:33 +01:00
}
}
_ => {}
}
return HttpResponse::Ok().json(NotePublic {
contents: changed.contents,
meta: changed.meta,
});
}
}
2021-05-01 12:39:40 +02:00
}
2021-12-22 13:10:08 +01:00
#[derive(Serialize, Deserialize)]
struct Status {
2022-03-12 14:07:33 +01:00
version: String,
max_size: usize,
2021-12-22 13:10:08 +01:00
}
pub fn init() -> Scope {
2022-03-12 14:07:33 +01:00
web::scope("/notes")
.service(one)
.service(create)
.service(delete)
2021-05-01 12:39:40 +02:00
}