summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kjetil.orbekk@gmail.com>2020-01-29 19:15:28 -0500
committerKjetil Orbekk <kjetil.orbekk@gmail.com>2020-01-29 19:15:28 -0500
commitc8db39dea2cf50dd1fa6c499600e09818b8db44a (patch)
treeb2eb940f9769323cd1d3e1c92bbe3c16d38d9dd6
parent6c16bcd190328443f15029fc3ee2467b6c270eed (diff)
Add database support
-rw-r--r--.env1
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock147
-rw-r--r--Cargo.toml9
-rw-r--r--diesel.toml5
-rw-r--r--migrations/.gitkeep0
-rw-r--r--migrations/00000000000000_diesel_initial_setup/down.sql6
-rw-r--r--migrations/00000000000000_diesel_initial_setup/up.sql36
-rw-r--r--migrations/2020-01-29-094607_create_config/down.sql1
-rw-r--r--migrations/2020-01-29-094607_create_config/up.sql8
-rw-r--r--migrations/2020-01-29-230359_create_users/down.sql1
-rw-r--r--migrations/2020-01-29-230359_create_users/up.sql5
-rw-r--r--src/db.rs36
-rw-r--r--src/error.rs36
-rw-r--r--src/lib.rs51
-rw-r--r--src/main.rs109
-rw-r--r--src/models.rs26
-rw-r--r--src/schema.rs20
-rw-r--r--src/server.rs50
-rw-r--r--src/strava.rs32
20 files changed, 481 insertions, 99 deletions
diff --git a/.env b/.env
new file mode 100644
index 0000000..6235ad4
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+DATABASE_URL=postgres://orbekk@/pjournal_dev
diff --git a/.gitignore b/.gitignore
index 53eaa21..3c18fd1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
/target
**/*.rs.bk
+run.sh
diff --git a/Cargo.lock b/Cargo.lock
index 25a0d41..6afecd5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 9edf61a..070fb3e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 {}
diff --git a/src/lib.rs b/src/lib.rs
index d7f7b98..5f8118b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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(&params);
- let mut res = req.send().unwrap().text();
- println!("{:?}", res);
+ req.send().map(|r| r.json())?
}