aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Ashby <martin@ashbysoft.com>2022-12-29 22:49:33 +0000
committerMartin Ashby <martin@ashbysoft.com>2022-12-29 22:49:33 +0000
commit30927637f2ae8af9224eb6daeca25793a0675bca (patch)
tree9d2acb62368f1757359d6d4e66352fe5e78e9225
parent19da6ec39be9e3caa5b9e2766139684fd7bbe0a0 (diff)
downloadmfashby.net-30927637f2ae8af9224eb6daeca25793a0675bca.tar.gz
mfashby.net-30927637f2ae8af9224eb6daeca25793a0675bca.tar.bz2
mfashby.net-30927637f2ae8af9224eb6daeca25793a0675bca.tar.xz
mfashby.net-30927637f2ae8af9224eb6daeca25793a0675bca.zip
More work on comments
-rw-r--r--comments/Cargo.lock20
-rw-r--r--comments/Cargo.toml5
-rw-r--r--comments/migrations/1_capcha.sql6
-rw-r--r--comments/src/main.rs35
-rw-r--r--comments/templates/form.html3
5 files changed, 45 insertions, 24 deletions
diff --git a/comments/Cargo.lock b/comments/Cargo.lock
index 1ed266e..1f2ab0b 100644
--- a/comments/Cargo.lock
+++ b/comments/Cargo.lock
@@ -95,7 +95,6 @@ checksum = "08b108ad2665fa3f6e6a517c3d80ec3e77d224c47d605167aefaa5d7ef97fa48"
dependencies = [
"async-trait",
"axum-core",
- "axum-macros",
"bitflags",
"bytes",
"futures-util",
@@ -139,18 +138,6 @@ dependencies = [
]
[[package]]
-name = "axum-macros"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4df0fc33ada14a338b799002f7e8657711422b25d4e16afb032708d6b185621"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "base-x"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1164,6 +1151,7 @@ dependencies = [
"time",
"tokio-stream",
"url",
+ "uuid",
"webpki",
"webpki-roots",
"whoami",
@@ -1565,6 +1553,12 @@ dependencies = [
]
[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+
+[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/comments/Cargo.toml b/comments/Cargo.toml
index 61b8a46..8773580 100644
--- a/comments/Cargo.toml
+++ b/comments/Cargo.toml
@@ -7,9 +7,8 @@ edition = "2021"
[dependencies]
askama = "0.11"
-axum = { version="0.6", features = ["macros"] }
+axum = { version="0.6" }
serde = "1"
-sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "any", "postgres", "time"] }
-# time = "0.3"
+sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "any", "postgres", "time", "uuid"] }
tokio = { version = "1", features = ["full"] }
diff --git a/comments/migrations/1_capcha.sql b/comments/migrations/1_capcha.sql
new file mode 100644
index 0000000..c80a4bd
--- /dev/null
+++ b/comments/migrations/1_capcha.sql
@@ -0,0 +1,6 @@
+create table if not exists capchas(question text not null, answer text not null, id uuid not null default gen_random_uuid());
+create unique index if not exists idx_capchas_id on capchas(id);
+insert into capchas(question, answer) values ('What is 1 + 3?', '4');
+insert into capchas(question, answer) values ('If I have 3 apples and 4 pears, how many fruit do I have?', '7');
+insert into capchas(question, answer) values ('What is 3 squared?', '9');
+insert into capchas(question, answer) values ('What is the meaning of life, the universe, and everything?', '42');
diff --git a/comments/src/main.rs b/comments/src/main.rs
index 312dafa..287b89e 100644
--- a/comments/src/main.rs
+++ b/comments/src/main.rs
@@ -14,12 +14,14 @@ use axum::{
http::StatusCode,
routing::get,
Router,
- debug_handler,
};
use serde::Deserialize;
use sqlx::{
postgres::{PgPool, PgPoolOptions},
- types::time::OffsetDateTime,
+ types::{
+ time::OffsetDateTime,
+ uuid::Uuid,
+ },
};
use std::{net::SocketAddr, time::Duration};
@@ -76,13 +78,20 @@ struct UrlQuery {
#[derive(Template)]
#[template(path = "form.html")]
struct CommentForm {
- url: String
+ url: String,
+ capcha_question: String,
+ capcha_id: Uuid,
}
async fn get_form(
- Query(uq): Query<UrlQuery>,
+ State(ctx): State<Ctx>,
+ Query(uq): Query<UrlQuery>
) -> Result<String, (StatusCode, String)> {
- let c = CommentForm{url: uq.url};
+ let capcha = sqlx::query!("select id, question from capchas order by random() limit 1")
+ .fetch_one(&ctx.pool)
+ .await
+ .map_err(internal_error)?;
+ let c = CommentForm{url: uq.url, capcha_question: capcha.question, capcha_id: capcha.id};
let res = c.render().map_err(internal_error)?;
Ok(res)
}
@@ -99,8 +108,8 @@ struct Comment {
}
async fn get_comments(
- Query(uq): Query<UrlQuery>,
- State(ctx): State<Ctx>) -> Result<String, (StatusCode,String)> {
+ State(ctx): State<Ctx>,
+ Query(uq): Query<UrlQuery>) -> Result<String, (StatusCode,String)> {
let comments = sqlx::query!("select author,comment,ts from comments where url = $1", uq.url)
.fetch_all(&ctx.pool)
.await
@@ -122,12 +131,22 @@ struct PostComment {
url: String,
author: String,
comment: String,
+ capcha_id: String,
+ capcha_answer: String,
}
-#[debug_handler]
async fn post_comments(
State(ctx): State<Ctx>,
Form(post_comment): Form<PostComment>) -> Result<Redirect,(StatusCode,String)> {
+ let capcha_id: Uuid = post_comment.capcha_id.parse()
+ .map_err(|_| {(StatusCode::BAD_REQUEST, "Invalid capcha_id".to_string())})?;
+ let ans: String = sqlx::query_as!("select answer from capchas where id = $1", capcha_id)
+ .fetch_one(&ctx.pool)
+ .await
+ .map_err(internal_error)?;
+ if post_comment.capcha_answer != ans {
+ return Err((StatusCode::BAD_REQUEST, "Capcha was wrong!".to_string()));
+ }
sqlx::query!("insert into comments(url,author,comment) values($1, $2, $3)", post_comment.url, post_comment.author, post_comment.comment)
.execute(&ctx.pool)
.await
diff --git a/comments/templates/form.html b/comments/templates/form.html
index 90c065e..09fc81f 100644
--- a/comments/templates/form.html
+++ b/comments/templates/form.html
@@ -1,8 +1,11 @@
<form action="/api/comments">
<input type="hidden" name="url" value="{{ url }}"><br>
+ <input type="hidden" name="capcha_id" value="{{ capcha_id }}"><br>
<label for="author">Name:</label><br>
<input type="text" id="author" name="author"><br>
<label for="comment">Comment:</label><br>
<input type="text" id="comment" name="lname">
+ <label for="capcha">{{ capcha_question }}</label>
+ <input type="text" id="capcha" name="capcha_answer"><br>
<input type="submit" value="Submit">
</form>