Add Gravatar email hashes
This commit is contained in:
parent
bbebe8b119
commit
82e70178d5
5 changed files with 102 additions and 12 deletions
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -589,6 +589,12 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
|
@ -648,6 +654,12 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
|
@ -971,9 +983,11 @@ name = "soudan"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"md5",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"validator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1112,6 +1126,21 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "validator"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f07b0a1390e01c0fc35ebb26b28ced33c9a3808f7f9fbe94d3cc01e233bfeed5"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
|
|
@ -10,3 +10,5 @@ actix-web = "4"
|
|||
rusqlite = "0.27.0"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
validator = "0.15.0"
|
||||
md5 = "0.7.0"
|
||||
|
|
|
@ -1,7 +1,48 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
// Master comment type that is stored in database
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Comment {
|
||||
pub author: Option<String>, // None/null is Anonymous
|
||||
pub email: Option<String>,
|
||||
pub text: String
|
||||
}
|
||||
|
||||
impl Comment {
|
||||
pub fn send(&self) -> CommentSend {
|
||||
CommentSend {
|
||||
author: self.author.clone(),
|
||||
gravatar: match self.email.clone() {
|
||||
Some(email) => Some(format!("{:x}", md5::compute(email.to_lowercase()))),
|
||||
None => None,
|
||||
},
|
||||
text: self.text.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Comment type for API responses
|
||||
#[derive(Serialize)]
|
||||
pub struct CommentSend {
|
||||
pub author: Option<String>,
|
||||
pub gravatar: Option<String>,
|
||||
pub text: String
|
||||
}
|
||||
|
||||
// Comment type received containing new comment data
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommentReceive {
|
||||
pub author: Option<String>,
|
||||
pub email: Option<String>,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
impl CommentReceive {
|
||||
pub fn to_master(&self) -> Comment {
|
||||
Comment {
|
||||
author: self.author.clone(),
|
||||
email: self.email.clone(),
|
||||
text: self.text.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rusqlite::{params, Connection, Result};
|
||||
use crate::comment::Comment;
|
||||
use crate::comment::{Comment, CommentSend};
|
||||
|
||||
pub struct Database {
|
||||
conn: Connection,
|
||||
|
@ -11,6 +11,7 @@ impl Database {
|
|||
conn.execute(
|
||||
"CREATE TABLE comment (
|
||||
id INTEGER PRIMARY KEY,
|
||||
email TEXT,
|
||||
author TEXT,
|
||||
text TEXT NOT NULL
|
||||
)",
|
||||
|
@ -21,20 +22,37 @@ impl Database {
|
|||
|
||||
pub fn get_comments(&self) -> Result<Vec<Comment>> {
|
||||
self.conn
|
||||
.prepare("SELECT author, text FROM comment")?
|
||||
.prepare("SELECT author, email, text FROM comment")?
|
||||
.query_map([], |row| {
|
||||
Ok(Comment {
|
||||
author: row.get(0)?,
|
||||
text: row.get(1)?,
|
||||
email: row.get(1)?,
|
||||
text: row.get(2)?,
|
||||
})
|
||||
})?
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_send_comments(&self) -> Result<Vec<CommentSend>> {
|
||||
self.conn
|
||||
.prepare("SELECT author, email, text FROM comment")?
|
||||
.query_map([], |row| {
|
||||
Ok(CommentSend {
|
||||
author: row.get(0)?,
|
||||
gravatar: match row.get::<usize, Option<String>>(1)? {
|
||||
Some(email) => Some(format!("{:x}", md5::compute(email.to_lowercase()))),
|
||||
None => None,
|
||||
},
|
||||
text: row.get(2)?,
|
||||
})
|
||||
})?
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn create_comment(&self, comment: &Comment) -> Result<()> {
|
||||
self.conn.execute(
|
||||
"INSERT INTO comment (author, text) VALUES (?1, ?2)",
|
||||
params![&comment.author, &comment.text],
|
||||
"INSERT INTO comment (author, email, text) VALUES (?1, ?2, ?3)",
|
||||
params![&comment.author, &comment.email, &comment.text],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -1,5 +1,5 @@
|
|||
mod comment;
|
||||
pub use comment::Comment;
|
||||
pub use comment::*;
|
||||
|
||||
mod database;
|
||||
pub use database::Database;
|
||||
|
@ -14,22 +14,22 @@ struct AppState {
|
|||
#[get("/")]
|
||||
async fn get_comments(data: web::Data<AppState>) -> impl Responder {
|
||||
let db = &data.db.lock().unwrap();
|
||||
HttpResponse::Ok().json(&db.get_comments().unwrap())
|
||||
HttpResponse::Ok().json(&db.get_send_comments().unwrap())
|
||||
}
|
||||
|
||||
#[post("/")]
|
||||
async fn post_comments(data: web::Data<AppState>, bytes: web::Bytes) -> impl Responder {
|
||||
async fn post_comment(data: web::Data<AppState>, bytes: web::Bytes) -> impl Responder {
|
||||
match String::from_utf8(bytes.to_vec()) {
|
||||
Ok(text) => {
|
||||
let db = match data.db.lock() {
|
||||
Ok(db) => db,
|
||||
Err(_) => return HttpResponse::InternalServerError(),
|
||||
};
|
||||
let comment: Comment = match serde_json::from_str(&text) {
|
||||
let comment: CommentReceive = match serde_json::from_str(&text) {
|
||||
Ok(comment) => comment,
|
||||
Err(_) => return HttpResponse::BadRequest(),
|
||||
};
|
||||
db.create_comment(&comment).unwrap();
|
||||
db.create_comment(&comment.to_master()).unwrap();
|
||||
HttpResponse::Ok()
|
||||
},
|
||||
Err(_) => HttpResponse::BadRequest().into()
|
||||
|
@ -43,7 +43,7 @@ async fn main() -> Result<(), std::io::Error> {
|
|||
HttpServer::new(move || {
|
||||
App::new()
|
||||
.service(get_comments)
|
||||
.service(post_comments)
|
||||
.service(post_comment)
|
||||
.app_data(state.clone())
|
||||
})
|
||||
.bind(("127.0.0.1", 8080))?
|
||||
|
|
Loading…
Add table
Reference in a new issue