diff options
author | Kjetil Orbekk <kjetil.orbekk@gmail.com> | 2020-01-29 19:15:28 -0500 |
---|---|---|
committer | Kjetil Orbekk <kjetil.orbekk@gmail.com> | 2020-01-29 19:15:28 -0500 |
commit | c8db39dea2cf50dd1fa6c499600e09818b8db44a (patch) | |
tree | b2eb940f9769323cd1d3e1c92bbe3c16d38d9dd6 | |
parent | 6c16bcd190328443f15029fc3ee2467b6c270eed (diff) |
Add database support
-rw-r--r-- | .env | 1 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 147 | ||||
-rw-r--r-- | Cargo.toml | 9 | ||||
-rw-r--r-- | diesel.toml | 5 | ||||
-rw-r--r-- | migrations/.gitkeep | 0 | ||||
-rw-r--r-- | migrations/00000000000000_diesel_initial_setup/down.sql | 6 | ||||
-rw-r--r-- | migrations/00000000000000_diesel_initial_setup/up.sql | 36 | ||||
-rw-r--r-- | migrations/2020-01-29-094607_create_config/down.sql | 1 | ||||
-rw-r--r-- | migrations/2020-01-29-094607_create_config/up.sql | 8 | ||||
-rw-r--r-- | migrations/2020-01-29-230359_create_users/down.sql | 1 | ||||
-rw-r--r-- | migrations/2020-01-29-230359_create_users/up.sql | 5 | ||||
-rw-r--r-- | src/db.rs | 36 | ||||
-rw-r--r-- | src/error.rs | 36 | ||||
-rw-r--r-- | src/lib.rs | 51 | ||||
-rw-r--r-- | src/main.rs | 109 | ||||
-rw-r--r-- | src/models.rs | 26 | ||||
-rw-r--r-- | src/schema.rs | 20 | ||||
-rw-r--r-- | src/server.rs | 50 | ||||
-rw-r--r-- | src/strava.rs | 32 |
20 files changed, 481 insertions, 99 deletions
@@ -0,0 +1 @@ +DATABASE_URL=postgres://orbekk@/pjournal_dev @@ -1,2 +1,3 @@ /target **/*.rs.bk +run.sh @@ -2,6 +2,14 @@ # It is not intended for manual editing. [[package]] name = "aho-corasick" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "aho-corasick" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -64,6 +72,18 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "bcrypt" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blowfish 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -80,6 +100,14 @@ dependencies = [ ] [[package]] +name = "block-cipher-trait" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "block-padding" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -88,6 +116,16 @@ dependencies = [ ] [[package]] +name = "blowfish" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "bumpalo" version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -194,6 +232,27 @@ dependencies = [ ] [[package]] +name = "diesel" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel_derives 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "diesel_derives" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "digest" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -202,6 +261,14 @@ dependencies = [ ] [[package]] +name = "dotenv" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "dtoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -862,10 +929,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "pjournal" version = "0.1.0" dependencies = [ + "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bcrypt 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -879,6 +953,14 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "pq-sys" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "proc-macro2" version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -959,6 +1041,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "regex" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex" version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -970,6 +1064,14 @@ dependencies = [ [[package]] name = "regex-syntax" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-util 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1140,6 +1242,19 @@ dependencies = [ name = "serde" version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "serde_json" @@ -1249,6 +1364,14 @@ dependencies = [ [[package]] name = "thread_local" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thread_local" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -1342,6 +1465,11 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "ucd-util" +version = "0.1.7" +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" @@ -1419,6 +1547,11 @@ dependencies = [ ] [[package]] +name = "utf8-ranges" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "vcpkg" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1624,6 +1757,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" @@ -1633,9 +1767,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +"checksum bcrypt 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28dff1c1a22f9401213d983f6c309e807e72c33d5dc5514fe5005b0205c46e8f" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +"checksum blowfish 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aeb80d00f2688459b8542068abd974cfb101e7a82182414a99b5026c0d85cc3" "checksum bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5fb8038c1ddc0a5f73787b130f4cc75151e96ed33e417fde765eb5a81e3532f4" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" @@ -1650,7 +1787,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3" "checksum devise_codegen 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7" "checksum devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487" +"checksum diesel 1.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d7cc03b910de9935007861dce440881f69102aaaedfd4bc5a6f40340ca5840c" +"checksum diesel_derives 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +"checksum dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "400b347fe65ccfbd8f545c9d9a75d04b0caf23fec49aaa838a9a05398f94c019" "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" "checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" @@ -1729,6 +1869,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" +"checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" "checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" @@ -1739,7 +1880,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" "checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87" +"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "checksum regex-syntax 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e734e891f5b408a29efbf8309e656876276f49ab6a6ac208600b4419bd893d90" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0e798e19e258bf6c30a304622e3e9ac820e483b06a1857a026e1f109b113fe4" @@ -1755,6 +1898,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum security-framework 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8ef2429d7cefe5fd28bd1d2ed41c944547d4ff84776f5935b456da44593a16df" "checksum security-framework-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e31493fc37615debb8c5090a7aeb4a9730bc61e77ab10b9af59f1a202284f895" "checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" "checksum serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "eab8f15f15d6c41a154c1b128a22f2dfabe350ef53c40953d84e36155c91192b" "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" "checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" @@ -1768,6 +1912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum tokio 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdd17989496f49cdc57978c96f0c9fe5e4a58a8bddc6813c449a4624f6a030b" @@ -1780,6 +1925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2" +"checksum ucd-util 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5ccdc2daea7cf8bc50cd8710d170a9d816678e54943829c5082bb1594312cf8e" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" @@ -1791,6 +1937,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" +"checksum utf8-ranges 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba" "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" @@ -5,7 +5,14 @@ authors = ["Kjetil Orbekk <kjetil.orbekk@gmail.com>"] edition = "2018" [dependencies] +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" reqwest = { version = "0.10.1", features = ["blocking", "json"] } clap = "2" rocket = "0.4.2" -rocket_contrib = { version = "0.4.2", default-features = false, features = ["handlebars_templates"] }
\ No newline at end of file +rocket_contrib = { version = "0.4.2", default-features = false, features = ["handlebars_templates"] } +diesel = { version = "1.0.0", features = ["postgres"] } +dotenv = "0.9.0" +bcrypt = "0.6" +base64 = "0.11" +rand = "0.7"
\ No newline at end of file diff --git a/diesel.toml b/diesel.toml new file mode 100644 index 0000000..92267c8 --- /dev/null +++ b/diesel.toml @@ -0,0 +1,5 @@ +# For documentation on how to configure this file, +# see diesel.rs/guides/configuring-diesel-cli + +[print_schema] +file = "src/schema.rs" diff --git a/migrations/.gitkeep b/migrations/.gitkeep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/migrations/.gitkeep diff --git a/migrations/00000000000000_diesel_initial_setup/down.sql b/migrations/00000000000000_diesel_initial_setup/down.sql new file mode 100644 index 0000000..a9f5260 --- /dev/null +++ b/migrations/00000000000000_diesel_initial_setup/down.sql @@ -0,0 +1,6 @@ +-- 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. + +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 0000000..d68895b --- /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/2020-01-29-094607_create_config/down.sql b/migrations/2020-01-29-094607_create_config/down.sql new file mode 100644 index 0000000..2e6f861 --- /dev/null +++ b/migrations/2020-01-29-094607_create_config/down.sql @@ -0,0 +1 @@ +DROP TABLE config; diff --git a/migrations/2020-01-29-094607_create_config/up.sql b/migrations/2020-01-29-094607_create_config/up.sql new file mode 100644 index 0000000..ccd1abd --- /dev/null +++ b/migrations/2020-01-29-094607_create_config/up.sql @@ -0,0 +1,8 @@ +CREATE TABLE config ( + strava_client_secret varchar NOT NULL, + strava_client_id varchar NOT NULL, + rocket_secret_key varchar(64) NOT NULL, + singleton bool DEFAULT TRUE PRIMARY KEY, + +CONSTRAINT unique_config CHECK (singleton) +); diff --git a/migrations/2020-01-29-230359_create_users/down.sql b/migrations/2020-01-29-230359_create_users/down.sql new file mode 100644 index 0000000..cc1f647 --- /dev/null +++ b/migrations/2020-01-29-230359_create_users/down.sql @@ -0,0 +1 @@ +DROP TABLE users; diff --git a/migrations/2020-01-29-230359_create_users/up.sql b/migrations/2020-01-29-230359_create_users/up.sql new file mode 100644 index 0000000..4b845dc --- /dev/null +++ b/migrations/2020-01-29-230359_create_users/up.sql @@ -0,0 +1,5 @@ +CREATE TABLE users ( + username varchar NOT NULL PRIMARY KEY, + -- bcrypt with cost 12 + password varchar NOT NULL +); diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..71490d8 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,36 @@ +use crate::models; +use crate::error::Error; +use diesel::connection::Connection; +use diesel::pg::PgConnection; +use diesel::RunQueryDsl; +use rand::Rng; +use rand; +use base64; +use bcrypt; + +pub const COST: u32 = 12; + +pub fn create_config(conn: &PgConnection, config: &models::Config) -> Result<(), Error> { + use crate::schema::config; + + conn.transaction(|| { + diesel::delete(config::table).execute(conn)?; + + diesel::insert_into(config::table) + .values(config) + .execute(conn)?; + Ok(()) + }) +} + +pub fn adduser(conn: &PgConnection, username: &str, password: &str) -> Result<(), Error> { + use crate::schema::users; + + let hashed = bcrypt::hash(password, COST)?; + let rows = diesel::insert_into(users::table) + .values(models::User::new(username, &hashed)).execute(conn)?; + if rows != 1 { + Err(Error::AlreadyExists)?; + } + Ok(()) +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..6ab0741 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,36 @@ +use std::convert::From; +use std::error::Error as StdError; +use bcrypt::BcryptError; +use diesel::result::Error as DieselErr; +use std::fmt; + +#[derive(Debug)] +pub enum Error { + DieselError(DieselErr), + PasswordError(BcryptError), + AlreadyExists, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::DieselError(ref e) => e.fmt(f), + Error::PasswordError(ref e) => e.fmt(f), + Error::AlreadyExists => f.write_str("AlreadyExists"), + } + } +} + +impl From<DieselErr> for Error { + fn from(e: DieselErr) -> Error { + Error::DieselError(e) + } +} + +impl From<BcryptError> for Error { + fn from(e: BcryptError) -> Error { + Error::PasswordError(e) + } +} + +impl StdError for Error {} @@ -2,12 +2,9 @@ #![feature(decl_macro)] #[macro_use] extern crate rocket; -use rocket::response; -use rocket::State; -use rocket_contrib::templates::Template; -use std::collections::HashMap; -mod strava; +#[macro_use] +extern crate diesel; #[derive(Debug)] pub struct Config { @@ -16,41 +13,9 @@ pub struct Config { pub base_url: String, } -#[get("/")] -fn index() -> Template { - let mut context = HashMap::new(); - context.insert("parent", "layout"); - context.insert("message", "Hello, World"); - Template::render("index", context) -} - -#[get("/link_strava_callback?<code>")] -fn link_strava_callback(config: State<Config>, code: String) -> String { - strava::exchange_token(&config.client_id, &config.client_secret, &code); - "OK".to_string() -} - -#[get("/link_strava")] -fn link_strava(config: State<Config>) -> response::Redirect { - response::Redirect::to( - format!( - concat!( - "https://www.strava.com/oauth/authorize?", - "client_id={}&", - "response_type=code&", - "redirect_uri={}&", - "approval_prompt=force&", - "scope=read", - ), - config.client_id, - format!("{}/link_strava_callback", config.base_url)) - ) -} - -pub fn start_server(config: Config) { - rocket::ignite() - .manage(config) - .mount("/", routes![index, link_strava, link_strava_callback]) - .attach(Template::fairing()) - .launch(); -} +pub mod error; +pub mod db; +pub mod models; +mod schema; +pub mod server; +mod strava; diff --git a/src/main.rs b/src/main.rs index 32333f1..f88b7e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,36 +1,85 @@ #[macro_use] extern crate clap; +use clap::App; +use clap::Arg; +use clap::SubCommand; +use diesel::connection::Connection; +use diesel::pg::PgConnection; fn main() { - let matches = clap_app!(pjournal => - (version: "0.1") - (author: "KJ Ørbekk <kj@orbekk.com>") - (about: "Practice Journaling") - (@arg strava_client_secret: - --strava_client_secret - +required +takes_value - "Client secret for strava authentication") - (@arg strava_client_id: - --strava_client_id - +required +takes_value - "Client id for strava authentication") - (@arg base_url: - --base_url - +takes_value - "Endpoint for this web app") - ) - .get_matches(); + let matches = App::new("pjournal") + .version("0.1") + .author("KJ Ørbekk <kj@orbekk.com>") + .about("Practice Journaling") + .arg( + Arg::with_name("database_url") + .long("database_url") + .required(true) + .takes_value(true) + .help("URL to postgresql database"), + ) + .arg( + Arg::with_name("base_url") + .long("base_url") + .takes_value(true) + .help("Endpoint for this web server"), + ) + .subcommand( + SubCommand::with_name("init") + .about("initialize database config") + .arg( + Arg::with_name("rocket_secret_key") + .long("rocket_secret_key") + .takes_value(true) + .required(true) + .help("Secret passed to rocket for encrypted cookies"), + ) + .arg( + Arg::with_name("strava_client_secret") + .long("strava_client_secret") + .takes_value(true) + .required(true) + .help("Client secret for strava authentication"), + ) + .arg( + Arg::with_name("strava_client_id") + .long("strava_client_id") + .takes_value(true) + .required(true) + .help("Client id for strava authentication"), + ), + ) + .subcommand( + SubCommand::with_name("adduser") + .about("add a user account") + .arg(Arg::with_name("USERNAME").required(true).index(1)) + .arg(Arg::with_name("PASSWORD").required(true).index(2)), + ) + .get_matches(); - let config = pjournal::Config { - client_id: matches - .value_of("strava_client_id") - .unwrap().to_string(), - client_secret: matches - .value_of("strava_client_secret") - .unwrap().to_string(), - base_url: matches - .value_of("base_url") - .unwrap_or("http://localhost:8000").to_string(), - }; - pjournal::start_server(config); + let base_url = matches + .value_of("base_url") + .unwrap_or("http://localhost:8000"); + + let db_url = matches.value_of("database_url").unwrap(); + let conn = PgConnection::establish(db_url).unwrap(); + + if let Some(matches) = matches.subcommand_matches("init") { + let config = pjournal::models::Config { + strava_client_id: matches.value_of("strava_client_id").unwrap(), + strava_client_secret: matches.value_of("strava_client_secret").unwrap(), + rocket_secret_key: matches.value_of("rocket_secret_key").unwrap(), + }; + + pjournal::db::create_config(&conn, &config); + } else if let Some(matches) = matches.subcommand_matches("adduser") { + let user = matches.value_of("USERNAME").unwrap(); + let password = matches.value_of("PASSWORD").unwrap(); + pjournal::db::adduser(&conn, user, password).unwrap(); + } else { + let config = pjournal::server::Params { + base_url: base_url.to_string(), + }; + pjournal::server::start(db_url, config); + } } diff --git a/src/models.rs b/src/models.rs new file mode 100644 index 0000000..8bee887 --- /dev/null +++ b/src/models.rs @@ -0,0 +1,26 @@ +use crate::schema::config; +use crate::schema::users; + +#[derive(Insertable, Queryable)] +#[table_name = "config"] +pub struct Config<'a> { + pub strava_client_secret: &'a str, + pub strava_client_id: &'a str, + pub rocket_secret_key: &'a str, +} + +#[derive(Insertable, Queryable)] +#[table_name = "users"] +pub struct User<'a> { + pub username: &'a str, + password: &'a str, +} + +impl<'a> User<'a> { + pub fn new(username: &'a str, password: &'a str) -> User<'a> { + User { + username: username, + password: password, + } + } +} diff --git a/src/schema.rs b/src/schema.rs new file mode 100644 index 0000000..809706c --- /dev/null +++ b/src/schema.rs @@ -0,0 +1,20 @@ +table! { + config (singleton) { + strava_client_secret -> Varchar, + strava_client_id -> Varchar, + rocket_secret_key -> Varchar, + singleton -> Bool, + } +} + +table! { + users (username) { + username -> Varchar, + password -> Varchar, + } +} + +allow_tables_to_appear_in_same_query!( + config, + users, +); diff --git a/src/server.rs b/src/server.rs index 6f05afe..2c7baad 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,11 +1,17 @@ +use rocket::config; +use rocket::config::Environment; +use rocket::config::Value; use rocket::response; use rocket::State; use rocket_contrib::templates::Template; use std::collections::HashMap; -use crate::Config; use crate::strava; +pub struct Params { + pub base_url: String, +} + #[get("/")] fn index() -> Template { let mut context = HashMap::new(); @@ -15,30 +21,36 @@ fn index() -> Template { } #[get("/link_strava_callback?<code>")] -fn link_strava_callback(config: State<Config>, code: String) -> Result<String, impl std::error::Error> { - strava::exchange_token( - &config.client_id, &config.client_secret, &code) +fn link_strava_callback( + config: State<Params>, + code: String, +) -> Result<String, impl std::error::Error> { + strava::exchange_token("&config.client_id", "&config.client_secret", &code) .map(|t| format!("{:#?}", t)) } #[get("/link_strava")] -fn link_strava(config: State<Config>) -> response::Redirect { - response::Redirect::to( - format!( - concat!( - "https://www.strava.com/oauth/authorize?", - "client_id={}&", - "response_type=code&", - "redirect_uri={}&", - "approval_prompt=force&", - "scope=read", - ), - config.client_id, - format!("{}/link_strava_callback", config.base_url)) - ) +fn link_strava(config: State<Params>) -> response::Redirect { + response::Redirect::to(format!( + concat!( + "https://www.strava.com/oauth/authorize?", + "client_id={}&", + "response_type=code&", + "redirect_uri={}&", + "approval_prompt=force&", + "scope=read", + ), + "config.client_id", + format!("{}/link_strava_callback", config.base_url) + )) } -pub fn start(config: Config) { +pub fn start(db_url: &str, config: Params) { + let mut database_config = HashMap::new(); + let mut databases = HashMap::new(); + database_config.insert("url", Value::from(db_url)); + databases.insert("db", Value::from(database_config)); + rocket::ignite() .manage(config) .mount("/", routes![index, link_strava, link_strava_callback]) diff --git a/src/strava.rs b/src/strava.rs index 490964b..dcd8dc1 100644 --- a/src/strava.rs +++ b/src/strava.rs @@ -1,15 +1,35 @@ use reqwest; +use serde::Deserialize; +use serde::Serialize; + +#[derive(Serialize, Deserialize, Debug)] +pub struct AthleteSummary { + id: i64, + username: String, + firstname: String, + lastname: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Token { + expires_in: i64, + refresh_token: String, + access_token: String, + athlete: AthleteSummary, +} pub fn exchange_token( client_id: &str, client_secret: &str, - code: &str) { + code: &str, +) -> Result<Token, reqwest::Error> { let client = reqwest::blocking::Client::new(); - let params = [("client_id", client_id), - ("client_secret", client_secret), - ("code", code)]; + let params = [ + ("client_id", client_id), + ("client_secret", client_secret), + ("code", code), + ]; let uri = "https://www.strava.com/oauth/token"; let req = client.post(uri).form(¶ms); - let mut res = req.send().unwrap().text(); - println!("{:?}", res); + req.send().map(|r| r.json())? } |