diff --git a/Cargo.lock b/Cargo.lock index 1aa2eb1..8671f2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,19 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ammonia" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -483,6 +496,15 @@ name = "fuchsia-zircon-sys" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "futf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "futures" version = "0.1.21" @@ -528,6 +550,19 @@ name = "hex" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "html5ever" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "httparse" version = "1.2.4" @@ -694,6 +729,31 @@ dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "maplit" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "markup5ever" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.43 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "matches" version = "0.1.6" @@ -800,6 +860,14 @@ dependencies = [ "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nodrop" version = "0.1.12" @@ -956,6 +1024,7 @@ version = "0.1.0" dependencies = [ "activitypub 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "activitystreams-types 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -988,6 +1057,11 @@ dependencies = [ "vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "proc-macro2" version = "0.2.3" @@ -1349,6 +1423,37 @@ name = "state" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "string_cache" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "string_cache_codegen" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "string_cache_shared" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.7.0" @@ -1423,6 +1528,16 @@ dependencies = [ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "tendril" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tera" version = "0.10.10" @@ -1750,6 +1865,11 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "utf-8" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1834,6 +1954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum activitystreams-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "14806b3c88c439e1670fdc99d9b18bf1a47d4fa7152fe8a3bd7da08b6ced3e95" "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum ammonia 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd4c682378117e4186a492b2252b9537990e1617f44aed9788b9a1149de45477" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum array_tool 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8f8cb5d814eb646a863c4f24978cff2880c4be96ad8cde2c0f0678732902e271" @@ -1882,6 +2003,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +"checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b" "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" @@ -1889,6 +2011,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +"checksum html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b04478cf718862650a0bf66acaf8f2f8c906fbc703f35c916c1f4211b069a364" "checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37" "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" @@ -1908,6 +2031,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" +"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" +"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" @@ -1919,6 +2045,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "9044faf1413a1057267be51b5afba8eb1090bd2231c693664aa1db716fe1eae0" +"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "checksum num-integer 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d26da319fb45674985c78f1d1caf99aa4941f785d384a2ae36d0740bc3e2fe" "checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364" @@ -1940,6 +2067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" "checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" "checksum pq-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfb5e575ef93a1b7b2a381d47ba7c5d4e4f73bff37cee932195de769aad9a54" +"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" "checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" @@ -1981,6 +2109,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c" "checksum state 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5562ac59585fe3d9a1ccf6b4e298ce773f5063db80d59f783776b410c1714c2" +"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423" +"checksum string_cache_codegen 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35293b05cf1494e8ddd042a7df6756bf18d07f42d234f32e71dce8a7aabb0191" +"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5" @@ -1990,6 +2121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syntex_fmt_macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5386bdc48758d136af85b3880548e1f3a9fad8d7dc2b38bdb48c36a9cdefc0" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +"checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" "checksum tera 0.10.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d706c3bec8103f346fc7b8a3887a2ff4195cf704bdbc6307069f32ea8a2b3af5" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" @@ -2027,6 +2159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" "checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7" +"checksum utf-8 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1262dfab4c30d5cb7c07026be00ee343a6cf5027fdc0104a9160f354e5db75c" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" "checksum vcpkg 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7ed0f6789c8a85ca41bbc1c9d175422116a9869bd1cf31bb08e1493ecce60380" diff --git a/Cargo.toml b/Cargo.toml index c463bff..9f90b6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ serde = "*" serde_derive = "1.0" serde_json = "1.0" url = "1.7" +ammonia = "1.1.0" [dependencies.chrono] features = ["serde"] diff --git a/src/activity_pub/inbox.rs b/src/activity_pub/inbox.rs index 294fd1f..4560e7b7 100644 --- a/src/activity_pub/inbox.rs +++ b/src/activity_pub/inbox.rs @@ -22,6 +22,7 @@ use models::{ reshares::*, users::User }; +use safe_string::SafeString; #[derive(Fail, Debug)] enum InboxError { @@ -41,7 +42,7 @@ pub trait Inbox { blog_id: 0, // TODO slug: String::from(""), // TODO title: article.object_props.name_string().unwrap(), - content: article.object_props.content_string().unwrap(), + content: SafeString::new(&article.object_props.content_string().unwrap()), published: true, license: String::from("CC-0"), ap_url: article.object_props.url_string()? @@ -53,7 +54,7 @@ pub trait Inbox { let previous_url = note.object_props.in_reply_to.clone().unwrap().as_str().unwrap().to_string(); let previous_comment = Comment::find_by_ap_url(conn, previous_url.clone()); Comment::insert(conn, NewComment { - content: note.object_props.content_string().unwrap(), + content: SafeString::new(¬e.object_props.content_string().unwrap()), spoiler_text: note.object_props.summary_string().unwrap_or(String::from("")), ap_url: note.object_props.id_string().ok(), in_response_to_id: previous_comment.clone().map(|c| c.id), diff --git a/src/main.rs b/src/main.rs index ba8ddfe..90ecbc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,7 @@ extern crate serde_derive; #[macro_use] extern crate serde_json; extern crate url; +extern crate ammonia; use diesel::{pg::PgConnection, r2d2::{ConnectionManager, Pool}}; use dotenv::dotenv; @@ -42,6 +43,7 @@ mod models; mod schema; mod routes; mod utils; +mod safe_string; lazy_static! { pub static ref BASE_URL: String = env::var("BASE_URL") diff --git a/src/models/comments.rs b/src/models/comments.rs index 691dfc3..e763e90 100644 --- a/src/models/comments.rs +++ b/src/models/comments.rs @@ -17,11 +17,12 @@ use models::{ users::User }; use schema::comments; +use safe_string::SafeString; #[derive(Queryable, Identifiable, Serialize, Clone)] pub struct Comment { pub id: i32, - pub content: String, + pub content: SafeString, pub in_response_to_id: Option, pub post_id: i32, pub author_id: i32, @@ -34,7 +35,7 @@ pub struct Comment { #[derive(Insertable)] #[table_name = "comments"] pub struct NewComment { - pub content: String, + pub content: SafeString, pub in_response_to_id: Option, pub post_id: i32, pub author_id: i32, diff --git a/src/models/posts.rs b/src/models/posts.rs index ae24439..206e6ac 100644 --- a/src/models/posts.rs +++ b/src/models/posts.rs @@ -19,6 +19,7 @@ use models::{ users::User }; use schema::posts; +use safe_string::SafeString; #[derive(Queryable, Identifiable, Serialize)] pub struct Post { @@ -26,7 +27,7 @@ pub struct Post { pub blog_id: i32, pub slug: String, pub title: String, - pub content: String, + pub content: SafeString, pub published: bool, pub license: String, pub creation_date: NaiveDateTime, @@ -39,7 +40,7 @@ pub struct NewPost { pub blog_id: i32, pub slug: String, pub title: String, - pub content: String, + pub content: SafeString, pub published: bool, pub license: String, pub ap_url: String diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 57f5a64..86542a1 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -13,6 +13,7 @@ use models::{ }; use utils; +use safe_string::SafeString; #[get("/~/<_blog>//comment")] fn new(_blog: String, slug: String, user: User, conn: DbConn) -> Template { @@ -43,7 +44,7 @@ fn create(blog: String, slug: String, query: CommentQuery, data: Form/", rank = 4)] fn details(blog: String, slug: String, conn: DbConn, user: Option) -> Template { @@ -100,7 +101,7 @@ fn create(blog_name: String, data: Form, user: User, conn: DbConn) blog_id: blog.id, slug: slug.to_string(), title: form.title.to_string(), - content: content, + content: SafeString::new(&content), published: true, license: form.license.to_string(), ap_url: "".to_string() diff --git a/src/safe_string.rs b/src/safe_string.rs new file mode 100644 index 0000000..3b17a6e --- /dev/null +++ b/src/safe_string.rs @@ -0,0 +1,103 @@ +use ammonia::clean; +use serde::{self, Serialize, Deserialize, + Serializer, Deserializer, de::Visitor}; +use std::{fmt::{self, Display}, + borrow::Borrow, io::Write, + ops::Deref}; +use diesel::{self, deserialize::Queryable, + types::ToSql, + sql_types::Text, + serialize::{self, Output}}; + +#[derive(Debug,Clone,AsExpression,FromSqlRow)] +#[sql_type = "Text"] +pub struct SafeString{ + value: String, +} + +impl SafeString{ +pub fn new(value: &str) -> Self { + SafeString{ + value: clean(&value), + } + } + pub fn set(&mut self, value: &str) { + self.value = clean(value); + } + pub fn get(&self) -> &String { + &self.value + } +} + +impl Serialize for SafeString { + fn serialize(&self, serializer: S) -> Result + where S: Serializer, { + serializer.serialize_str(&self.value) + } +} + +struct SafeStringVisitor; + +impl<'de> Visitor<'de> for SafeStringVisitor { + type Value = SafeString; + + fn expecting(&self, formatter:&mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string") + } + + fn visit_str(self, value: &str) -> Result + where E: serde::de::Error{ + Ok(SafeString::new(value)) + } +} + +impl<'de> Deserialize<'de> for SafeString { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de>, { + Ok( + deserializer.deserialize_string(SafeStringVisitor)? + ) + } +} + +impl Queryable for SafeString { + type Row = String; + fn build(value: Self::Row) -> Self { + SafeString::new(&value) + } +} + +impl ToSql for SafeString +where + DB: diesel::backend::Backend, + str: ToSql, { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + str::to_sql(&self.value, out) + } +} + + +impl Borrow for SafeString { + fn borrow(&self) -> &str { + &self.value + } +} + +impl Display for SafeString { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.value) + } +} + +impl Deref for SafeString { + type Target = str; + fn deref(&self) -> &str { + &self.value + } +} + +impl AsRef for SafeString { + fn as_ref(&self) -> &str { + &self.value + } +} diff --git a/templates/base.tera b/templates/base.html.tera similarity index 100% rename from templates/base.tera rename to templates/base.html.tera diff --git a/templates/blogs/details.tera b/templates/blogs/details.html.tera similarity index 100% rename from templates/blogs/details.tera rename to templates/blogs/details.html.tera diff --git a/templates/blogs/new.tera b/templates/blogs/new.html.tera similarity index 100% rename from templates/blogs/new.tera rename to templates/blogs/new.html.tera diff --git a/templates/comments/new.tera b/templates/comments/new.html.tera similarity index 100% rename from templates/comments/new.tera rename to templates/comments/new.html.tera diff --git a/templates/errors/500.tera b/templates/errors/500.html.tera similarity index 100% rename from templates/errors/500.tera rename to templates/errors/500.html.tera diff --git a/templates/errors/base.tera b/templates/errors/base.html.tera similarity index 100% rename from templates/errors/base.tera rename to templates/errors/base.html.tera diff --git a/templates/instance/configure.tera b/templates/instance/configure.html.tera similarity index 100% rename from templates/instance/configure.tera rename to templates/instance/configure.html.tera diff --git a/templates/instance/index.tera b/templates/instance/index.html.tera similarity index 100% rename from templates/instance/index.tera rename to templates/instance/index.html.tera diff --git a/templates/macros.tera b/templates/macros.html.tera similarity index 100% rename from templates/macros.tera rename to templates/macros.html.tera diff --git a/templates/notifications/index.tera b/templates/notifications/index.html.tera similarity index 100% rename from templates/notifications/index.tera rename to templates/notifications/index.html.tera diff --git a/templates/posts/details.tera b/templates/posts/details.html.tera similarity index 100% rename from templates/posts/details.tera rename to templates/posts/details.html.tera diff --git a/templates/posts/new.tera b/templates/posts/new.html.tera similarity index 100% rename from templates/posts/new.tera rename to templates/posts/new.html.tera diff --git a/templates/session/login.tera b/templates/session/login.html.tera similarity index 93% rename from templates/session/login.tera rename to templates/session/login.html.tera index 1099b5e..35da145 100644 --- a/templates/session/login.tera +++ b/templates/session/login.html.tera @@ -7,7 +7,7 @@ Login {% block content %}

Login

{% if message %} -

{{ message | escape }}

+

{{ message }}

{% endif %}
diff --git a/templates/users/details.tera b/templates/users/details.html.tera similarity index 97% rename from templates/users/details.tera rename to templates/users/details.html.tera index d225a30..ca681b2 100644 --- a/templates/users/details.tera +++ b/templates/users/details.html.tera @@ -28,7 +28,7 @@
- {{ user.summary | safe }} + {{ user.summary }}
{% if recents | length != 0 %} diff --git a/templates/users/edit.tera b/templates/users/edit.html.tera similarity index 100% rename from templates/users/edit.tera rename to templates/users/edit.html.tera diff --git a/templates/users/followers.tera b/templates/users/followers.html.tera similarity index 100% rename from templates/users/followers.tera rename to templates/users/followers.html.tera diff --git a/templates/users/new.tera b/templates/users/new.html.tera similarity index 100% rename from templates/users/new.tera rename to templates/users/new.html.tera