From c70e20cfadf15e6c1201f699dd1393c290abd7af Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Tue, 28 Nov 2017 14:18:56 -0500 Subject: [PATCH 1/7] The beginnings of a rocket.rs app Most of the meat of the app is contained in a `lib`-style crate, with the actual server being a `bin`-style crate that lives in `src/bin/main.rs`. This is done so that we can easily add binaries that share models, database schemas, etc, down the line. --- Cargo.lock | 805 +++++++++++++++++++++++++++- Cargo.toml | 27 +- src/bin/main.rs | 33 ++ src/{ => fedibook}/config.rs | 0 src/fedibook/controllers/apps.rs | 15 + src/fedibook/controllers/mod.rs | 1 + src/fedibook/lib.rs | 17 + src/fedibook/models/apps.rs | 18 + src/fedibook/models/mod.rs | 2 + src/fedibook/models/scope.rs | 63 +++ src/fedibook/routes/applications.rs | 71 +++ src/fedibook/routes/auth.rs | 43 ++ src/fedibook/routes/mod.rs | 2 + src/main.rs | 24 - templates/sign_in.html.hbs | 12 + templates/sign_up.html.hbs | 14 + 16 files changed, 1119 insertions(+), 28 deletions(-) create mode 100644 src/bin/main.rs rename src/{ => fedibook}/config.rs (100%) create mode 100644 src/fedibook/controllers/apps.rs create mode 100644 src/fedibook/controllers/mod.rs create mode 100644 src/fedibook/lib.rs create mode 100644 src/fedibook/models/apps.rs create mode 100644 src/fedibook/models/mod.rs create mode 100644 src/fedibook/models/scope.rs create mode 100644 src/fedibook/routes/applications.rs create mode 100644 src/fedibook/routes/auth.rs create mode 100644 src/fedibook/routes/mod.rs delete mode 100644 src/main.rs create mode 100644 templates/sign_in.html.hbs create mode 100644 templates/sign_up.html.hbs diff --git a/Cargo.lock b/Cargo.lock index 6ae14e09..57624c25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,8 +1,219 @@ -[root] +[[package]] +name = "aho-corasick" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "base64" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bitflags" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "byteorder" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cc" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "coco" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "collection_macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cookie" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "derive-error-chain" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "derive_builder" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive_builder_core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "derive_builder_core" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel_codegen" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dotenv" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "dtoa" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "either" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "error-chain" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "failure" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "fedibook" -version = "0.0.0" +version = "0.1.0" dependencies = [ + "collection_macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libxml 0.0.7481 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket_codegen 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket_contrib 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -10,11 +221,103 @@ name = "gcc" version = "0.3.54" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "handlebars" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "httparse" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hyper" +version = "0.10.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "idna" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "isatty" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "itoa" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "lazy_static" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libc" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libxml" version = "0.0.7481" @@ -24,7 +327,505 @@ dependencies = [ "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "log" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "matches" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memchr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mime" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num_cpus" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ordermap" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pear" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pear_codegen" +version = "0.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "percent-encoding" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "pest" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quick-error" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "rand" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "redox_syscall" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ring" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rocket" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "pear 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "pear_codegen 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "state 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", + "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "yansi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rocket_codegen" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "yansi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rocket_contrib" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 0.27.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "safemem" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "smallvec" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "state" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synstructure" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "time" +version = "0.1.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "toml" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "traitobject" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "typeable" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicase" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "untrusted" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "url" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "utf8-ranges" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "yansi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [metadata] +"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" +"checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" +"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" +"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" +"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" +"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" +"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" +"checksum collection_macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50b180e6a75e306052a61658f832b4fc565a6e5a204da05f0fe7f50a31fb827a" +"checksum cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "477eb650753e319be2ae77ec368a58c638f9f0c4d941c39bad95e950fb1d1d0d" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" +"checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" +"checksum derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03600ae366b6eb2314e54d62adc833d9866da03798acc61c61789654ceaa227a" +"checksum derive_builder_core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eed37eae64daa5511467b1a55cebdf472deeaef108d22f62f25e8bbcaffd56ac" +"checksum diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "304226fa7a3982b0405f6bb95dd9c10c3e2000709f194038a60ec2c277150951" +"checksum diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a42ca5c9b660add51d58bc5a50a87123380e1e458069c5504528a851ed7384" +"checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3" +"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" +"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +"checksum failure 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76aa046667594883228b6c1f55c260425950a5cdc66d3aa09c30472d5ac6e70c" +"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" +"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" +"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" "checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" +"checksum handlebars 0.27.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef7567daf271a32e60301e4821fcb5b51a5b535167115d1ce04f46c3f0a15f0b" +"checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" +"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" +"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" +"checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2" +"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" +"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" +"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122" +"checksum libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "5ba3df4dcb460b9dfbd070d41c94c19209620c191b0340b929ce748a2bcd42d2" "checksum libxml 0.0.7481 (registry+https://github.com/rust-lang/crates.io-index)" = "9db47ba61ecba4a0d1d2bbe36dd69e34d49fca711bd915d45ae0c7c411a6f90f" +"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" +"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 mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" +"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" +"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" +"checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b" +"checksum pear 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "87dd0e084e2c18b047658e40f89b856dfc23104011fd43f9369e873d03b7f15b" +"checksum pear_codegen 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0455b67d07b3aa40a552256059f11eb8db3a848cbec81bae3e3cb366e6e74e24" +"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" +"checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" +"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" +"checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a" +"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" +"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" +"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" +"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724" +"checksum rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ad92f830d1ae2e9400ff212c949f6101b794cb3f50df975a8278b30280de51e" +"checksum rocket_codegen 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a945a800964fd73054d726fcfb52dbb5ed2c77f9c97f94de81f94970779f12ad" +"checksum rocket_contrib 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c3aa9888842d219dc3561f7a91f166c48c34746429f8e436d4a8b6edbfdb39" +"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" +"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6eda663e865517ee783b0891a3f6eb3a253e0b0dabb46418969ee9635beadd9e" +"checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" +"checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab" +"checksum serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e4586746d1974a030c48919731ecffd0ed28d0c40749d0d18d43b3a7d6c9b20e" +"checksum smallvec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4f357e8cd37bf8822e1b964e96fd39e2cb5a0424f8aaa284ccaccc2162411c" +"checksum state 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "acc74e29126a281afcfd8dfa0ae83f1720a1adf5fc99524898e45ca440a73919" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" +"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" +"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" +"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" +"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +"checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" +"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.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" +"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" +"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum yansi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a503e4eea629f145a693c8ed1eddba88b3b9de5171c6ebd0e2820cf82d38f934" diff --git a/Cargo.toml b/Cargo.toml index 93a4d9b8..20b33e65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,30 @@ [package] name = "fedibook" -version = "0.0.0" -authors = ["Eric Chadbourne ", "Peter Alexander ", "Elijah Mark Anderson "] +version = "0.1.0" +authors = ["Eric Chadbourne ", "Peter Alexander ", "Elijah Mark Anderson ", "Paul Woolcock "] + +[lib] +name = "_fedibook" +path = "src/fedibook/lib.rs" + +[[bin]] +name = "fedibook-server" +path = "src/bin/main.rs" [dependencies] +collection_macros = "0.2.0" +derive_builder = "0.5.0" +diesel = "0.16.0" +diesel_codegen = "0.16.0" +failure = "0.1.0" +failure_derive = "0.1.1" libxml = "0.0.7481" +rocket = "0.3.3" +rocket_codegen = "0.3.3" +serde = "1.0.21" +serde_derive = "1.0.21" + +[dependencies.rocket_contrib] +version = "0.3.3" +default-features = false +features = ["handlebars_templates", "json"] diff --git a/src/bin/main.rs b/src/bin/main.rs new file mode 100644 index 00000000..a6a2b515 --- /dev/null +++ b/src/bin/main.rs @@ -0,0 +1,33 @@ +#![feature(try_from)] +#![feature(plugin)] +#![feature(custom_derive)] +#![plugin(rocket_codegen)] + +extern crate rocket; +extern crate failure; +extern crate rocket_contrib; +extern crate serde; + +extern crate _fedibook as fedibook; + +use rocket::Rocket; +use rocket_contrib::Template; + +fn rocket() -> Rocket { + rocket::ignite() + .mount("/api/v1", routes![ + fedibook::routes::applications::register_application + ]) + .mount("/", routes![ + fedibook::routes::auth::sign_up_form, + fedibook::routes::auth::sign_in_form, + fedibook::routes::auth::sign_up, + fedibook::routes::auth::sign_in, + ]) + .attach(Template::fairing()) +} + +fn main() { + rocket().launch(); +} + diff --git a/src/config.rs b/src/fedibook/config.rs similarity index 100% rename from src/config.rs rename to src/fedibook/config.rs diff --git a/src/fedibook/controllers/apps.rs b/src/fedibook/controllers/apps.rs new file mode 100644 index 00000000..8a339f6c --- /dev/null +++ b/src/fedibook/controllers/apps.rs @@ -0,0 +1,15 @@ +use models::apps::{App, AppId, AppIdBuilder}; + +#[derive(Fail, Debug)] +#[fail(display = "Failed to create app.")] +pub(crate) struct CreateAppError; + +pub(crate) fn create(app: App) -> Result { + // store the app somewhere + Ok(AppIdBuilder::default() + .id("foo") + .client_id("bar") + .client_secret("baz") + .build() + .unwrap()) +} diff --git a/src/fedibook/controllers/mod.rs b/src/fedibook/controllers/mod.rs new file mode 100644 index 00000000..c2b34bdc --- /dev/null +++ b/src/fedibook/controllers/mod.rs @@ -0,0 +1 @@ +pub mod apps; diff --git a/src/fedibook/lib.rs b/src/fedibook/lib.rs new file mode 100644 index 00000000..706adef3 --- /dev/null +++ b/src/fedibook/lib.rs @@ -0,0 +1,17 @@ +#![feature(try_from)] +#![feature(plugin)] +#![feature(custom_derive)] +#![plugin(rocket_codegen)] + +extern crate rocket; +extern crate failure; +extern crate rocket_contrib; +extern crate serde; +#[macro_use] extern crate failure_derive; +#[macro_use] extern crate serde_derive; +#[macro_use] extern crate derive_builder; +#[macro_use] extern crate collection_macros; + +pub mod models; +pub mod controllers; +pub mod routes; diff --git a/src/fedibook/models/apps.rs b/src/fedibook/models/apps.rs new file mode 100644 index 00000000..01217c95 --- /dev/null +++ b/src/fedibook/models/apps.rs @@ -0,0 +1,18 @@ +use models::scope::Scope; + +#[derive(Debug, Clone, PartialEq)] +pub struct App<'a> { + pub client_name: &'a str, + pub redirect_uris: &'a str, + pub scopes: &'a Scope, + pub website: &'a Option, +} + +#[derive(Default, Builder, Debug, Clone, PartialEq, Serialize)] +#[builder(setter(into))] +pub struct AppId { + id: String, + client_id: String, + client_secret: String +} + diff --git a/src/fedibook/models/mod.rs b/src/fedibook/models/mod.rs new file mode 100644 index 00000000..b59d08c2 --- /dev/null +++ b/src/fedibook/models/mod.rs @@ -0,0 +1,2 @@ +pub mod apps; +pub mod scope; diff --git a/src/fedibook/models/scope.rs b/src/fedibook/models/scope.rs new file mode 100644 index 00000000..8f130052 --- /dev/null +++ b/src/fedibook/models/scope.rs @@ -0,0 +1,63 @@ +use std::convert::TryFrom; + + +#[derive(Debug, Clone, PartialEq)] +pub enum Scope { + Read, + Write, + Follow, + ReadWrite, + ReadFollow, + WriteFollow, + ReadWriteFollow, +} + +#[derive(Debug, Fail)] +#[fail(display = "Error decoding 'scope'")] +pub struct ScopeDecodeError; + +impl TryFrom for Scope { + type Error = ScopeDecodeError; + + fn try_from(scope: String) -> Result { + let mut read: bool = false; + let mut write: bool = false; + let mut follow: bool = false; + + // because "read write follow" is length 17 and that is the longest string that should be + // coming in here + if scope.len() > 17 { + return Err(ScopeDecodeError); + } + + let parts = scope.splitn(3, ' '); + + for part in parts { + if part == "read" { + read = true; + } + if part == "write" { + write = true; + } + if part == "follow" { + follow = true; + } + } + + Ok(match (read, write, follow) { + (true, false, false) => {Scope::Read}, + (false, true, false) => {Scope::Write}, + (false, false, true) => {Scope::Follow}, + (true, true, false) => {Scope::ReadWrite}, + (true, false, true) => {Scope::ReadFollow}, + (false, true, true) => {Scope::WriteFollow}, + (true, true, true) => {Scope::ReadWriteFollow}, + _ => { + return Err(ScopeDecodeError); + } + }) + } +} + + + diff --git a/src/fedibook/routes/applications.rs b/src/fedibook/routes/applications.rs new file mode 100644 index 00000000..27c8ebe1 --- /dev/null +++ b/src/fedibook/routes/applications.rs @@ -0,0 +1,71 @@ +/// Routes for dealing with applications + +use failure::Error; +use rocket_contrib::Json; + +use models::scope::Scope; +use models::apps::{App, AppId}; +use controllers; + +mod deser_scope { + use std::convert::TryFrom; + use models::scope::Scope; + use serde::{self, Deserialize, Deserializer}; + + pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result + where D: Deserializer<'de> + { + let s = String::deserialize(deserializer)?; + TryFrom::try_from(s).map_err(serde::de::Error::custom) + } +} + +#[derive(Debug, Fail)] +enum CreateAppError { + #[fail(display = "validation error when creating app")] + ValidationError, +} + +/// Represents the form that is POSTed to /api/v1/apps to create an application +#[derive(Deserialize)] +struct CreateApp { + client_name: String, + redirect_uris: String, + #[serde(with = "deser_scope")] + scopes: Scope, + website: Option, +} + +impl CreateApp { + fn validate(&self) -> Result<(), CreateAppError> { + if self.client_name.is_empty() || self.client_name.len() > 256 { + return Err(CreateAppError::ValidationError); + } + + if self.redirect_uris.is_empty() { + return Err(CreateAppError::ValidationError); + } + + Ok(()) + } +} + +impl<'a, 'b: 'a> From<&'b CreateApp> for App<'a> { + fn from(app: &'b CreateApp) -> App<'a> { + App { + client_name: &app.client_name[..], + redirect_uris: &app.redirect_uris[..], + scopes: &app.scopes, + website: &app.website, + } + } +} + +#[post("/apps", data = "")] +fn register_application(app: Json) -> Result, Error> { + let app = app.into_inner(); + app.validate()?; + Ok(Json(controllers::apps::create(App::from(&app))?)) +} + + diff --git a/src/fedibook/routes/auth.rs b/src/fedibook/routes/auth.rs new file mode 100644 index 00000000..43792cdd --- /dev/null +++ b/src/fedibook/routes/auth.rs @@ -0,0 +1,43 @@ +use rocket::response::Redirect; +use rocket::request::Form; +use rocket_contrib::Template; + +#[derive(Debug, Clone, PartialEq, FromForm)] +struct SignUpForm { + csrf_token: String, + username: String, + email: String, + password: String, + password_confirmation: String, +} + +#[derive(Debug, Clone, PartialEq, FromForm)] +struct SignInForm { + csrf_token: String, + email: String, + password: String, +} + +#[get("/auth/sign_up")] +fn sign_up_form() -> Template { + let token = "some csrf token"; + Template::render("sign_up", hashmap!{ "token" => token }) +} + +#[get("/auth/sign_in")] +fn sign_in_form() -> Template { + let token = "some csrf token"; + Template::render("sign_in", hashmap!{ "token" => token }) +} + +#[post("/auth", data = "
")] +fn sign_up(form: Form) -> Redirect { + println!("got sign up form: {:#?}", form.into_inner()); + Redirect::to("/auth/sign_in") +} + +#[post("/auth/sign_in", data = "")] +fn sign_in(form: Form) -> Redirect { + println!("got sign in form: {:#?}", form.into_inner()); + Redirect::to("/app") +} diff --git a/src/fedibook/routes/mod.rs b/src/fedibook/routes/mod.rs new file mode 100644 index 00000000..96a0835b --- /dev/null +++ b/src/fedibook/routes/mod.rs @@ -0,0 +1,2 @@ +pub mod auth; +pub mod applications; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index a677c1a9..00000000 --- a/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::env; -use std::path::PathBuf; - -mod config; -use config::*; - -fn main() { - // TODO: Parse command-line arguments - // Set defaults for command line arguments - let cfg_file = PathBuf::from("settings.xml"); - - // Process and shadow defaults. - - // TODO: Complete config module - let cfg = Config::new(cfg_file).unwrap(); - - // TODO: Initialize/Fork - - // Main loop - let mut run = true; - while run { - - } -} diff --git a/templates/sign_in.html.hbs b/templates/sign_in.html.hbs new file mode 100644 index 00000000..bd8a8b4f --- /dev/null +++ b/templates/sign_in.html.hbs @@ -0,0 +1,12 @@ + + + +

Sign In

+ + + + + + + + diff --git a/templates/sign_up.html.hbs b/templates/sign_up.html.hbs new file mode 100644 index 00000000..613f3fc4 --- /dev/null +++ b/templates/sign_up.html.hbs @@ -0,0 +1,14 @@ + + + +

Sign Up

+
+ + + + + + +
+ + From 411de5cf573d3c158f042b10381ebef0bba49e3f Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Tue, 28 Nov 2017 15:14:22 -0500 Subject: [PATCH 2/7] Initial integration of `diesel` --- Cargo.toml | 14 ++- Rocket.toml | 8 ++ migrations/.gitkeep | 0 .../down.sql | 2 + .../up.sql | 36 ++++++ .../2017-11-28-112459_create_schema/down.sql | 2 + .../2017-11-28-112459_create_schema/up.sql | 3 + .../down.sql | 3 + .../2017-11-28-112508_create_accounts/up.sql | 9 ++ .../2017-11-28-112517_create_users/down.sql | 2 + .../2017-11-28-112517_create_users/up.sql | 24 ++++ src/bin/main.rs | 27 +++- src/fedibook/lib.rs | 3 + src/fedibook/schema.rs | 115 ++++++++++++++++++ 14 files changed, 242 insertions(+), 6 deletions(-) create mode 100644 Rocket.toml create mode 100644 migrations/.gitkeep create mode 100644 migrations/00000000000000_diesel_initial_setup/down.sql create mode 100644 migrations/00000000000000_diesel_initial_setup/up.sql create mode 100644 migrations/2017-11-28-112459_create_schema/down.sql create mode 100644 migrations/2017-11-28-112459_create_schema/up.sql create mode 100644 migrations/2017-11-28-112508_create_accounts/down.sql create mode 100644 migrations/2017-11-28-112508_create_accounts/up.sql create mode 100644 migrations/2017-11-28-112517_create_users/down.sql create mode 100644 migrations/2017-11-28-112517_create_users/up.sql create mode 100644 src/fedibook/schema.rs diff --git a/Cargo.toml b/Cargo.toml index 20b33e65..49b4ff6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,16 +14,26 @@ path = "src/bin/main.rs" [dependencies] collection_macros = "0.2.0" derive_builder = "0.5.0" -diesel = "0.16.0" -diesel_codegen = "0.16.0" failure = "0.1.0" failure_derive = "0.1.1" libxml = "0.0.7481" +r2d2 = "0.7" +r2d2-diesel = "0.16" rocket = "0.3.3" rocket_codegen = "0.3.3" serde = "1.0.21" serde_derive = "1.0.21" +[dependencies.diesel] +version = "0.16" +default-features = false +features = ["postgres", "uuid"] + +[dependencies.diesel_codegen] +version = "0.16" +default-features = false +features = ["postgres"] + [dependencies.rocket_contrib] version = "0.3.3" default-features = false diff --git a/Rocket.toml b/Rocket.toml new file mode 100644 index 00000000..21e09910 --- /dev/null +++ b/Rocket.toml @@ -0,0 +1,8 @@ +[development] +port = 7878 # https://twitter.com/ag_dubs/status/852559264510070784 +database_url = "postgres://localhost/fedibook_development" + +[staging] + +[production] + diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 00000000..8fb31a8e --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,2 @@ +DROP FUNCTION IF EXISTS diesel_manage_updated_at(_tbl regclass); +DROP FUNCTION IF EXISTS diesel_set_updated_at(); diff --git a/migrations/00000000000000_diesel_initial_setup/up.sql b/migrations/00000000000000_diesel_initial_setup/up.sql new file mode 100644 index 00000000..d68895b1 --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/up.sql @@ -0,0 +1,36 @@ +-- This file was automatically created by Diesel to setup helper functions +-- and other internal bookkeeping. This file is safe to edit, any future +-- changes will be added to existing projects as new migrations. + + + + +-- Sets up a trigger for the given table to automatically set a column called +-- `updated_at` whenever the row is modified (unless `updated_at` was included +-- in the modified columns) +-- +-- # Example +-- +-- ```sql +-- CREATE TABLE users (id SERIAL PRIMARY KEY, updated_at TIMESTAMP NOT NULL DEFAULT NOW()); +-- +-- SELECT diesel_manage_updated_at('users'); +-- ``` +CREATE OR REPLACE FUNCTION diesel_manage_updated_at(_tbl regclass) RETURNS VOID AS $$ +BEGIN + EXECUTE format('CREATE TRIGGER set_updated_at BEFORE UPDATE ON %s + FOR EACH ROW EXECUTE PROCEDURE diesel_set_updated_at()', _tbl); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION diesel_set_updated_at() RETURNS trigger AS $$ +BEGIN + IF ( + NEW IS DISTINCT FROM OLD AND + NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at + ) THEN + NEW.updated_at := current_timestamp; + END IF; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; diff --git a/migrations/2017-11-28-112459_create_schema/down.sql b/migrations/2017-11-28-112459_create_schema/down.sql new file mode 100644 index 00000000..edb01e82 --- /dev/null +++ b/migrations/2017-11-28-112459_create_schema/down.sql @@ -0,0 +1,2 @@ +DROP EXTENSION IF EXISTS "pgcrypto"; +DROP SCHEMA IF EXISTS fedibook; diff --git a/migrations/2017-11-28-112459_create_schema/up.sql b/migrations/2017-11-28-112459_create_schema/up.sql new file mode 100644 index 00000000..748e36a0 --- /dev/null +++ b/migrations/2017-11-28-112459_create_schema/up.sql @@ -0,0 +1,3 @@ +CREATE SCHEMA IF NOT EXISTS fedibook; + +CREATE EXTENSION IF NOT EXISTS "pgcrypto"; diff --git a/migrations/2017-11-28-112508_create_accounts/down.sql b/migrations/2017-11-28-112508_create_accounts/down.sql new file mode 100644 index 00000000..da18456c --- /dev/null +++ b/migrations/2017-11-28-112508_create_accounts/down.sql @@ -0,0 +1,3 @@ +DROP INDEX IF EXISTS id_idx; +DROP INDEX IF EXISTS username_domain_unique_idx; +DROP TABLE IF EXISTS fedibook.accounts; diff --git a/migrations/2017-11-28-112508_create_accounts/up.sql b/migrations/2017-11-28-112508_create_accounts/up.sql new file mode 100644 index 00000000..7127c52e --- /dev/null +++ b/migrations/2017-11-28-112508_create_accounts/up.sql @@ -0,0 +1,9 @@ +CREATE TABLE IF NOT EXISTS fedibook.accounts ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + username VARCHAR NOT NULL DEFAULT '', + domain VARCHAR, + display_name VARCHAR NOT NULL DEFAULT '' +); + +CREATE UNIQUE INDEX IF NOT EXISTS id_idx ON fedibook.accounts (id); +CREATE UNIQUE INDEX IF NOT EXISTS username_domain_unique_idx ON fedibook.accounts (username, domain); diff --git a/migrations/2017-11-28-112517_create_users/down.sql b/migrations/2017-11-28-112517_create_users/down.sql new file mode 100644 index 00000000..8b4a17ff --- /dev/null +++ b/migrations/2017-11-28-112517_create_users/down.sql @@ -0,0 +1,2 @@ +DROP INDEX IF EXISTS email_idx; +DROP TABLE IF EXISTS fedibook.users; diff --git a/migrations/2017-11-28-112517_create_users/up.sql b/migrations/2017-11-28-112517_create_users/up.sql new file mode 100644 index 00000000..0f62b5d9 --- /dev/null +++ b/migrations/2017-11-28-112517_create_users/up.sql @@ -0,0 +1,24 @@ +CREATE TABLE IF NOT EXISTS fedibook.users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + email VARCHAR NOT NULL DEFAULT '', + encrypted_password VARCHAR NOT NULL DEFAULT '', + account_id UUID NOT NULL, + + -- flags + admin BOOLEAN NOT NULL, + disabled BOOLEAN NOT NULL, + + -- confirmation stuff + unconfirmed_email VARCHAR NOT NULL DEFAULT '', + confirmation_token VARCHAR NOT NULL DEFAULT '', + confirmed_at TIMESTAMP WITHOUT TIME ZONE, + confirmation_sent_at TIMESTAMP WITHOUT TIME ZONE, + + -- timestamps + created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (now() at time zone 'utc'), + updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (now() at time zone 'utc'), + + FOREIGN KEY (account_id) REFERENCES fedibook.accounts (id) +); + +CREATE INDEX IF NOT EXISTS email_idx ON fedibook.users (email); diff --git a/src/bin/main.rs b/src/bin/main.rs index a6a2b515..7aa2463e 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -7,14 +7,28 @@ extern crate rocket; extern crate failure; extern crate rocket_contrib; extern crate serde; +extern crate r2d2; +extern crate r2d2_diesel; +extern crate diesel; extern crate _fedibook as fedibook; use rocket::Rocket; use rocket_contrib::Template; +use diesel::pg::PgConnection; +use r2d2_diesel::ConnectionManager; -fn rocket() -> Rocket { - rocket::ignite() +type Pool = r2d2::Pool>; + +fn db_pool(rocket: &Rocket) -> Pool { + let database_url = rocket.config().get_str("database_url").expect("Must set DATABASE_URL"); + let config = r2d2::Config::default(); + let manager = ConnectionManager::::new(database_url); + r2d2::Pool::new(config, manager).expect("Could not get DB connection pool") +} + +fn app() -> Rocket { + let r = rocket::ignite() .mount("/api/v1", routes![ fedibook::routes::applications::register_application ]) @@ -24,10 +38,15 @@ fn rocket() -> Rocket { fedibook::routes::auth::sign_up, fedibook::routes::auth::sign_in, ]) - .attach(Template::fairing()) + .attach(Template::fairing()); + + // we need an instance of the app to access the config values in Rocket.toml, + // so we pass it to the db_pool function, get the pool, and _then_ return the instance + let pool = db_pool(&r); + r.manage(pool) } fn main() { - rocket().launch(); + app().launch(); } diff --git a/src/fedibook/lib.rs b/src/fedibook/lib.rs index 706adef3..610b4f15 100644 --- a/src/fedibook/lib.rs +++ b/src/fedibook/lib.rs @@ -1,3 +1,4 @@ +#![recursion_limit="128"] #![feature(try_from)] #![feature(plugin)] #![feature(custom_derive)] @@ -11,7 +12,9 @@ extern crate serde; #[macro_use] extern crate serde_derive; #[macro_use] extern crate derive_builder; #[macro_use] extern crate collection_macros; +#[macro_use] extern crate diesel; pub mod models; pub mod controllers; pub mod routes; +pub mod schema; diff --git a/src/fedibook/schema.rs b/src/fedibook/schema.rs new file mode 100644 index 00000000..8d1df188 --- /dev/null +++ b/src/fedibook/schema.rs @@ -0,0 +1,115 @@ +pub mod fedibook { + table! { + /// Representation of the `fedibook.accounts` table. + /// + /// (Automatically generated by Diesel.) + accounts (id) { + /// The `id` column of the `fedibook.accounts` table. + /// + /// Its SQL type is `Uuid`. + /// + /// (Automatically generated by Diesel.) + id -> Uuid, + /// The `username` column of the `fedibook.accounts` table. + /// + /// Its SQL type is `Varchar`. + /// + /// (Automatically generated by Diesel.) + username -> Varchar, + /// The `domain` column of the `fedibook.accounts` table. + /// + /// Its SQL type is `Nullable`. + /// + /// (Automatically generated by Diesel.) + domain -> Nullable, + /// The `display_name` column of the `fedibook.accounts` table. + /// + /// Its SQL type is `Varchar`. + /// + /// (Automatically generated by Diesel.) + display_name -> Varchar, + } + } + + table! { + /// Representation of the `fedibook.users` table. + /// + /// (Automatically generated by Diesel.) + users (id) { + /// The `id` column of the `fedibook.users` table. + /// + /// Its SQL type is `Uuid`. + /// + /// (Automatically generated by Diesel.) + id -> Uuid, + /// The `email` column of the `fedibook.users` table. + /// + /// Its SQL type is `Varchar`. + /// + /// (Automatically generated by Diesel.) + email -> Varchar, + /// The `encrypted_password` column of the `fedibook.users` table. + /// + /// Its SQL type is `Varchar`. + /// + /// (Automatically generated by Diesel.) + encrypted_password -> Varchar, + /// The `account_id` column of the `fedibook.users` table. + /// + /// Its SQL type is `Uuid`. + /// + /// (Automatically generated by Diesel.) + account_id -> Uuid, + /// The `admin` column of the `fedibook.users` table. + /// + /// Its SQL type is `Bool`. + /// + /// (Automatically generated by Diesel.) + admin -> Bool, + /// The `disabled` column of the `fedibook.users` table. + /// + /// Its SQL type is `Bool`. + /// + /// (Automatically generated by Diesel.) + disabled -> Bool, + /// The `unconfirmed_email` column of the `fedibook.users` table. + /// + /// Its SQL type is `Varchar`. + /// + /// (Automatically generated by Diesel.) + unconfirmed_email -> Varchar, + /// The `confirmation_token` column of the `fedibook.users` table. + /// + /// Its SQL type is `Varchar`. + /// + /// (Automatically generated by Diesel.) + confirmation_token -> Varchar, + /// The `confirmed_at` column of the `fedibook.users` table. + /// + /// Its SQL type is `Nullable`. + /// + /// (Automatically generated by Diesel.) + confirmed_at -> Nullable, + /// The `confirmation_sent_at` column of the `fedibook.users` table. + /// + /// Its SQL type is `Nullable`. + /// + /// (Automatically generated by Diesel.) + confirmation_sent_at -> Nullable, + /// The `created_at` column of the `fedibook.users` table. + /// + /// Its SQL type is `Timestamp`. + /// + /// (Automatically generated by Diesel.) + created_at -> Timestamp, + /// The `updated_at` column of the `fedibook.users` table. + /// + /// Its SQL type is `Timestamp`. + /// + /// (Automatically generated by Diesel.) + updated_at -> Timestamp, + } + } + + joinable!(users -> accounts (account_id)); +} From 6d227cdaf742badf4d4e28ab9061fd97a777e74a Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Tue, 28 Nov 2017 15:15:05 -0500 Subject: [PATCH 3/7] Add a couple columns to `accounts` and get the models for users & accounts going --- Cargo.lock | 143 +++++++++++++++--- Cargo.toml | 10 +- .../2017-11-28-112508_create_accounts/up.sql | 5 +- src/fedibook/lib.rs | 3 + src/fedibook/models/account.rs | 22 +++ src/fedibook/models/mod.rs | 2 + src/fedibook/models/user.rs | 31 ++++ src/fedibook/schema.rs | 12 ++ 8 files changed, 203 insertions(+), 25 deletions(-) create mode 100644 src/fedibook/models/account.rs create mode 100644 src/fedibook/models/user.rs diff --git a/Cargo.lock b/Cargo.lock index 57624c25..eaa06d5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,11 @@ dependencies = [ "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "antidote" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "backtrace" version = "0.3.4" @@ -43,6 +48,11 @@ name = "bitflags" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "bitflags" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" version = "1.1.0" @@ -58,6 +68,16 @@ name = "cfg-if" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chrono" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "coco" version = "0.1.1" @@ -92,15 +112,6 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "derive-error-chain" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "derive_builder" version = "0.5.0" @@ -125,7 +136,11 @@ name = "diesel" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pq-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -134,19 +149,17 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "dotenv" -version = "0.10.1" +name = "diesel_infer_schema" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -159,11 +172,6 @@ name = "either" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "error-chain" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "failure" version = "0.1.0" @@ -186,6 +194,7 @@ dependencies = [ name = "fedibook" version = "0.1.0" dependencies = [ + "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "collection_macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -193,11 +202,14 @@ dependencies = [ "failure 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "libxml 0.0.7481 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_codegen 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_contrib 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -353,6 +365,33 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "num" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-integer" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-iter" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.1.40" @@ -391,6 +430,14 @@ name = "pest" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "pq-sys" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "quick-error" version = "1.2.1" @@ -401,6 +448,25 @@ name = "quote" version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "r2d2" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "r2d2-diesel" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand" version = "0.3.18" @@ -530,6 +596,14 @@ name = "safemem" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scheduled-thread-pool" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "scopeguard" version = "0.3.3" @@ -709,6 +783,19 @@ name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "uuid" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "vcpkg" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "version_check" version = "0.1.3" @@ -736,26 +823,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699" +"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" +"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" +"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum collection_macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50b180e6a75e306052a61658f832b4fc565a6e5a204da05f0fe7f50a31fb827a" "checksum cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "477eb650753e319be2ae77ec368a58c638f9f0c4d941c39bad95e950fb1d1d0d" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" -"checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" "checksum derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03600ae366b6eb2314e54d62adc833d9866da03798acc61c61789654ceaa227a" "checksum derive_builder_core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eed37eae64daa5511467b1a55cebdf472deeaef108d22f62f25e8bbcaffd56ac" "checksum diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "304226fa7a3982b0405f6bb95dd9c10c3e2000709f194038a60ec2c277150951" "checksum diesel_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18a42ca5c9b660add51d58bc5a50a87123380e1e458069c5504528a851ed7384" -"checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3" +"checksum diesel_infer_schema 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1957ff5cd3b04772e43c162c2f69c2aa918080ff9b020276792d236be8be52" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" "checksum failure 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "76aa046667594883228b6c1f55c260425950a5cdc66d3aa09c30472d5ac6e70c" "checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" @@ -778,6 +866,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" +"checksum num 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "a311b77ebdc5dd4cf6449d81e4135d9f0e3b153839ac90e648a8ef538f923525" +"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" +"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" "checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b" @@ -785,8 +876,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pear_codegen 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0455b67d07b3aa40a552256059f11eb8db3a848cbec81bae3e3cb366e6e74e24" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum pest 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6dda33d67c26f0aac90d324ab2eb7239c819fc7b2552fe9faa4fe88441edc8" +"checksum pq-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfb5e575ef93a1b7b2a381d47ba7c5d4e4f73bff37cee932195de769aad9a54" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" +"checksum r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2c8284508b38df440f8f3527395e23c4780b22f74226b270daf58fee38e4bcce" +"checksum r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f6b921696a6c45991296d21b52ed973b9fb56f6c47524fda1f99458c2d6c0478" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" "checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" @@ -800,6 +894,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rocket_contrib 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c3aa9888842d219dc3561f7a91f166c48c34746429f8e436d4a8b6edbfdb39" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" +"checksum scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d9fbe48ead32343b76f544c85953bf260ed39219a8bbbb62cd85f6a00f9644f" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum serde 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6eda663e865517ee783b0891a3f6eb3a253e0b0dabb46418969ee9635beadd9e" "checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788" @@ -824,6 +919,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" "checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 49b4ff6f..812dfab2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,10 +24,18 @@ rocket_codegen = "0.3.3" serde = "1.0.21" serde_derive = "1.0.21" +[dependencies.chrono] +version = "0.4" +features = ["serde"] + +[dependencies.uuid] +version = "0.5" +features = ["v4"] + [dependencies.diesel] version = "0.16" default-features = false -features = ["postgres", "uuid"] +features = ["postgres", "uuid", "chrono"] [dependencies.diesel_codegen] version = "0.16" diff --git a/migrations/2017-11-28-112508_create_accounts/up.sql b/migrations/2017-11-28-112508_create_accounts/up.sql index 7127c52e..c589dc06 100644 --- a/migrations/2017-11-28-112508_create_accounts/up.sql +++ b/migrations/2017-11-28-112508_create_accounts/up.sql @@ -2,7 +2,10 @@ CREATE TABLE IF NOT EXISTS fedibook.accounts ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username VARCHAR NOT NULL DEFAULT '', domain VARCHAR, - display_name VARCHAR NOT NULL DEFAULT '' + display_name VARCHAR NOT NULL DEFAULT '', + + created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (now() at time zone 'utc'), + updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT (now() at time zone 'utc') ); CREATE UNIQUE INDEX IF NOT EXISTS id_idx ON fedibook.accounts (id); diff --git a/src/fedibook/lib.rs b/src/fedibook/lib.rs index 610b4f15..6ac658b9 100644 --- a/src/fedibook/lib.rs +++ b/src/fedibook/lib.rs @@ -4,15 +4,18 @@ #![feature(custom_derive)] #![plugin(rocket_codegen)] +extern crate chrono; extern crate rocket; extern crate failure; extern crate rocket_contrib; extern crate serde; +extern crate uuid; #[macro_use] extern crate failure_derive; #[macro_use] extern crate serde_derive; #[macro_use] extern crate derive_builder; #[macro_use] extern crate collection_macros; #[macro_use] extern crate diesel; +#[macro_use] extern crate diesel_codegen; pub mod models; pub mod controllers; diff --git a/src/fedibook/models/account.rs b/src/fedibook/models/account.rs new file mode 100644 index 00000000..c88f309e --- /dev/null +++ b/src/fedibook/models/account.rs @@ -0,0 +1,22 @@ +use uuid::Uuid; +use chrono::NaiveDateTime; + +use schema::fedibook::accounts; + +#[derive(Queryable)] +pub(crate) struct Account { + id: Uuid, + username: String, + domain: Option, + display_name: String, + created_at: NaiveDateTime, + updated_at: NaiveDateTime, +} + +#[derive(Insertable)] +#[table_name="accounts"] +pub(crate) struct NewAccount { + username: String, + domain: Option, + display_name: String, +} diff --git a/src/fedibook/models/mod.rs b/src/fedibook/models/mod.rs index b59d08c2..d82d1f7d 100644 --- a/src/fedibook/models/mod.rs +++ b/src/fedibook/models/mod.rs @@ -1,2 +1,4 @@ +pub mod account; pub mod apps; pub mod scope; +pub mod user; diff --git a/src/fedibook/models/user.rs b/src/fedibook/models/user.rs new file mode 100644 index 00000000..841c19a6 --- /dev/null +++ b/src/fedibook/models/user.rs @@ -0,0 +1,31 @@ +use uuid::Uuid; +use chrono::NaiveDateTime; + +use schema::fedibook::users; + +#[derive(Queryable)] +pub(crate) struct User { + id: Uuid, + email: String, + encrypted_password: String, + account_id: Uuid, + admin: bool, + disabled: bool, + unconfirmed_email: String, + confirmation_token: String, + confirmed_at: NaiveDateTime, + confirmation_sent_at: NaiveDateTime, + created_at: NaiveDateTime, + updated_at: NaiveDateTime, +} + +#[derive(Insertable)] +#[table_name="users"] +pub(crate) struct NewUser { + encrypted_password: String, + account_id: Uuid, + unconfirmed_email: String, + confirmation_token: String, + confirmed_at: NaiveDateTime, + confirmation_sent_at: NaiveDateTime, +} diff --git a/src/fedibook/schema.rs b/src/fedibook/schema.rs index 8d1df188..6da3ab89 100644 --- a/src/fedibook/schema.rs +++ b/src/fedibook/schema.rs @@ -28,6 +28,18 @@ pub mod fedibook { /// /// (Automatically generated by Diesel.) display_name -> Varchar, + /// The `created_at` column of the `fedibook.accounts` table. + /// + /// Its SQL type is `Timestamp`. + /// + /// (Automatically generated by Diesel.) + created_at -> Timestamp, + /// The `updated_at` column of the `fedibook.accounts` table. + /// + /// Its SQL type is `Timestamp`. + /// + /// (Automatically generated by Diesel.) + updated_at -> Timestamp, } } From 4266192c98d44cd63bd408fb5f59f55cf9463e60 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Wed, 29 Nov 2017 16:33:02 -0500 Subject: [PATCH 4/7] user sign-up and account confirmation are implemented --- Cargo.lock | 44 +++++++ Cargo.toml | 3 + .../2017-11-28-112517_create_users/up.sql | 8 +- src/bin/main.rs | 6 +- src/fedibook/controllers/auth.rs | 113 ++++++++++++++++++ src/fedibook/controllers/mod.rs | 1 + src/fedibook/forms/auth.rs | 17 +++ src/fedibook/forms/mod.rs | 2 + src/fedibook/lib.rs | 37 ++++++ src/fedibook/models/account.rs | 6 +- src/fedibook/models/user.rs | 31 +++-- src/fedibook/routes/auth.rs | 61 +++++++--- src/fedibook/schema.rs | 12 +- 13 files changed, 295 insertions(+), 46 deletions(-) create mode 100644 src/fedibook/controllers/auth.rs create mode 100644 src/fedibook/forms/auth.rs create mode 100644 src/fedibook/forms/mod.rs diff --git a/Cargo.lock b/Cargo.lock index eaa06d5e..fff34918 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,26 @@ dependencies = [ "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "base64" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "bcrypt" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bitflags" version = "0.7.0" @@ -194,6 +214,8 @@ dependencies = [ name = "fedibook" version = "0.1.0" dependencies = [ + "base64 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bcrypt 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "collection_macros 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -204,6 +226,7 @@ dependencies = [ "libxml 0.0.7481 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2-diesel 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_codegen 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_contrib 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -586,11 +609,28 @@ dependencies = [ "serde_json 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rust-crypto" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-demangle" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-serialize" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "safemem" version = "0.2.0" @@ -827,6 +867,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" +"checksum base64 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5032d51da2741729bfdaeb2664d9b8c6d9fd1e2b90715c660b6def36628499c2" +"checksum bcrypt 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "302595df73812344cb2e6e4e4b2cb6f69171c9ea08a6eb78b43d19124cd62eb7" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d" @@ -892,7 +934,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rocket 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ad92f830d1ae2e9400ff212c949f6101b794cb3f50df975a8278b30280de51e" "checksum rocket_codegen 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a945a800964fd73054d726fcfb52dbb5ed2c77f9c97f94de81f94970779f12ad" "checksum rocket_contrib 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c3aa9888842d219dc3561f7a91f166c48c34746429f8e436d4a8b6edbfdb39" +"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" +"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d9fbe48ead32343b76f544c85953bf260ed39219a8bbbb62cd85f6a00f9644f" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" diff --git a/Cargo.toml b/Cargo.toml index 812dfab2..abc180aa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ name = "fedibook-server" path = "src/bin/main.rs" [dependencies] +base64 = "0.7" +bcrypt = "0.1" collection_macros = "0.2.0" derive_builder = "0.5.0" failure = "0.1.0" @@ -19,6 +21,7 @@ failure_derive = "0.1.1" libxml = "0.0.7481" r2d2 = "0.7" r2d2-diesel = "0.16" +ring = "0.11" rocket = "0.3.3" rocket_codegen = "0.3.3" serde = "1.0.21" diff --git a/migrations/2017-11-28-112517_create_users/up.sql b/migrations/2017-11-28-112517_create_users/up.sql index 0f62b5d9..8984cc1e 100644 --- a/migrations/2017-11-28-112517_create_users/up.sql +++ b/migrations/2017-11-28-112517_create_users/up.sql @@ -1,16 +1,16 @@ CREATE TABLE IF NOT EXISTS fedibook.users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR NOT NULL DEFAULT '', - encrypted_password VARCHAR NOT NULL DEFAULT '', + encrypted_password VARCHAR NOT NULL, account_id UUID NOT NULL, -- flags - admin BOOLEAN NOT NULL, - disabled BOOLEAN NOT NULL, + admin BOOLEAN NOT NULL DEFAULT false, + disabled BOOLEAN NOT NULL DEFAULT false, -- confirmation stuff unconfirmed_email VARCHAR NOT NULL DEFAULT '', - confirmation_token VARCHAR NOT NULL DEFAULT '', + confirmation_token BYTEA NOT NULL, confirmed_at TIMESTAMP WITHOUT TIME ZONE, confirmation_sent_at TIMESTAMP WITHOUT TIME ZONE, diff --git a/src/bin/main.rs b/src/bin/main.rs index 7aa2463e..4c74c7b1 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -9,10 +9,12 @@ extern crate rocket_contrib; extern crate serde; extern crate r2d2; extern crate r2d2_diesel; +extern crate ring; extern crate diesel; extern crate _fedibook as fedibook; +use ring::rand::SystemRandom; use rocket::Rocket; use rocket_contrib::Template; use diesel::pg::PgConnection; @@ -37,8 +39,10 @@ fn app() -> Rocket { fedibook::routes::auth::sign_in_form, fedibook::routes::auth::sign_up, fedibook::routes::auth::sign_in, + fedibook::routes::auth::confirm, ]) - .attach(Template::fairing()); + .attach(Template::fairing()) + .manage(SystemRandom::new()); // we need an instance of the app to access the config values in Rocket.toml, // so we pass it to the db_pool function, get the pool, and _then_ return the instance diff --git a/src/fedibook/controllers/auth.rs b/src/fedibook/controllers/auth.rs new file mode 100644 index 00000000..6e6673b6 --- /dev/null +++ b/src/fedibook/controllers/auth.rs @@ -0,0 +1,113 @@ +use base64; +use bcrypt::{DEFAULT_COST, hash}; +use ring::rand::SecureRandom; +use diesel; +use diesel::LoadDsl; +use diesel::pg::PgConnection; +use diesel::prelude::*; +use failure::Error; +use chrono::Utc; + +use forms::auth::SignUpForm; +use models::account::{Account, NewAccount}; +use models::user::{NewUser, User}; +use schema::fedibook::{accounts, users}; + +#[derive(Fail, Debug)] +pub(crate) enum SignUpFail { + #[fail(display = "Passwords do not match")] + PasswordMatchError, + #[fail(display = "Failed to insert account into database")] + AccountCreateError, + #[fail(display = "Failed to insert user into database")] + UserCreateError, + #[fail(display = "Failed to hash password")] + PasswordHashError, +} + +pub(crate) fn create_user_and_account(form: SignUpForm, gen: &T, db: &PgConnection) -> Result<(), SignUpFail> { + // validation goes here + if form.password != form.password_confirmation { + return Err(SignUpFail::PasswordMatchError); + } + let account = NewAccount { + username: form.username, + }; + let account: Account = match diesel::insert(&account).into(accounts::table).get_result(db) { + Ok(account) => account, + Err(e) => return Err(SignUpFail::AccountCreateError), + }; + + let mut token: Vec = vec![0; 16]; + generate_token(gen, &mut token)?; + let strtoken = base64::encode(&token); + + let now = Utc::now().naive_utc(); + + let hashed_password = hash_password(&form.password)?; + let user = NewUser { + encrypted_password: hashed_password, + account_id: account.id, + unconfirmed_email: form.email, + confirmation_token: token, + confirmation_sent_at: now, + }; + + let user: User = match diesel::insert(&user).into(users::table).get_result(db) { + Ok(user) => user, + Err(e) => return Err(SignUpFail::UserCreateError), + }; + + // just printing this out for now so we can copy/paste into the browser to confirm accounts, + // but obviously this will need to be emailed to the user + println!("confirmation token url: /auth/confirmation?token={}", &strtoken); + + Ok(()) +} + +#[derive(Debug, Fail)] +pub(crate) enum ConfirmAccountFail { + #[fail(display = "token was not found")] + TokenNotFound, + #[fail(display = "failed to decode confirmation token")] + Base64DecodeError, + #[fail(display = "failed to update the user record")] + UpdateFail, +} + +pub(crate) fn confirm_account(token: &str, db: &PgConnection) -> Result { + use schema::fedibook::users::dsl::*; + + let token = match base64::decode(token) { + Ok(t) => t, + Err(_) => return Err(ConfirmAccountFail::Base64DecodeError), + }; + let mut user = match users.filter(confirmation_token.eq(token)).first::(db) { + Ok(user) => user, + Err(e) => { + println!("Err: {:#?}", e); + return Err(ConfirmAccountFail::TokenNotFound); + } + }; + + let user = match user.confirm().save_changes::(db) { + Ok(user) => user, + Err(e) => { + println!("Err: {:#?}", e); + return Err(ConfirmAccountFail::UpdateFail); + }, + }; + Ok(user) +} + +fn hash_password(password: &str) -> Result { + Ok(match hash(password, DEFAULT_COST) { + Ok(h) => h, + Err(e) => return Err(SignUpFail::PasswordHashError), + }) +} + +fn generate_token(gen: &T, buffer: &mut [u8]) -> Result<(), SignUpFail> { + gen.fill(buffer); + Ok(()) +} diff --git a/src/fedibook/controllers/mod.rs b/src/fedibook/controllers/mod.rs index c2b34bdc..8207667c 100644 --- a/src/fedibook/controllers/mod.rs +++ b/src/fedibook/controllers/mod.rs @@ -1 +1,2 @@ pub mod apps; +pub mod auth; diff --git a/src/fedibook/forms/auth.rs b/src/fedibook/forms/auth.rs new file mode 100644 index 00000000..24b4797d --- /dev/null +++ b/src/fedibook/forms/auth.rs @@ -0,0 +1,17 @@ +#[derive(Debug, Clone, PartialEq, FromForm)] +pub(crate) struct SignUpForm { + pub csrf_token: String, + pub username: String, + pub email: String, + pub password: String, + pub password_confirmation: String, +} + +#[derive(Debug, Clone, PartialEq, FromForm)] +pub(crate) struct SignInForm { + csrf_token: String, + email: String, + password: String, +} + + diff --git a/src/fedibook/forms/mod.rs b/src/fedibook/forms/mod.rs new file mode 100644 index 00000000..ed9d022e --- /dev/null +++ b/src/fedibook/forms/mod.rs @@ -0,0 +1,2 @@ +pub mod auth; + diff --git a/src/fedibook/lib.rs b/src/fedibook/lib.rs index 6ac658b9..6184cc2d 100644 --- a/src/fedibook/lib.rs +++ b/src/fedibook/lib.rs @@ -4,9 +4,14 @@ #![feature(custom_derive)] #![plugin(rocket_codegen)] +extern crate base64; +extern crate bcrypt; extern crate chrono; +extern crate ring; extern crate rocket; extern crate failure; +extern crate r2d2; +extern crate r2d2_diesel; extern crate rocket_contrib; extern crate serde; extern crate uuid; @@ -17,7 +22,39 @@ extern crate uuid; #[macro_use] extern crate diesel; #[macro_use] extern crate diesel_codegen; +use std::ops::Deref; +use rocket::http::Status; +use rocket::request::{self, FromRequest}; +use rocket::{Request, State, Outcome}; +use r2d2_diesel::ConnectionManager; +use diesel::pg::PgConnection; + pub mod models; pub mod controllers; +pub mod forms; pub mod routes; pub mod schema; + +type Pool = r2d2::Pool>; + +pub struct DbConn(pub r2d2::PooledConnection>); + +impl<'l, 'r> FromRequest<'l, 'r> for DbConn { + type Error = (); + + fn from_request(request: &'l Request<'r>) -> request::Outcome { + let pool = request.guard::>()?; + match pool.get() { + Ok(conn) => Outcome::Success(DbConn(conn)), + Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())), + } + } +} + +impl Deref for DbConn { + type Target = PgConnection; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/src/fedibook/models/account.rs b/src/fedibook/models/account.rs index c88f309e..0cdd5f9f 100644 --- a/src/fedibook/models/account.rs +++ b/src/fedibook/models/account.rs @@ -5,7 +5,7 @@ use schema::fedibook::accounts; #[derive(Queryable)] pub(crate) struct Account { - id: Uuid, + pub id: Uuid, username: String, domain: Option, display_name: String, @@ -16,7 +16,5 @@ pub(crate) struct Account { #[derive(Insertable)] #[table_name="accounts"] pub(crate) struct NewAccount { - username: String, - domain: Option, - display_name: String, + pub username: String, } diff --git a/src/fedibook/models/user.rs b/src/fedibook/models/user.rs index 841c19a6..3f56df7c 100644 --- a/src/fedibook/models/user.rs +++ b/src/fedibook/models/user.rs @@ -1,9 +1,9 @@ use uuid::Uuid; -use chrono::NaiveDateTime; +use chrono::{Utc, NaiveDateTime}; use schema::fedibook::users; -#[derive(Queryable)] +#[derive(Queryable, Identifiable, AsChangeset, Debug)] pub(crate) struct User { id: Uuid, email: String, @@ -11,21 +11,28 @@ pub(crate) struct User { account_id: Uuid, admin: bool, disabled: bool, - unconfirmed_email: String, - confirmation_token: String, - confirmed_at: NaiveDateTime, - confirmation_sent_at: NaiveDateTime, + pub unconfirmed_email: String, + confirmation_token: Vec, + confirmed_at: Option, + confirmation_sent_at: Option, created_at: NaiveDateTime, updated_at: NaiveDateTime, } +impl User { + pub(crate) fn confirm(&mut self) -> &mut Self { + self.email = self.unconfirmed_email.clone(); + self.confirmed_at = Some(Utc::now().naive_utc()); + self + } +} + #[derive(Insertable)] #[table_name="users"] pub(crate) struct NewUser { - encrypted_password: String, - account_id: Uuid, - unconfirmed_email: String, - confirmation_token: String, - confirmed_at: NaiveDateTime, - confirmation_sent_at: NaiveDateTime, + pub encrypted_password: String, + pub account_id: Uuid, + pub unconfirmed_email: String, + pub confirmation_token: Vec, + pub confirmation_sent_at: NaiveDateTime, } diff --git a/src/fedibook/routes/auth.rs b/src/fedibook/routes/auth.rs index 43792cdd..c63c9e3a 100644 --- a/src/fedibook/routes/auth.rs +++ b/src/fedibook/routes/auth.rs @@ -1,22 +1,14 @@ -use rocket::response::Redirect; +use ring::rand::SystemRandom; +use rocket::State; +use rocket::response::{self, Redirect}; use rocket::request::Form; use rocket_contrib::Template; +use diesel::pg::PgConnection; +use r2d2; +use r2d2_diesel::ConnectionManager; -#[derive(Debug, Clone, PartialEq, FromForm)] -struct SignUpForm { - csrf_token: String, - username: String, - email: String, - password: String, - password_confirmation: String, -} - -#[derive(Debug, Clone, PartialEq, FromForm)] -struct SignInForm { - csrf_token: String, - email: String, - password: String, -} +use DbConn; +use forms::auth::{SignUpForm, SignInForm}; #[get("/auth/sign_up")] fn sign_up_form() -> Template { @@ -31,9 +23,18 @@ fn sign_in_form() -> Template { } #[post("/auth", data = "
")] -fn sign_up(form: Form) -> Redirect { - println!("got sign up form: {:#?}", form.into_inner()); - Redirect::to("/auth/sign_in") +fn sign_up(form: Form, gen: State, db: DbConn) -> Redirect { + use controllers::auth; + + match auth::create_user_and_account(form.into_inner(), gen.inner(), &db) { + Ok(_) => Redirect::to("/auth/sign_in"), + Err(e) => { + // this is obviously inadequate for now, we'll need + // to send an error message up to the user as well + println!("unable to create account: {:#?}", e); + Redirect::to("/auth/sign_up") + } + } } #[post("/auth/sign_in", data = "")] @@ -41,3 +42,25 @@ fn sign_in(form: Form) -> Redirect { println!("got sign in form: {:#?}", form.into_inner()); Redirect::to("/app") } + +#[derive(FromForm)] +struct ConfirmToken { + pub token: String, +} + +#[derive(Debug, Fail)] +#[fail(display = "Failed to confirm account")] +struct ConfirmError; + +#[get("/auth/confirmation?")] +fn confirm(token: ConfirmToken, db: DbConn) -> Result { + use controllers::auth; + + Ok(match auth::confirm_account(&token.token, &db) { + Ok(_) => Redirect::to("/auth/sign_in"), + Err(e) => { + println!("unable to confirm account: {:#?}", e); + return Err(ConfirmError); + } + }) +} diff --git a/src/fedibook/schema.rs b/src/fedibook/schema.rs index 6da3ab89..c9e43e13 100644 --- a/src/fedibook/schema.rs +++ b/src/fedibook/schema.rs @@ -3,7 +3,7 @@ pub mod fedibook { /// Representation of the `fedibook.accounts` table. /// /// (Automatically generated by Diesel.) - accounts (id) { + fedibook.accounts (id) { /// The `id` column of the `fedibook.accounts` table. /// /// Its SQL type is `Uuid`. @@ -42,12 +42,12 @@ pub mod fedibook { updated_at -> Timestamp, } } - + table! { /// Representation of the `fedibook.users` table. /// /// (Automatically generated by Diesel.) - users (id) { + fedibook.users (id) { /// The `id` column of the `fedibook.users` table. /// /// Its SQL type is `Uuid`. @@ -92,10 +92,10 @@ pub mod fedibook { unconfirmed_email -> Varchar, /// The `confirmation_token` column of the `fedibook.users` table. /// - /// Its SQL type is `Varchar`. + /// Its SQL type is `Bytea`. /// /// (Automatically generated by Diesel.) - confirmation_token -> Varchar, + confirmation_token -> Bytea, /// The `confirmed_at` column of the `fedibook.users` table. /// /// Its SQL type is `Nullable`. @@ -122,6 +122,6 @@ pub mod fedibook { updated_at -> Timestamp, } } - + joinable!(users -> accounts (account_id)); } From db31c6ad9e165125af7aa62320bfa62dcdc522f0 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Thu, 30 Nov 2017 10:37:48 -0500 Subject: [PATCH 5/7] Sign in is implemented --- src/bin/main.rs | 4 ++- src/fedibook/controllers/auth.rs | 38 +++++++++++++++++++++++++-- src/fedibook/forms/auth.rs | 6 ++--- src/fedibook/lib.rs | 2 +- src/fedibook/models/account.rs | 2 +- src/fedibook/models/user.rs | 44 +++++++++++++++++++++++++++++--- src/fedibook/routes/app.rs | 20 +++++++++++++++ src/fedibook/routes/auth.rs | 18 ++++++++++--- src/fedibook/routes/mod.rs | 1 + templates/home.html.hbs | 5 ++++ 10 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 src/fedibook/routes/app.rs create mode 100644 templates/home.html.hbs diff --git a/src/bin/main.rs b/src/bin/main.rs index 4c74c7b1..662decfc 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,4 +1,3 @@ -#![feature(try_from)] #![feature(plugin)] #![feature(custom_derive)] #![plugin(rocket_codegen)] @@ -40,6 +39,9 @@ fn app() -> Rocket { fedibook::routes::auth::sign_up, fedibook::routes::auth::sign_in, fedibook::routes::auth::confirm, + + fedibook::routes::app::home, + fedibook::routes::app::home_redirect, ]) .attach(Template::fairing()) .manage(SystemRandom::new()); diff --git a/src/fedibook/controllers/auth.rs b/src/fedibook/controllers/auth.rs index 6e6673b6..9e9fdcf2 100644 --- a/src/fedibook/controllers/auth.rs +++ b/src/fedibook/controllers/auth.rs @@ -1,5 +1,5 @@ use base64; -use bcrypt::{DEFAULT_COST, hash}; +use bcrypt::{DEFAULT_COST, hash, verify}; use ring::rand::SecureRandom; use diesel; use diesel::LoadDsl; @@ -8,7 +8,8 @@ use diesel::prelude::*; use failure::Error; use chrono::Utc; -use forms::auth::SignUpForm; +use Pool; +use forms::auth::{SignInForm, SignUpForm}; use models::account::{Account, NewAccount}; use models::user::{NewUser, User}; use schema::fedibook::{accounts, users}; @@ -107,7 +108,40 @@ fn hash_password(password: &str) -> Result { }) } +fn check_password(password: &str, hash: &str) -> Result<(), SignInFail> { + if let Err(e) = verify(password, hash) { + return Err(SignInFail::WrongPassword); + } + Ok(()) +} + fn generate_token(gen: &T, buffer: &mut [u8]) -> Result<(), SignUpFail> { gen.fill(buffer); Ok(()) } + +#[derive(Fail, Debug)] +pub(crate) enum SignInFail { + #[fail(display = "user not found")] + UserNotFound, + #[fail(display = "password is incorrect")] + WrongPassword, +} + +pub(crate) fn sign_in(form: &SignInForm, db: &PgConnection) -> Result { + use schema::fedibook::users::dsl::*; + + // check csrf token + + let user = match users.filter(email.eq(&form.email)).first::(db) { + Ok(user) => user, + Err(e) => { + println!("user {} not found", &form.email); + return Err(SignInFail::UserNotFound); + }, + }; + + check_password(&form.password, &user.encrypted_password)?; + + Ok(user) +} diff --git a/src/fedibook/forms/auth.rs b/src/fedibook/forms/auth.rs index 24b4797d..25c525e8 100644 --- a/src/fedibook/forms/auth.rs +++ b/src/fedibook/forms/auth.rs @@ -9,9 +9,9 @@ pub(crate) struct SignUpForm { #[derive(Debug, Clone, PartialEq, FromForm)] pub(crate) struct SignInForm { - csrf_token: String, - email: String, - password: String, + pub csrf_token: String, + pub email: String, + pub password: String, } diff --git a/src/fedibook/lib.rs b/src/fedibook/lib.rs index 6184cc2d..21b98eb2 100644 --- a/src/fedibook/lib.rs +++ b/src/fedibook/lib.rs @@ -35,7 +35,7 @@ pub mod forms; pub mod routes; pub mod schema; -type Pool = r2d2::Pool>; +pub type Pool = r2d2::Pool>; pub struct DbConn(pub r2d2::PooledConnection>); diff --git a/src/fedibook/models/account.rs b/src/fedibook/models/account.rs index 0cdd5f9f..89a12f04 100644 --- a/src/fedibook/models/account.rs +++ b/src/fedibook/models/account.rs @@ -3,7 +3,7 @@ use chrono::NaiveDateTime; use schema::fedibook::accounts; -#[derive(Queryable)] +#[derive(Queryable, Identifiable)] pub(crate) struct Account { pub id: Uuid, username: String, diff --git a/src/fedibook/models/user.rs b/src/fedibook/models/user.rs index 3f56df7c..025bf704 100644 --- a/src/fedibook/models/user.rs +++ b/src/fedibook/models/user.rs @@ -1,13 +1,23 @@ +use std::sync::Arc; + +use rocket::{Outcome, Request, State}; +use rocket::http::Status; +use rocket::request::{self, FromRequest}; +use rocket::outcome::IntoOutcome; +use diesel::prelude::*; use uuid::Uuid; use chrono::{Utc, NaiveDateTime}; +use {DbConn, Pool}; +use models::account::Account; use schema::fedibook::users; -#[derive(Queryable, Identifiable, AsChangeset, Debug)] +#[derive(Queryable, Identifiable, AsChangeset, Associations, Debug)] +#[belongs_to(Account, foreign_key = "account_id")] pub(crate) struct User { - id: Uuid, - email: String, - encrypted_password: String, + pub id: Uuid, + pub email: String, + pub encrypted_password: String, account_id: Uuid, admin: bool, disabled: bool, @@ -25,6 +35,32 @@ impl User { self.confirmed_at = Some(Utc::now().naive_utc()); self } + + pub(crate) fn get(id: &str, db: &PgConnection) -> Option { + use schema::fedibook::users::dsl::*; + users.find(id).first(db).ok() + } +} + +impl<'l, 'r> FromRequest<'l, 'r> for User { + type Error = (); + + fn from_request(request: &'l Request<'r>) -> request::Outcome { + + let pool = request.guard::>()?; + let db = match pool.get() { + Ok(p) => p, + Err(_) => return Outcome::Failure((Status::ServiceUnavailable, ())) + }; + println!("Got db conn"); + let user_id = request.cookies() + .get_private("user_id") + .and_then(|c| Some(c.value().to_string())); + println!("got user id {:#?}", &user_id); + let user = user_id.and_then(|id| User::get(&id, &db)); + println!("got user {:#?}", &user); + user.or_forward(()) + } } #[derive(Insertable)] diff --git a/src/fedibook/routes/app.rs b/src/fedibook/routes/app.rs new file mode 100644 index 00000000..c4f3d78a --- /dev/null +++ b/src/fedibook/routes/app.rs @@ -0,0 +1,20 @@ +use rocket::http::{Cookie, Cookies}; +use rocket::response::{self, Redirect}; +use rocket::request::Form; +use rocket_contrib::Template; + +use models::user::User; +use DbConn; + +#[get("/web")] +fn home(user: User, db: DbConn) -> Template { + let map = hashmap!{ + "email" => user.email, + }; + Template::render("home", map) +} + +#[get("/web", rank = 2)] +fn home_redirect() -> Redirect { + Redirect::to("/auth/sign_in") +} diff --git a/src/fedibook/routes/auth.rs b/src/fedibook/routes/auth.rs index c63c9e3a..4092a28a 100644 --- a/src/fedibook/routes/auth.rs +++ b/src/fedibook/routes/auth.rs @@ -1,5 +1,6 @@ use ring::rand::SystemRandom; use rocket::State; +use rocket::http::{Cookie, Cookies}; use rocket::response::{self, Redirect}; use rocket::request::Form; use rocket_contrib::Template; @@ -38,9 +39,20 @@ fn sign_up(form: Form, gen: State, db: DbConn) -> Redi } #[post("/auth/sign_in", data = "")] -fn sign_in(form: Form) -> Redirect { - println!("got sign in form: {:#?}", form.into_inner()); - Redirect::to("/app") +fn sign_in(form: Form, db: DbConn, mut cookies: Cookies) -> Redirect { + use controllers::auth; + match auth::sign_in(&form.into_inner(), &db) { + Ok(user) => { + let mut cookie = Cookie::new("user_id", user.id.to_string()); + cookie.set_http_only(true); + cookies.add_private(cookie); + Redirect::to("/web") + }, + Err(e) => { + println!("unable to log in: {:#?}", e); + Redirect::to("/auth/sign_in") + } + } } #[derive(FromForm)] diff --git a/src/fedibook/routes/mod.rs b/src/fedibook/routes/mod.rs index 96a0835b..ec72b1ec 100644 --- a/src/fedibook/routes/mod.rs +++ b/src/fedibook/routes/mod.rs @@ -1,2 +1,3 @@ pub mod auth; +pub mod app; pub mod applications; diff --git a/templates/home.html.hbs b/templates/home.html.hbs new file mode 100644 index 00000000..210beadb --- /dev/null +++ b/templates/home.html.hbs @@ -0,0 +1,5 @@ + + + +

Welcome, {{ email }}

+ From 154348eced8d8fc89a6801b6d8c948ab44daeed5 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Thu, 30 Nov 2017 10:47:58 -0500 Subject: [PATCH 6/7] Sign out is implemented --- src/bin/main.rs | 1 + src/fedibook/models/user.rs | 3 --- src/fedibook/routes/auth.rs | 7 +++++++ templates/home.html.hbs | 5 ++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 662decfc..834ab545 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -39,6 +39,7 @@ fn app() -> Rocket { fedibook::routes::auth::sign_up, fedibook::routes::auth::sign_in, fedibook::routes::auth::confirm, + fedibook::routes::auth::sign_out, fedibook::routes::app::home, fedibook::routes::app::home_redirect, diff --git a/src/fedibook/models/user.rs b/src/fedibook/models/user.rs index 025bf704..1b760420 100644 --- a/src/fedibook/models/user.rs +++ b/src/fedibook/models/user.rs @@ -52,13 +52,10 @@ impl<'l, 'r> FromRequest<'l, 'r> for User { Ok(p) => p, Err(_) => return Outcome::Failure((Status::ServiceUnavailable, ())) }; - println!("Got db conn"); let user_id = request.cookies() .get_private("user_id") .and_then(|c| Some(c.value().to_string())); - println!("got user id {:#?}", &user_id); let user = user_id.and_then(|id| User::get(&id, &db)); - println!("got user {:#?}", &user); user.or_forward(()) } } diff --git a/src/fedibook/routes/auth.rs b/src/fedibook/routes/auth.rs index 4092a28a..a5e9548a 100644 --- a/src/fedibook/routes/auth.rs +++ b/src/fedibook/routes/auth.rs @@ -9,6 +9,7 @@ use r2d2; use r2d2_diesel::ConnectionManager; use DbConn; +use models::user::User; use forms::auth::{SignUpForm, SignInForm}; #[get("/auth/sign_up")] @@ -76,3 +77,9 @@ fn confirm(token: ConfirmToken, db: DbConn) -> Result { } }) } + +#[post("/auth/sign_out")] +fn sign_out(user: User, mut cookies: Cookies) -> Redirect { + cookies.remove_private(Cookie::named("user_id")); + Redirect::to("/auth/sign_in") +} diff --git a/templates/home.html.hbs b/templates/home.html.hbs index 210beadb..d64c93f8 100644 --- a/templates/home.html.hbs +++ b/templates/home.html.hbs @@ -1,5 +1,8 @@ -

Welcome, {{ email }}

+ + + +

Welcome, {{ email }}

From 2361bfe0a454eacab60cab519defd2ffb2018226 Mon Sep 17 00:00:00 2001 From: Paul Woolcock Date: Thu, 30 Nov 2017 11:40:54 -0500 Subject: [PATCH 7/7] Small write-up about the incoming pull request --- src/README.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/README.md diff --git a/src/README.md b/src/README.md new file mode 100644 index 00000000..01d933c1 --- /dev/null +++ b/src/README.md @@ -0,0 +1,104 @@ +# Rust backend + +Since the initial PR for this is rather large, I'm including a write-up +here to hopefully aid in the code review process. + +The rust app here uses primarily [Rocket.rs](https://rocket.rs) and +[Diesel](https://diesel.rs), along with a number of smaller crates to +fill in any gaps. There are two primary entry points into the code, +`src/bin/main.rs` and `src/fedibook/lib.rs`. This is a pretty standard +setup for rust projects, in which the bulk of the code is in a +library-style crate (`src/fedibook/`) and the main runnable binary +is a smaller crate that sets up a few things and then calls into the +library crate. Keeping this separation is useful for adding other +binaries down the line, and it doesn't really cost us anything now. + +## src/bin/main.rs + +This is the file that, when compiled, implements the actual runnable +binary. It will be where we set up all the necessary data structures +that the webapp needs to run, gathers config from the user (right now +it's just using the standard `Rocket.toml` file that rocket.rs expects), +and sets up the various routes that are actually defined in the library +crate. + +Currently we are mounting routes under 2 prefixes: `"/"` and +`"/api/v1"`, though there is nothing actually implemented under +`"/api/v1"`, other than a placeholder example route. All the URLs +mounted under `"/"` are routes that you would expect a user to request +in their browser. The routes that are currently written implement a +barebones user login/registration system, though there are still many +things to do to improve that system. + +Routes under the `"/api/v1"` prefix are routes that should not be +directly browsed to, but will use OAuth for authentication, accept and +return JSON, and would primarily be used via XMLHttpRequests from the +browser webapp (or via cURL during development). + +## src/fedibook/ + +This is where the real meat of the application is. The main entry point +for the library crate is `src/fedibook/lib.rs`, that has all the `mod` +statements and such. There are a few directories from here that should +be pretty self-explanatory. `controllers`, `forms`, `models`, and +`routes`. The `routes` module contain the definitions for the actual +endpoints, though I've tried to keep those small and move the bulk of +the logic into the controllers. + +There is a special file, `src/fedibook/schema.rs`, that holds the +generated database schema. This is generated by: + + 1. Installing `diesel_cli`: `$ cargo install diesel_cli --no-default-features --features "postgres"` + 2. Running `diesel print-schema --with-docs -s fedibook > src/fedibook/schema.rs` + +The version of `diesel` that was used to develop this has a small bug in +which the `joinable!()` invocation at the bottom of the schema.rs file +had to be slightly changed, but the next version of `diesel` does not +have that bug and I am working on upgrading `fedibook` to that version. + +## Migrations + +In the `migrations/` directory, you will find all the database +migrations that `diesel` will need to properly set up your database. + +## Templates + +In the `templates/` directory, you will find the templates that `rocket` +uses to serve the login, logout, register, and home pages (barely more +than placeholders right now) + +## In the browser + +To go with the user registration/login system, I have a handful of +(very) barebones templates that can be used to register, login, and +logout in a browser. Assuming that rust, postgres, and diesel are +already installed, the workflow goes like this: + + * start postgres. make sure you can successfully connect to it + * cd into the fedibook directory and set up the database (this is only + necessary the first time): + * make sure diesel can connect to your database: + `export DATABASE_URL="postgres://user:pass@host/dbname"` + * `diesel setup` should create the database + * `diesel migration run` should run all the migrations + * start the app: `cargo run` (or `cargo run --bin fedibook-server` if + you want to be explicit) + * When you see "Rocket has launched from http://...." you should be + able to connect to the running app + * Assuming you run the app on `localhost` and use the `7878` port, you + can browse to `http://localhost:7878/auth/sign_up` and register a + user account + * If the registration succeeds, it will redirect you to + `http://localhost:7878/auth/sign_in`. You won't actually be able to + sign in yet, you have to confirm your account. + * Go back to the command line, you should see a message that has a + path at the end with the token to confirm your account. + * Go to `http://localhost:7878` in your + browser + * If the confirmation succeeded, it should redirect you back to the + `/auth/sign_in` page, where you should be able to log in now. + * If the log in succeeds, it should redirect you to `/web` and show + you a message, and a "logout" button + +Going to `/web` without logging in should redirect you to the login page +