commit
14d2070b62
8 changed files with 1993 additions and 0 deletions
@ -0,0 +1 @@ |
||||
/target |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@ |
||||
[package] |
||||
name = "cryptgeon" |
||||
version = "0.1.0" |
||||
authors = ["cupcakearmy <hi@nicco.io>"] |
||||
edition = "2018" |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[dependencies] |
||||
actix-web = "3" |
||||
serde = "1" |
||||
serde_json = "1" |
||||
lazy_static = "1" |
||||
ring = "0.16" |
||||
bs62 = "0.1" |
@ -0,0 +1 @@ |
||||
<div>Icons made by <a href="https://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div> |
@ -0,0 +1,19 @@ |
||||
use actix_web::{middleware, App, HttpServer}; |
||||
|
||||
#[macro_use] |
||||
extern crate lazy_static; |
||||
|
||||
mod note; |
||||
|
||||
#[actix_web::main] |
||||
async fn main() -> std::io::Result<()> { |
||||
HttpServer::new(|| { |
||||
App::new() |
||||
.wrap(middleware::Compress::default()) |
||||
.wrap(middleware::DefaultHeaders::default()) |
||||
.configure(note::init) |
||||
}) |
||||
.bind("127.0.0.1:5000")? |
||||
.run() |
||||
.await |
||||
} |
@ -0,0 +1,5 @@ |
||||
mod model; |
||||
mod routes; |
||||
|
||||
pub use model::*; |
||||
pub use routes::*; |
@ -0,0 +1,23 @@ |
||||
use bs62; |
||||
use ring::rand::SecureRandom; |
||||
use serde::{Deserialize, Serialize}; |
||||
|
||||
#[derive(Serialize, Deserialize, Clone)] |
||||
pub struct Note { |
||||
pub contents: String, |
||||
pub password: bool, |
||||
pub views: Option<u8>, |
||||
pub expiration: Option<u16>, |
||||
} |
||||
|
||||
#[derive(Serialize, Deserialize, Clone)] |
||||
pub struct PubNote { |
||||
pub password: bool, |
||||
} |
||||
|
||||
pub fn generate_id() -> String { |
||||
let mut id: [u8; 64] = [0; 64]; |
||||
let sr = ring::rand::SystemRandom::new(); |
||||
let _ = sr.fill(&mut id); |
||||
return bs62::encode_data(&id); |
||||
} |
@ -0,0 +1,97 @@ |
||||
use actix_web::{delete, get, post, web, HttpResponse, Responder}; |
||||
use serde::{Deserialize, Serialize}; |
||||
use std::collections::HashMap; |
||||
use std::sync::Mutex; |
||||
|
||||
use crate::note::{generate_id, Note, PubNote}; |
||||
|
||||
lazy_static! { |
||||
static ref RAM: Mutex<HashMap<String, Note>> = { |
||||
let mut m = HashMap::new(); |
||||
m.insert( |
||||
"test".to_string(), |
||||
Note { |
||||
contents: "some stuff".to_string(), |
||||
password: false, |
||||
views: Some(1), |
||||
expiration: Some(100), |
||||
}, |
||||
); |
||||
return Mutex::new(m); |
||||
}; |
||||
} |
||||
|
||||
#[derive(Serialize, Deserialize)] |
||||
struct NotePath { |
||||
id: String, |
||||
} |
||||
|
||||
#[get("/notes/{id}")] |
||||
async fn one(path: web::Path<NotePath>) -> impl Responder { |
||||
let ram = RAM.lock().unwrap(); |
||||
let p = path.into_inner(); |
||||
let note = ram.get(&p.id); |
||||
match note { |
||||
None => return HttpResponse::NotFound().finish(), |
||||
Some(note) => { |
||||
return HttpResponse::Ok().json(PubNote { |
||||
password: note.password, |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
#[get("/notes/")] |
||||
async fn all() -> impl Responder { |
||||
let values: Vec<Note> = RAM.lock().unwrap().values().cloned().collect(); |
||||
return HttpResponse::Ok().json(values); |
||||
} |
||||
|
||||
#[derive(Serialize, Deserialize)] |
||||
struct CreateResponse { |
||||
id: String, |
||||
} |
||||
|
||||
#[post("/notes/")] |
||||
async fn create(note: web::Json<Note>) -> impl Responder { |
||||
let n = note.into_inner(); |
||||
let id = generate_id(); |
||||
RAM.lock().unwrap().insert(id.clone(), n.clone()); |
||||
return HttpResponse::Ok().json(CreateResponse { id: id }); |
||||
} |
||||
|
||||
#[delete("/notes/{id}")] |
||||
async fn delete(path: web::Path<NotePath>) -> impl Responder { |
||||
let mut ram = RAM.lock().unwrap(); |
||||
let p = path.into_inner(); |
||||
let note = ram.get(&p.id); |
||||
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(); |
||||
} else { |
||||
match changed.views { |
||||
Some(v) => { |
||||
changed.views = Some(v - 1); |
||||
if v <= 1 { |
||||
ram.remove(&p.id); |
||||
} else { |
||||
ram.insert(p.id, changed.clone()); |
||||
} |
||||
} |
||||
_ => {} |
||||
} |
||||
return HttpResponse::Ok().json(changed); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub fn init(cfg: &mut web::ServiceConfig) { |
||||
cfg.service(create); |
||||
cfg.service(delete); |
||||
cfg.service(one); |
||||
cfg.service(all); |
||||
} |
Loading…
Reference in new issue