feature/update-dependencies #6
177
Cargo.lock
generated
177
Cargo.lock
generated
@@ -209,9 +209,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "actix-rt"
|
||||
version = "2.0.2"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c88cf46527e27f66efcd5831f60b3d9c2dac795b6d255ed17791752d6c36a8ea"
|
||||
checksum = "0b4e57bc1a3915e71526d128baf4323700bd1580bc676239e2298a4c5b001f18"
|
||||
dependencies = [
|
||||
"actix-macros 0.2.0",
|
||||
"futures-core",
|
||||
@@ -381,9 +381,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
|
||||
checksum = "bedc89c5c7b5550ffb9372eb5c5ffc7f9f705cc3f4a128bd4669b9745f555093"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
@@ -411,6 +411,17 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
@@ -450,7 +461,7 @@ dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"miniz_oxide 0.4.3",
|
||||
"miniz_oxide 0.4.4",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
@@ -541,15 +552,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.6.0"
|
||||
version = "3.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9"
|
||||
checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a4bad0c5981acc24bc09e532f35160f952e35422603f0563cd7a73c2c2e65a0"
|
||||
checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@@ -580,9 +591,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.66"
|
||||
version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
|
||||
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -679,7 +690,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils 0.8.1",
|
||||
"crossbeam-utils 0.8.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -690,18 +701,17 @@ checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils 0.8.1",
|
||||
"crossbeam-utils 0.8.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.1"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
|
||||
checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"const_fn",
|
||||
"crossbeam-utils 0.8.1",
|
||||
"crossbeam-utils 0.8.3",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
@@ -720,9 +730,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.1"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -830,6 +840,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.14"
|
||||
@@ -851,7 +874,7 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide 0.4.3",
|
||||
"miniz_oxide 0.4.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -862,9 +885,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
|
||||
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
@@ -907,9 +930,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"
|
||||
checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -922,9 +945,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
|
||||
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -932,15 +955,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
|
||||
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9e59fdc009a4b3096bf94f740a0f2424c082521f20a9b08c5c07c48d90fd9b9"
|
||||
checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@@ -949,15 +972,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
|
||||
checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd"
|
||||
checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
@@ -967,24 +990,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
|
||||
checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.12"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
|
||||
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -1140,10 +1160,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.1"
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
@@ -1177,16 +1203,18 @@ dependencies = [
|
||||
"actix-cors",
|
||||
"actix-files",
|
||||
"actix-multipart",
|
||||
"actix-rt 2.0.2",
|
||||
"actix-rt 2.1.0",
|
||||
"actix-web",
|
||||
"bcrypt",
|
||||
"chrono",
|
||||
"diesel",
|
||||
"dotenv",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"hmac",
|
||||
"image",
|
||||
"jsonwebtoken",
|
||||
"log",
|
||||
"notify",
|
||||
"path-absolutize",
|
||||
"rayon",
|
||||
@@ -1432,9 +1460,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.3"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
|
||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
@@ -1461,9 +1489,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.7"
|
||||
version = "0.7.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e50ae3f04d169fcc9bde0b547d1c205219b7157e07ded9c5aff03e0637cb3ed7"
|
||||
checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
@@ -1635,9 +1663,9 @@ checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.5.2"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
checksum = "10acf907b94fc1b1a152d08ef97e7759650268cf986bf127f387e602b02c7e5a"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
@@ -1884,7 +1912,7 @@ checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
||||
dependencies = [
|
||||
"crossbeam-channel 0.5.0",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils 0.8.1",
|
||||
"crossbeam-utils 0.8.3",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
@@ -2043,9 +2071,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.9.3"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4b312c3731e3fe78a185e6b9b911a7aa715b8e31cce117975219aab2acf285d"
|
||||
checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -2198,19 +2226,28 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.23"
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1"
|
||||
checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2242,7 +2279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437"
|
||||
dependencies = [
|
||||
"jpeg-decoder",
|
||||
"miniz_oxide 0.4.3",
|
||||
"miniz_oxide 0.4.4",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
@@ -2338,7 +2375,7 @@ checksum = "e8190d04c665ea9e6b6a0dc45523ade572c088d2e6566244c1122671dbf4ae3a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libc",
|
||||
"mio 0.7.7",
|
||||
"mio 0.7.9",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"pin-project-lite 0.2.4",
|
||||
@@ -2363,9 +2400,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.23"
|
||||
version = "0.1.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d40a22fd029e33300d8d89a5cc8ffce18bb7c587662f54629e94c9de5487f3"
|
||||
checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"log",
|
||||
@@ -2384,11 +2421,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-futures"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"pin-project 0.4.27",
|
||||
"pin-project 1.0.5",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@@ -2501,9 +2538,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.2.0"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
|
||||
checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
|
||||
@@ -29,3 +29,5 @@ rayon = "1.3"
|
||||
notify = "4.0"
|
||||
tokio = "1"
|
||||
path-absolutize = "3.0.6"
|
||||
log="0.4"
|
||||
env_logger="0.8"
|
||||
|
||||
@@ -11,4 +11,5 @@ They should be defined where the binary is located or above it in an `.env` file
|
||||
- `THUMBNAILS` is a path where generated thumbnails should be stored
|
||||
- `BIND_URL` is the url and port to bind to (typically your own IP address)
|
||||
- `SECRET_KEY` is the *hopefully* random string to sign Tokens with
|
||||
- `RUST_LOG` is one of `off, error, warn, info, debug, trace`, from least to most noisy [error is default]
|
||||
|
||||
|
||||
44
src/auth.rs
Normal file
44
src/auth.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use actix_web::web::{HttpResponse, Json};
|
||||
use actix_web::{post, Responder};
|
||||
use chrono::{Duration, Utc};
|
||||
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||
use log::debug;
|
||||
|
||||
use crate::data::LoginRequest;
|
||||
use crate::data::{secret_key, Claims, CreateAccountRequest, Token};
|
||||
use crate::database::{create_user, get_user, user_exists};
|
||||
|
||||
#[post("/register")]
|
||||
async fn register(user: Json<CreateAccountRequest>) -> impl Responder {
|
||||
if !user.username.is_empty() && user.password.len() > 5 && user.password == user.confirmation {
|
||||
if user_exists(&user.username) {
|
||||
HttpResponse::BadRequest()
|
||||
} else if let Some(_user) = create_user(&user.username, &user.password) {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::InternalServerError()
|
||||
}
|
||||
} else {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/login")]
|
||||
async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
||||
debug!("Logging in: {}", creds.username);
|
||||
if let Some(user) = get_user(&creds.username, &creds.password) {
|
||||
let claims = Claims {
|
||||
sub: user.id.to_string(),
|
||||
exp: (Utc::now() + Duration::days(5)).timestamp(),
|
||||
};
|
||||
let token = encode(
|
||||
&Header::default(),
|
||||
&claims,
|
||||
&EncodingKey::from_secret(secret_key().as_bytes()),
|
||||
)
|
||||
.unwrap();
|
||||
HttpResponse::Ok().json(Token { token: &token })
|
||||
} else {
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use log::error;
|
||||
|
||||
use actix_web::error::ErrorUnauthorized;
|
||||
use actix_web::{dev, http::header, Error, FromRequest, HttpRequest};
|
||||
use futures::future::{err, ok, Ready};
|
||||
@@ -11,15 +13,19 @@ pub struct Token<'a> {
|
||||
pub token: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Claims {
|
||||
pub sub: String,
|
||||
pub exp: i64,
|
||||
}
|
||||
|
||||
pub fn secret_key() -> String {
|
||||
if cfg!(test) {
|
||||
String::from("test_key")
|
||||
} else {
|
||||
dotenv::var("SECRET_KEY").expect("SECRET_KEY env not set!")
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Claims {
|
||||
type Err = jsonwebtoken::errors::Error;
|
||||
@@ -34,7 +40,7 @@ impl FromStr for Claims {
|
||||
) {
|
||||
Ok(data) => Ok(data.claims),
|
||||
Err(other) => {
|
||||
println!("DecodeError: {}", other);
|
||||
error!("DecodeError: {}", other);
|
||||
Err(other)
|
||||
}
|
||||
}
|
||||
@@ -85,3 +91,39 @@ pub struct CreateAccountRequest {
|
||||
pub struct AddFavoriteRequest {
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Claims;
|
||||
use jsonwebtoken::errors::ErrorKind;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_token_from_claims() {
|
||||
let claims = Claims {
|
||||
exp: 16136164790, // 2481-ish
|
||||
sub: String::from("9"),
|
||||
};
|
||||
|
||||
let c = Claims::from_str(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5IiwiZXhwIjoxNjEzNjE2NDc5MH0.9wwK4l8vhvq55YoueEljMbN_5uVTaAsGLLRPr0AuymE")
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(claims.sub, c.sub);
|
||||
assert_eq!(claims.exp, c.exp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expired_token() {
|
||||
let err = Claims::from_str(
|
||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5IiwiZXhwIjoxNn0.eZnfaNfiD54VMbphIqeBICeG9SzAtwNXntLwtTBihjY");
|
||||
|
||||
match err.unwrap_err().into_kind() {
|
||||
ErrorKind::ExpiredSignature => assert!(true),
|
||||
kind => {
|
||||
println!("Unexpected error: {:?}", kind);
|
||||
assert!(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
103
src/main.rs
103
src/main.rs
@@ -2,74 +2,40 @@
|
||||
extern crate diesel;
|
||||
extern crate rayon;
|
||||
|
||||
use crate::auth::login;
|
||||
use futures::stream::StreamExt;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc};
|
||||
use std::sync::mpsc::channel;
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix::{Actor, Addr};
|
||||
use actix_files::NamedFile;
|
||||
use actix_multipart as mp;
|
||||
use actix_web::{App, get, HttpServer, post, Responder, web};
|
||||
use actix_web::web::{HttpRequest, HttpResponse, Json};
|
||||
use chrono::{Duration, Utc};
|
||||
use futures::stream::StreamExt;
|
||||
use jsonwebtoken::{encode, EncodingKey, Header};
|
||||
use notify::{DebouncedEvent, RecursiveMode, watcher, Watcher};
|
||||
use actix_web::{get, post, web, App, HttpServer, Responder};
|
||||
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
|
||||
use rayon::prelude::*;
|
||||
use serde::Serialize;
|
||||
|
||||
use data::{AddFavoriteRequest, LoginRequest, ThumbnailRequest};
|
||||
use data::{AddFavoriteRequest, ThumbnailRequest};
|
||||
use log::{debug, error, info};
|
||||
|
||||
use crate::data::{Claims, CreateAccountRequest, secret_key, Token};
|
||||
use crate::database::{add_favorite, create_user, get_favorites, get_user, user_exists};
|
||||
use crate::data::Claims;
|
||||
use crate::database::{add_favorite, get_favorites};
|
||||
use crate::files::{is_valid_path, list_files};
|
||||
use crate::video::*;
|
||||
|
||||
mod auth;
|
||||
mod data;
|
||||
mod database;
|
||||
mod files;
|
||||
mod video;
|
||||
|
||||
#[post("/register")]
|
||||
async fn register(user: Json<CreateAccountRequest>) -> impl Responder {
|
||||
if !user.username.is_empty() && user.password.len() > 5 && user.password == user.confirmation {
|
||||
if user_exists(&user.username) {
|
||||
HttpResponse::BadRequest()
|
||||
} else if let Some(_user) = create_user(&user.username, &user.password) {
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
HttpResponse::InternalServerError()
|
||||
}
|
||||
} else {
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/login")]
|
||||
async fn login(creds: Json<LoginRequest>) -> impl Responder {
|
||||
println!("Logging in: {}", creds.username);
|
||||
if let Some(user) = get_user(&creds.username, &creds.password) {
|
||||
let claims = Claims {
|
||||
sub: user.id.to_string(),
|
||||
exp: (Utc::now() + Duration::days(5)).timestamp(),
|
||||
};
|
||||
let token = encode(
|
||||
&Header::default(),
|
||||
&claims,
|
||||
&EncodingKey::from_secret(secret_key().as_bytes()),
|
||||
)
|
||||
.unwrap();
|
||||
HttpResponse::Ok().json(Token { token: &token })
|
||||
} else {
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[post("/photos")]
|
||||
async fn list_photos(_claims: Claims, req: Json<ThumbnailRequest>) -> impl Responder {
|
||||
println!("{}", req.path);
|
||||
info!("{}", req.path);
|
||||
|
||||
let path = &req.path;
|
||||
if let Some(path) = is_valid_path(path) {
|
||||
@@ -89,6 +55,7 @@ async fn list_photos(_claims: Claims, req: Json<ThumbnailRequest>) -> impl Respo
|
||||
|
||||
HttpResponse::Ok().json(PhotosResponse { photos, dirs })
|
||||
} else {
|
||||
error!("Bad photos request: {}", req.path);
|
||||
HttpResponse::BadRequest().finish()
|
||||
}
|
||||
}
|
||||
@@ -113,7 +80,7 @@ async fn get_image(
|
||||
.expect("Error stripping prefix");
|
||||
let thumb_path = Path::new(&thumbs).join(relative_path);
|
||||
|
||||
println!("{:?}", thumb_path);
|
||||
debug!("{:?}", thumb_path);
|
||||
if let Ok(file) = NamedFile::open(&thumb_path) {
|
||||
file.into_response(&request).unwrap()
|
||||
} else {
|
||||
@@ -125,6 +92,7 @@ async fn get_image(
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
} else {
|
||||
error!("Bad photos request: {}", req.path);
|
||||
HttpResponse::BadRequest().finish()
|
||||
}
|
||||
}
|
||||
@@ -137,9 +105,9 @@ async fn upload_image(_: Claims, mut payload: mp::Multipart) -> impl Responder {
|
||||
|
||||
while let Some(Ok(mut part)) = payload.next().await {
|
||||
if let Some(content_type) = part.content_disposition() {
|
||||
println!("{:?}", content_type);
|
||||
debug!("{:?}", content_type);
|
||||
if let Some(filename) = content_type.get_filename() {
|
||||
println!("Name: {:?}", filename);
|
||||
debug!("Name: {:?}", filename);
|
||||
file_name = Some(filename.to_string());
|
||||
|
||||
while let Some(Ok(data)) = part.next().await {
|
||||
@@ -163,9 +131,11 @@ async fn upload_image(_: Claims, mut payload: mp::Multipart) -> impl Responder {
|
||||
let mut file = File::create(full_path).unwrap();
|
||||
file.write_all(&file_content).unwrap();
|
||||
} else {
|
||||
error!("File already exists: {:?}", full_path);
|
||||
return HttpResponse::BadRequest().body("File already exists");
|
||||
}
|
||||
} else {
|
||||
error!("Invalid path for upload: {:?}", full_path);
|
||||
return HttpResponse::BadRequest().body("Path was not valid");
|
||||
}
|
||||
} else {
|
||||
@@ -187,7 +157,8 @@ async fn generate_video(
|
||||
let playlist = format!("tmp/{}.m3u8", filename);
|
||||
if let Some(path) = is_valid_path(&body.path) {
|
||||
if let Ok(child) = create_playlist(&path.to_str().unwrap(), &playlist) {
|
||||
data.stream_manager.do_send(ProcessMessage(playlist.clone(), child));
|
||||
data.stream_manager
|
||||
.do_send(ProcessMessage(playlist.clone(), child));
|
||||
}
|
||||
} else {
|
||||
return HttpResponse::BadRequest().finish();
|
||||
@@ -195,6 +166,7 @@ async fn generate_video(
|
||||
|
||||
HttpResponse::Ok().json(playlist)
|
||||
} else {
|
||||
error!("Unable to get file name: {:?}", filename);
|
||||
HttpResponse::BadRequest().finish()
|
||||
}
|
||||
}
|
||||
@@ -206,7 +178,7 @@ async fn stream_video(
|
||||
path: web::Query<ThumbnailRequest>,
|
||||
) -> impl Responder {
|
||||
let playlist = &path.path;
|
||||
println!("Playlist: {}", playlist);
|
||||
debug!("Playlist: {}", playlist);
|
||||
|
||||
// Extract video playlist dir to dotenv
|
||||
if !playlist.starts_with("tmp") && is_valid_path(playlist) != None {
|
||||
@@ -225,11 +197,12 @@ async fn get_video_part(
|
||||
path: web::Path<ThumbnailRequest>,
|
||||
) -> impl Responder {
|
||||
let part = &path.path;
|
||||
println!("Video part: {}", part);
|
||||
debug!("Video part: {}", part);
|
||||
|
||||
if let Ok(file) = NamedFile::open(String::from("tmp/") + part) {
|
||||
file.into_response(&request).unwrap()
|
||||
} else {
|
||||
error!("Video part not found: tmp/{}", part);
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
}
|
||||
@@ -240,6 +213,7 @@ async fn favorites(claims: Claims) -> impl Responder {
|
||||
.into_iter()
|
||||
.map(|favorite| favorite.path)
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
HttpResponse::Ok().json(PhotosResponse {
|
||||
photos: &favorites,
|
||||
dirs: &Vec::new(),
|
||||
@@ -250,8 +224,10 @@ async fn favorites(claims: Claims) -> impl Responder {
|
||||
async fn post_add_favorite(claims: Claims, body: web::Json<AddFavoriteRequest>) -> impl Responder {
|
||||
if let Ok(user_id) = claims.sub.parse::<i32>() {
|
||||
add_favorite(user_id, body.path.clone());
|
||||
debug!("Adding favorite \"{}\" for userid: {}", user_id, body.path);
|
||||
HttpResponse::Ok()
|
||||
} else {
|
||||
error!("Unable to parse sub as i32: {}", claims.sub);
|
||||
HttpResponse::BadRequest()
|
||||
}
|
||||
}
|
||||
@@ -267,8 +243,9 @@ fn create_thumbnails() {
|
||||
.collect::<Vec<Result<_, _>>>()
|
||||
.into_par_iter()
|
||||
.filter_map(|entry| entry.ok())
|
||||
.filter(|entry| entry.file_type().is_file())
|
||||
.filter(|entry| {
|
||||
println!("{:?}", entry.path());
|
||||
debug!("{:?}", entry.path());
|
||||
if let Some(ext) = entry
|
||||
.path()
|
||||
.extension()
|
||||
@@ -279,12 +256,15 @@ fn create_thumbnails() {
|
||||
let thumb_path = Path::new(thumbnail_directory).join(relative_path);
|
||||
std::fs::create_dir_all(&thumb_path.parent().unwrap())
|
||||
.expect("Error creating directory");
|
||||
|
||||
debug!("Generating video thumbnail: {:?}", thumb_path);
|
||||
generate_video_thumbnail(entry.path(), &thumb_path);
|
||||
false
|
||||
} else {
|
||||
ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "nef"
|
||||
}
|
||||
} else {
|
||||
error!("Unable to get extension for file: {:?}", entry.path());
|
||||
false
|
||||
}
|
||||
})
|
||||
@@ -295,7 +275,12 @@ fn create_thumbnails() {
|
||||
!thumb_path.exists()
|
||||
})
|
||||
.map(|entry| (image::open(entry.path()), entry.path().to_path_buf()))
|
||||
.filter(|(img, _)| img.is_ok())
|
||||
.filter(|(img, path)| {
|
||||
if let Err(e) = img {
|
||||
error!("Unable to open image: {:?}. {}", path, e);
|
||||
}
|
||||
img.is_ok()
|
||||
})
|
||||
.map(|(img, path)| (img.unwrap(), path))
|
||||
.map(|(image, path)| (image.thumbnail(200, u32::MAX), path))
|
||||
.map(|(image, path)| {
|
||||
@@ -303,15 +288,18 @@ fn create_thumbnails() {
|
||||
let thumb_path = Path::new(thumbnail_directory).join(relative_path);
|
||||
std::fs::create_dir_all(&thumb_path.parent().unwrap())
|
||||
.expect("There was an issue creating directory");
|
||||
println!("{:?}", thumb_path);
|
||||
debug!("Saving thumbnail: {:?}", thumb_path);
|
||||
image.save(thumb_path).expect("Failure saving thumbnail");
|
||||
})
|
||||
.for_each(drop);
|
||||
|
||||
println!("Finished");
|
||||
debug!("Finished");
|
||||
}
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
dotenv::dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
create_thumbnails();
|
||||
|
||||
std::thread::spawn(|| {
|
||||
@@ -322,11 +310,10 @@ fn main() -> std::io::Result<()> {
|
||||
.unwrap();
|
||||
|
||||
loop {
|
||||
let ev = wrx.recv_timeout(std::time::Duration::from_secs(10));
|
||||
let ev = wrx.recv();
|
||||
if let Ok(event) = ev {
|
||||
match event {
|
||||
DebouncedEvent::Create(_) => create_thumbnails(),
|
||||
DebouncedEvent::Rename(_, _) => create_thumbnails(),
|
||||
DebouncedEvent::Create(_) | DebouncedEvent::Rename(_, _) => create_thumbnails(),
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::path::Path;
|
||||
use std::process::{Child, Command, ExitStatus, Stdio};
|
||||
|
||||
use actix::prelude::*;
|
||||
use log::{debug, trace};
|
||||
|
||||
// ffmpeg -i test.mp4 -c:v h264 -flags +cgop -g 30 -hls_time 3 out.m3u8
|
||||
// ffmpeg -i "filename.mp4" -preset veryfast -c:v libx264 -f hls -hls_list_size 100 -hls_time 2 -crf 24 -vf scale=1080:-2,setsar=1:1 attempt/vid_out.m3u8
|
||||
@@ -23,11 +24,11 @@ impl Handler<ProcessMessage> for StreamActor {
|
||||
type Result = Result<ExitStatus>;
|
||||
|
||||
fn handle(&mut self, msg: ProcessMessage, _ctx: &mut Self::Context) -> Self::Result {
|
||||
println!("Message received");
|
||||
trace!("Message received");
|
||||
let mut process = msg.1;
|
||||
let result = process.wait();
|
||||
|
||||
println!(
|
||||
debug!(
|
||||
"Finished waiting for: {:?}. Code: {:?}",
|
||||
msg.0,
|
||||
result
|
||||
@@ -40,7 +41,7 @@ impl Handler<ProcessMessage> for StreamActor {
|
||||
|
||||
pub fn create_playlist(video_path: &str, playlist_file: &str) -> Result<Child> {
|
||||
if Path::new(playlist_file).exists() {
|
||||
println!("Playlist already exists: {}", playlist_file);
|
||||
debug!("Playlist already exists: {}", playlist_file);
|
||||
return Err(std::io::Error::from(std::io::ErrorKind::AlreadyExists));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user