Add support for requiring name/email, close #2

main
Elnu 2 years ago
parent bc01421c54
commit cf2779dd40

@ -18,10 +18,13 @@ ARGS:
<SITES>... Set sites where comments will be posted
OPTIONS:
-h, --help Print help information
-p, --port <PORT> Set port where HTTP requests will be received [default: 8080]
-t, --testing Run in testing mode, with in-memory database(s) and permissive CORS policy
-V, --version Print version information
-e, --email-required Require email for comment submissions
-h, --help Print help information
-n, --name-required Require name for comment submissions
-p, --port <PORT> Set port where HTTP requests will be received [default: 8080]
-t, --testing Run in testing mode, with in-memory database(s) and permissive CORS
policy
-V, --version Print version information
```
The sites must be prefixed with either `http://` or `https://`. Each site may only use one protocol, so the HTTP and HTTPS versions of each site are considered separate sites. You should redirect HTTPS to HTTP.
@ -34,6 +37,8 @@ soudan -p 8081 https://example.com https://example.org
In addition, you can add the `-t`/`--testing` flag to run Soudan in testing mode. In this mode, Soudan stores all comments in a fresh in-memory database, and **all comments will be lost once Soudan is closed.** In addition, a permissive CORS policy is used to make testing easier.
Finally, you can also add the `-n`/`--name-required` and/or `-e`/`--email-required` flags to prevent anonymous comments. Keep in mind that the JavaScript in [soudan.js](demo/soudan.js) assumes that these flags are not set, so you would need to manually add the `required` flag to the name and email `<input>` fields respectively.
### Moderation
Soudan does not have any spam filtering or moderation built in. However, going into the database manually to browse and remove comments is very easy. If you need an SQLite database browser, I'd recommend [DB Browser for SQLite](https://sqlitebrowser.org/).

@ -16,6 +16,7 @@ use clap::Parser;
struct AppState {
databases: HashMap<String, Mutex<Database>>,
arguments: Arguments,
}
#[derive(Default, Parser)]
@ -27,6 +28,10 @@ struct Arguments {
sites: Vec<String>,
#[clap(short, long, help = "Run in testing mode, with in-memory database(s) and permissive CORS policy")]
testing: bool,
#[clap(short, long, help = "Require name for comment submissions")]
name_required: bool,
#[clap(short, long, help = "Require email for comment submissions")]
email_required: bool,
}
fn get_db<'a>(
@ -96,6 +101,12 @@ async fn post_comment(
if comment.validate().is_err() {
return HttpResponse::BadRequest().reason("invalid comment field(s)").finish();
}
if comment.author.is_none() && data.arguments.name_required {
return HttpResponse::BadRequest().reason("name required").finish();
}
if comment.email.is_none() && data.arguments.email_required {
return HttpResponse::BadRequest().reason("email required").finish();
}
let origin = match request.head().headers().get("Origin") {
Some(origin) => match origin.to_str() {
Ok(origin) => origin,
@ -191,15 +202,16 @@ async fn get_page_data(url: &str) -> Result<Option<PageData>, reqwest::Error> {
#[actix_web::main]
async fn main() -> Result<(), std::io::Error> {
let args = Arguments::parse();
let arguments = Arguments::parse();
let mut databases = HashMap::new();
for domain in args.sites.iter() {
for domain in arguments.sites.iter() {
databases.insert(
domain.to_owned(),
Mutex::new(Database::new(args.testing, domain).unwrap()),
Mutex::new(Database::new(arguments.testing, domain).unwrap()),
);
}
let state = web::Data::new(AppState { databases });
let port = arguments.port;
let state = web::Data::new(AppState { databases, arguments });
HttpServer::new(move || {
App::new()
.service(get_comments)
@ -207,18 +219,18 @@ async fn main() -> Result<(), std::io::Error> {
.app_data(state.clone())
// Issue with CORS on POST requests,
// keeping permissive for now
.wrap(Cors::permissive() /* if args.testing {
.wrap(Cors::permissive() /* if arguments.testing {
Cors::permissive()
} else {
let mut cors = Cors::default()
.allowed_methods(vec!["GET", "POST"]);
for domain in args.sites.iter() {
for domain in arguments.sites.iter() {
cors = cors.allowed_origin(domain);
}
cors
} */)
})
.bind(("127.0.0.1", args.port))?
.bind(("127.0.0.1", port))?
.run()
.await
}

Loading…
Cancel
Save