) -> Result, String> {
let post = parse_post(&response[0]["data"]["children"][0]).await;
// Return landing page if this post if this Reddit deems this post
- // NSFW, but we have also disabled the display of NSFW content.
- if setting(&req, "show_nsfw") != "on" && post.nsfw {
+ // NSFW, but we have also disabled the display of NSFW content
+ // or if the instance is SFW-only.
+ if post.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}
@@ -125,9 +126,7 @@ pub async fn item(req: Request) -> Result, String> {
let query_str = req.uri().query().unwrap_or_default().to_string();
if !query_str.is_empty() {
- let query: Vec<&str> = query_str.split('&').collect::>();
-
- for param in query.into_iter() {
+ for param in query_str.split('&') {
let kv: Vec<&str> = param.split('=').collect();
if kv.len() < 2 {
// Reject invalid query parameter.
diff --git a/src/post.rs b/src/post.rs
index 4a38f4b..2f00dd1 100644
--- a/src/post.rs
+++ b/src/post.rs
@@ -57,8 +57,9 @@ pub async fn item(req: Request) -> Result, String> {
let post = parse_post(&response[0]["data"]["children"][0]).await;
// Return landing page if this post if this Reddit deems this post
- // NSFW, but we have also disabled the display of NSFW content.
- if setting(&req, "show_nsfw") != "on" && post.nsfw {
+ // NSFW, but we have also disabled the display of NSFW content
+ // or if the instance is SFW-only.
+ if post.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}
diff --git a/src/search.rs b/src/search.rs
index 0a62b06..03e0d3d 100644
--- a/src/search.rs
+++ b/src/search.rs
@@ -1,5 +1,5 @@
// CRATES
-use crate::utils::{catch_random, error, filter_posts, format_num, format_url, get_filters, param, redirect, setting, template, val, Post, Preferences};
+use crate::utils::{self, catch_random, error, filter_posts, format_num, format_url, get_filters, param, redirect, setting, template, val, Post, Preferences};
use crate::{
client::json,
subreddit::{can_access_quarantine, quarantine},
@@ -48,7 +48,12 @@ struct SearchTemplate {
// SERVICES
pub async fn find(req: Request) -> Result, String> {
- let nsfw_results = if setting(&req, "show_nsfw") == "on" { "&include_over_18=on" } else { "" };
+ // This ensures that during a search, no NSFW posts are fetched at all
+ let nsfw_results = if setting(&req, "show_nsfw") == "on" && !utils::sfw_only() {
+ "&include_over_18=on"
+ } else {
+ ""
+ };
let path = format!("{}.json?{}{}&raw_json=1", req.uri().path(), req.uri().query().unwrap_or_default(), nsfw_results);
let query = param(&path, "q").unwrap_or_default();
diff --git a/src/subreddit.rs b/src/subreddit.rs
index 242a508..750bb1e 100644
--- a/src/subreddit.rs
+++ b/src/subreddit.rs
@@ -97,8 +97,8 @@ pub async fn community(req: Request) -> Result, String> {
};
// Return landing page if this post if this is NSFW community but the user
- // has disabled the display of NSFW content.
- if setting(&req, "show_nsfw") != "on" && sub.nsfw {
+ // has disabled the display of NSFW content or if the instance is SFW-only.
+ if sub.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}
diff --git a/src/user.rs b/src/user.rs
index 2872984..2d7eef6 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -50,8 +50,9 @@ pub async fn profile(req: Request) -> Result, String> {
let user = user(&username).await.unwrap_or_default();
// Return landing page if this post if this Reddit deems this user NSFW,
- // but we have also disabled the display of NSFW content.
- if setting(&req, "show_nsfw") != "on" && user.nsfw {
+ // but we have also disabled the display of NSFW content or if the instance
+ // is SFW-only.
+ if user.nsfw && (setting(&req, "show_nsfw") != "on" || crate::utils::sfw_only()) {
return Ok(nsfw_landing(req).await.unwrap_or_default());
}
diff --git a/src/utils.rs b/src/utils.rs
index 60af11b..ab3ed0d 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -9,6 +9,7 @@ use regex::Regex;
use rust_embed::RustEmbed;
use serde_json::Value;
use std::collections::{HashMap, HashSet};
+use std::env;
use std::str::FromStr;
use time::{macros::format_description, Duration, OffsetDateTime};
use url::Url;
@@ -849,6 +850,13 @@ pub async fn error(req: Request, msg: String) -> Result, St
Ok(Response::builder().status(404).header("content-type", "text/html").body(body.into()).unwrap_or_default())
}
+/// Set the FERRIT_SFW_ONLY environment variable to anything, to enable SFW-only mode.
+/// If environment variable is set, this bool will be true. Otherwise it will be false.
+/// This variable is set by the instance operator, and as such, side-steps the user config
+pub fn sfw_only() -> bool {
+ env::var("FERRIT_SFW_ONLY").is_ok()
+}
+
/// Render the landing page for NSFW content when the user has not enabled
/// "show NSFW posts" in settings.
pub async fn nsfw_landing(req: Request) -> Result, String> {
diff --git a/templates/base.html b/templates/base.html
index b5bb01b..bd8273d 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -30,7 +30,7 @@