refactor package
This commit is contained in:
1 parent
8b1f4b3005
commit
f6e4eec00d
12 files changed
+406
-230
No files matched your search
Generated
+176
-69
@@ -838,7 +838,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper",
|
||||
"sync_wrapper 0.1.2",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
@@ -3021,6 +3021,7 @@ dependencies = [
|
||||
"errors",
|
||||
"jwt-simple",
|
||||
"my-workspace-hack",
|
||||
"reqwest 0.12.7",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -3413,19 +3414,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.26.0"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
|
||||
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
"hyper 1.3.1",
|
||||
"hyper-util",
|
||||
"rustls 0.22.4",
|
||||
"rustls 0.23.13",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"webpki-roots 0.26.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3673,7 +3675,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"redis_common",
|
||||
"redis_schema",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -4568,7 +4570,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"rustls-pki-types",
|
||||
"semver 1.0.23",
|
||||
"serde",
|
||||
@@ -5093,7 +5095,7 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall 0.5.2",
|
||||
"smallvec 1.13.2",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5518,6 +5520,54 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684"
|
||||
dependencies = [
|
||||
"bytes 1.6.0",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.13",
|
||||
"socket2",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6"
|
||||
dependencies = [
|
||||
"bytes 1.6.0",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.13",
|
||||
"slab",
|
||||
"thiserror",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
@@ -5908,8 +5958,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"sync_wrapper 0.1.2",
|
||||
"system-configuration 0.5.1",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-util",
|
||||
@@ -5918,14 +5968,14 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winreg 0.50.0",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.4"
|
||||
version = "0.12.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10"
|
||||
checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.6.0",
|
||||
@@ -5949,14 +5999,15 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls 0.22.4",
|
||||
"quinn",
|
||||
"rustls 0.23.13",
|
||||
"rustls-pemfile 2.1.2",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"sync_wrapper 1.0.1",
|
||||
"system-configuration 0.6.1",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
@@ -5966,7 +6017,7 @@ dependencies = [
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots 0.26.2",
|
||||
"winreg 0.52.0",
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6157,6 +6208,12 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
@@ -6201,14 +6258,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.22.4"
|
||||
version = "0.23.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
|
||||
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki 0.102.4",
|
||||
"rustls-webpki 0.102.8",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -6250,9 +6307,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.4"
|
||||
version = "0.102.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
|
||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -7137,7 +7194,7 @@ dependencies = [
|
||||
"redis_common",
|
||||
"redis_schema",
|
||||
"regex",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"reusable_types",
|
||||
"rust-s3",
|
||||
"serde",
|
||||
@@ -7480,6 +7537,15 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.5.1"
|
||||
@@ -7488,7 +7554,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
"system-configuration-sys 0.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"core-foundation",
|
||||
"system-configuration-sys 0.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7501,6 +7578,16 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-deps"
|
||||
version = "6.2.2"
|
||||
@@ -7594,7 +7681,7 @@ dependencies = [
|
||||
"easyenv",
|
||||
"log",
|
||||
"my-workspace-hack",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
@@ -7796,11 +7883,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
|
||||
dependencies = [
|
||||
"rustls 0.22.4",
|
||||
"rustls 0.23.13",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
]
|
||||
@@ -8101,7 +8188,7 @@ dependencies = [
|
||||
"my-workspace-hack",
|
||||
"mysql_queries",
|
||||
"r2d2_redis",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -8292,7 +8379,7 @@ dependencies = [
|
||||
"actix-web",
|
||||
"mime_guess",
|
||||
"regex",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -8572,7 +8659,7 @@ dependencies = [
|
||||
"log",
|
||||
"my-workspace-hack",
|
||||
"once_cell",
|
||||
"reqwest 0.12.4",
|
||||
"reqwest 0.12.7",
|
||||
"rss",
|
||||
"scraper",
|
||||
"serde",
|
||||
@@ -8662,7 +8749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
||||
dependencies = [
|
||||
"windows-core 0.52.0",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8680,7 +8767,37 @@ version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
|
||||
dependencies = [
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
|
||||
dependencies = [
|
||||
"windows-result",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8698,7 +8815,7 @@ version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8718,18 +8835,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8740,9 +8857,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
@@ -8752,9 +8869,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
@@ -8764,15 +8881,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
@@ -8782,9 +8899,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
@@ -8794,9 +8911,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
@@ -8806,9 +8923,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
@@ -8818,9 +8935,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
@@ -8850,16 +8967,6 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
|
||||
@@ -29,6 +29,8 @@ errors = { path = "../../errors" }
|
||||
jwt-simple = { version = "0.12.10" , default-features=false, features=["pure-rust"] }
|
||||
base64 = "0.13"
|
||||
|
||||
reqwest = "0.12.7"
|
||||
|
||||
# Serialization
|
||||
serde = "1.0.125"
|
||||
serde_derive = "1.0.125"
|
||||
|
||||
+2
-6
@@ -1,11 +1,7 @@
|
||||
use crate::certs::key_map::KeyMap;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use jwt_simple::prelude::RS256PublicKey;
|
||||
use serde_derive::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Map of JWK `kid` to `RS256PublicKey`.
|
||||
/// (JWK sets typically contain more than one key.)
|
||||
pub type KeyMap = HashMap<String, RS256PublicKey>;
|
||||
|
||||
/// Parse Google's JWK keys into usable public keys.
|
||||
/// Grab Google's keys from here: https://www.googleapis.com/oauth2/v3/certs
|
||||
@@ -67,7 +63,7 @@ pub struct JsonKey {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::jwk_to_public_key::jwk_to_public_key;
|
||||
use crate::certs::jwk_to_public_key::jwk_to_public_key;
|
||||
use jwt_simple::algorithms::RSAPublicKeyLike;
|
||||
use std::fs::read_to_string;
|
||||
use testing::test_file_path::test_file_path;
|
||||
@@ -0,0 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
use jwt_simple::algorithms::RS256PublicKey;
|
||||
|
||||
/// Map of JWK `kid` to `RS256PublicKey`.
|
||||
/// (JWK sets typically contain more than one key.)
|
||||
pub type KeyMap = HashMap<String, RS256PublicKey>;
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod jwk_to_public_key;
|
||||
pub mod key_map;
|
||||
@@ -0,0 +1,29 @@
|
||||
use crate::claims::google_custom_claims::GoogleCustomClaims;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use jwt_simple::claims::{Audiences, JWTClaims};
|
||||
|
||||
pub struct Claims {
|
||||
pub (crate) claims: JWTClaims<GoogleCustomClaims>,
|
||||
}
|
||||
|
||||
impl Claims {
|
||||
pub fn email(&self) -> Option<&str> {
|
||||
self.claims.custom.email.as_deref()
|
||||
}
|
||||
|
||||
pub fn email_verified(&self) -> bool {
|
||||
self.claims.custom.email_verified.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Determine if the claim audience is as expected.
|
||||
/// This is necessary so third parties don't send claims signed on their behalf by Google.
|
||||
pub fn audience_matches(&self, audience: &str) -> AnyhowResult<bool> {
|
||||
match self.claims.audiences.as_ref() {
|
||||
Some(Audiences::AsString(claim_audience)) => Ok(claim_audience.eq(audience)),
|
||||
Some(Audiences::AsSet(audiences)) => Ok(audiences.contains(audience)),
|
||||
_ => Err(anyhow!("Invalid audience type")),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(bt,2024-09-20): Other fields if important.
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// Extra Payload of Google Sign In JWT
|
||||
/// https://developers.google.com/identity/openid-connect/openid-connect
|
||||
/// https://stackoverflow.com/questions/31056412/what-all-these-fields-mean
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
pub struct GoogleCustomClaims {
|
||||
/// The user's email address. Provided only if you included the email scope in your
|
||||
/// request. The value of this claim may not be unique to this account and could
|
||||
/// change over time, therefore you should not use this value as the primary identifier
|
||||
/// to link to your user record. You also can't rely on the domain of the email claim
|
||||
/// to identify users of Google Workspace or Cloud organizations; use the hd claim instead.
|
||||
pub email: Option<String>,
|
||||
|
||||
/// True if the user's e-mail address has been verified; otherwise false.
|
||||
pub email_verified: Option<bool>,
|
||||
|
||||
/// The user's full name, in a displayable form. (See Google documentation)
|
||||
pub name: Option<String>,
|
||||
|
||||
/// The user's given name(s) or first name(s). Might be provided when a name claim is present.
|
||||
pub given_name: Option<String>,
|
||||
|
||||
/// The user's surname(s) or last name(s). Might be provided when a name claim is present.
|
||||
pub family_name: Option<String>,
|
||||
|
||||
/// The client_id of the authorized presenter. This claim is only needed when the party
|
||||
/// requesting the ID token is not the same as the audience of the ID token. This may be
|
||||
/// the case at Google for hybrid apps where a web application and Android app have a
|
||||
/// different OAuth 2.0 client_id but share the same Google APIs project.
|
||||
pub azp: Option<String>,
|
||||
|
||||
/// An identifier for the user, unique among all Google accounts and never reused.
|
||||
/// A Google account can have multiple email addresses at different points in time,
|
||||
/// but the sub value is never changed. Use sub within your application as the
|
||||
/// unique-identifier key for the user. Maximum length of 255 case-sensitive ASCII
|
||||
/// characters.
|
||||
pub sub: Option<String>,
|
||||
|
||||
/// The URL of the user's profile picture. Might be provided when:
|
||||
/// - The request scope included the string "profile"
|
||||
/// - The ID token is returned from a token refresh
|
||||
/// When picture claims are present, you can use them to update your app's user records.
|
||||
/// Note that this claim is never guaranteed to be present.
|
||||
pub picture: Option<String>,
|
||||
|
||||
// Other fields are pulled out of the custom payload:
|
||||
|
||||
// /// The audience that this ID token is intended for. It must be one of the
|
||||
// /// OAuth 2.0 client IDs of your application.
|
||||
// /// NB: You must check that this matches the audience (the app client id)
|
||||
// pub aud: Option<String>,
|
||||
|
||||
// /// The Issuer Identifier for the Issuer of the response.
|
||||
// /// Always `https://accounts.google.com` or `accounts.google.com` for Google ID tokens.
|
||||
// /// NB: You must check that this matches the issuer.
|
||||
// pub iss: Option<String>,
|
||||
|
||||
// pub nbf: Option<String>,
|
||||
// pub jti: Option<String>,
|
||||
// pub iat: Option<String>,
|
||||
// pub exp: Option<String>,
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod claims;
|
||||
pub mod google_custom_claims;
|
||||
@@ -0,0 +1,98 @@
|
||||
use crate::claims::claims::Claims;
|
||||
use crate::claims::google_custom_claims::GoogleCustomClaims;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
use jwt_simple::algorithms::RS256PublicKey;
|
||||
use jwt_simple::algorithms::RSAPublicKeyLike;
|
||||
use jwt_simple::common::VerificationOptions;
|
||||
/*
|
||||
Example payload:
|
||||
iss https://accounts.google.com
|
||||
azp 788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com
|
||||
aud 788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com
|
||||
sub 113101967612396793777
|
||||
email vocodes2020@gmail.com
|
||||
email_verified true
|
||||
nbf 1726786100
|
||||
name Vocodes Vocodes
|
||||
picture https://lh3.googleusercontent.com/a/ACg8ocLz2-2OaAm0MQxR6j8CNr-Po8_Xr-aryATiCn4c0i_TuDmL_g=s96-c
|
||||
given_name Vocodes
|
||||
family_name Vocodes
|
||||
iat 1726786400
|
||||
exp 1726790000
|
||||
jti 4d44eeac06ce79fc0ab2270cfeea30d8acf77613
|
||||
*/
|
||||
|
||||
/// Decode a Google Sign In JWT.
|
||||
/// Verification options can be supplied to increase clock skew tolerance, etc.
|
||||
pub fn decode_and_verify_token_claims(key: &RS256PublicKey, token: &str, options: Option<VerificationOptions>) -> AnyhowResult<Claims> {
|
||||
let claims = key.verify_token::<GoogleCustomClaims>(token, options)?;
|
||||
|
||||
match claims.issuer.as_deref() {
|
||||
Some("https://accounts.google.com" | "accounts.google.com") => {} // Permitted
|
||||
_ => {
|
||||
return Err(anyhow!("Invalid issuer: {:?}", claims.issuer));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Claims {
|
||||
claims,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::certs::jwk_to_public_key::jwk_to_public_key;
|
||||
use crate::decode_and_verify_token_claims::decode_and_verify_token_claims;
|
||||
use coarsetime::Duration;
|
||||
use jwt_simple::claims::Audiences;
|
||||
use jwt_simple::prelude::VerificationOptions;
|
||||
use std::fs::read_to_string;
|
||||
use testing::test_file_path::test_file_path;
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
let jwk_file = test_file_path("test_data/crypto/google_signin.jwk").unwrap();
|
||||
let jwk_payload = read_to_string(jwk_file).unwrap();
|
||||
let key_map = jwk_to_public_key(&jwk_payload).unwrap();
|
||||
|
||||
let credential = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImIyNjIwZDVlN2YxMzJiNTJhZmU4ODc1Y2RmMzc3NmMwNjQyNDlkMDQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI3ODg4NDMwMzQyMzctdXFjZzh0YmdvZnJjZjF0bzM3ZTFicXBoZDkyNGphZjYuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI3ODg4NDMwMzQyMzctdXFjZzh0YmdvZnJjZjF0bzM3ZTFicXBoZDkyNGphZjYuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTMxMDE5Njc2MTIzOTY3OTM3NzciLCJlbWFpbCI6InZvY29kZXMyMDIwQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYmYiOjE3MjY3ODYxMDAsIm5hbWUiOiJWb2NvZGVzIFZvY29kZXMiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUNnOG9jTHoyLTJPYUFtME1ReFI2ajhDTnItUG84X1hyLWFyeUFUaUNuNGMwaV9UdURtTF9nPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IlZvY29kZXMiLCJmYW1pbHlfbmFtZSI6IlZvY29kZXMiLCJpYXQiOjE3MjY3ODY0MDAsImV4cCI6MTcyNjc5MDAwMCwianRpIjoiNGQ0NGVlYWMwNmNlNzlmYzBhYjIyNzBjZmVlYTMwZDhhY2Y3NzYxMyJ9.EYg71yIkvhxFGc8ZVCXeTOAmPAtLYDphHnkdf1sh8b_Jz4Y7S1DpmiTqQ1ytxu7J1xNixvdwhuIDzSlCvlxaFl8475GvAlyPTNtZtmWbFD5SRM_XHLOynijOp8WQ4nej-CHvT1KjjqMfkZ1EeQMoWk1H72PxPg_RiUgzsklkUs1wOkLAySk7R3EIAl7bIzpoY_WH2pxv9ccFpBtKDHaDqHkxAWBUQX0-G7ZXZBPVz07V28ZfdbzFDapjZaUFbumazh_-J2-9AA6JkcteF4h_gpbBcLYAuxt5bWI5FECWbYe42khwb93WJ5SK12Tt0EPoyzIObJs14NWGAajtHTg3wA";
|
||||
let key = key_map.get("b2620d5e7f132b52afe8875cdf3776c064249d04").unwrap();
|
||||
|
||||
// NB: This key won't work:
|
||||
// let key = key_map.get("5aaff47c21d06e266cce395b2145c7c6d4730ea5").unwrap();
|
||||
|
||||
let options = VerificationOptions {
|
||||
time_tolerance: Some(Duration::from_days(365 * 30)),
|
||||
reject_before: None,
|
||||
accept_future: false,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let claims = decode_and_verify_token_claims(key, credential, Some(options)).unwrap();
|
||||
|
||||
// Custom fields
|
||||
assert_eq!(claims.claims.custom.email, Some("vocodes2020@gmail.com".to_string()));
|
||||
assert_eq!(claims.claims.custom.email_verified, Some(true));
|
||||
assert_eq!(claims.claims.custom.azp, Some("788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com".to_string()));
|
||||
assert_eq!(claims.claims.custom.name, Some("Vocodes Vocodes".to_string()));
|
||||
assert_eq!(claims.claims.custom.picture, Some("https://lh3.googleusercontent.com/a/ACg8ocLz2-2OaAm0MQxR6j8CNr-Po8_Xr-aryATiCn4c0i_TuDmL_g=s96-c".to_string()));
|
||||
assert_eq!(claims.claims.custom.given_name, Some("Vocodes".to_string()));
|
||||
assert_eq!(claims.claims.custom.family_name, Some("Vocodes".to_string()));
|
||||
|
||||
// Standard fields
|
||||
assert_eq!(claims.claims.jwt_id, Some("4d44eeac06ce79fc0ab2270cfeea30d8acf77613".to_string()));
|
||||
assert_eq!(claims.claims.issuer, Some("https://accounts.google.com".to_string()));
|
||||
assert_eq!(claims.claims.subject, Some("113101967612396793777".to_string()));
|
||||
assert_eq!(claims.claims.issued_at.unwrap().as_secs(), 1726786400);
|
||||
|
||||
// Methods
|
||||
assert_eq!(claims.email_verified(), true);
|
||||
assert_eq!(claims.email(), Some("vocodes2020@gmail.com"));
|
||||
assert_eq!(claims.audience_matches("788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com").unwrap(), true);
|
||||
|
||||
match claims.claims.audiences.unwrap() {
|
||||
Audiences::AsString(audience) => assert_eq!(audience, "788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com"),
|
||||
Audiences::AsSet(_audiences) => panic!("Expected a single audience"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
use errors::AnyhowResult;
|
||||
use jwt_simple::algorithms::RS256PublicKey;
|
||||
use jwt_simple::algorithms::RSAPublicKeyLike;
|
||||
use jwt_simple::claims::JWTClaims;
|
||||
use jwt_simple::common::VerificationOptions;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
/// Payload of Google Sign In
|
||||
/// https://developers.google.com/identity/openid-connect/openid-connect
|
||||
/// https://stackoverflow.com/questions/31056412/what-all-these-fields-mean
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
pub struct GoogleJwtPayloadExtraFields {
|
||||
/// The user's email address. Provided only if you included the email scope in your
|
||||
/// request. The value of this claim may not be unique to this account and could
|
||||
/// change over time, therefore you should not use this value as the primary identifier
|
||||
/// to link to your user record. You also can't rely on the domain of the email claim
|
||||
/// to identify users of Google Workspace or Cloud organizations; use the hd claim instead.
|
||||
pub email: Option<String>,
|
||||
|
||||
/// True if the user's e-mail address has been verified; otherwise false.
|
||||
pub email_verified: Option<bool>,
|
||||
|
||||
/// The user's full name, in a displayable form. (See Google documentation)
|
||||
pub name: Option<String>,
|
||||
|
||||
/// The user's given name(s) or first name(s). Might be provided when a name claim is present.
|
||||
pub given_name: Option<String>,
|
||||
|
||||
/// The user's surname(s) or last name(s). Might be provided when a name claim is present.
|
||||
pub family_name: Option<String>,
|
||||
|
||||
/// The client_id of the authorized presenter. This claim is only needed when the party
|
||||
/// requesting the ID token is not the same as the audience of the ID token. This may be
|
||||
/// the case at Google for hybrid apps where a web application and Android app have a
|
||||
/// different OAuth 2.0 client_id but share the same Google APIs project.
|
||||
pub azp: Option<String>,
|
||||
|
||||
/// An identifier for the user, unique among all Google accounts and never reused.
|
||||
/// A Google account can have multiple email addresses at different points in time,
|
||||
/// but the sub value is never changed. Use sub within your application as the
|
||||
/// unique-identifier key for the user. Maximum length of 255 case-sensitive ASCII
|
||||
/// characters.
|
||||
pub sub: Option<String>,
|
||||
|
||||
/// The URL of the user's profile picture. Might be provided when:
|
||||
/// - The request scope included the string "profile"
|
||||
/// - The ID token is returned from a token refresh
|
||||
/// When picture claims are present, you can use them to update your app's user records.
|
||||
/// Note that this claim is never guaranteed to be present.
|
||||
pub picture: Option<String>,
|
||||
|
||||
// /// The audience that this ID token is intended for. It must be one of the
|
||||
// /// OAuth 2.0 client IDs of your application.
|
||||
// /// NB: You must check that this matches the audience (the app client id)
|
||||
// pub aud: Option<String>,
|
||||
|
||||
// /// The Issuer Identifier for the Issuer of the response.
|
||||
// /// Always `https://accounts.google.com` or `accounts.google.com` for Google ID tokens.
|
||||
// /// NB: You must check that this matches the issuer.
|
||||
// pub iss: Option<String>,
|
||||
|
||||
// pub nbf: Option<String>,
|
||||
// pub jti: Option<String>,
|
||||
// pub iat: Option<String>,
|
||||
// pub exp: Option<String>,
|
||||
}
|
||||
|
||||
/*
|
||||
Example payload:
|
||||
iss https://accounts.google.com
|
||||
azp 788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com
|
||||
aud 788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com
|
||||
sub 113101967612396793777
|
||||
email vocodes2020@gmail.com
|
||||
email_verified true
|
||||
nbf 1726786100
|
||||
name Vocodes Vocodes
|
||||
picture https://lh3.googleusercontent.com/a/ACg8ocLz2-2OaAm0MQxR6j8CNr-Po8_Xr-aryATiCn4c0i_TuDmL_g=s96-c
|
||||
given_name Vocodes
|
||||
family_name Vocodes
|
||||
iat 1726786400
|
||||
exp 1726790000
|
||||
jti 4d44eeac06ce79fc0ab2270cfeea30d8acf77613
|
||||
*/
|
||||
|
||||
/// Decode a Google Sign In JWT.
|
||||
/// Verification options can be supplied to increase clock skew tolerance, etc.
|
||||
pub fn decode_token(key: &RS256PublicKey, token: &str, options: Option<VerificationOptions>) -> AnyhowResult<JWTClaims<GoogleJwtPayloadExtraFields>> {
|
||||
let claims = key.verify_token::<GoogleJwtPayloadExtraFields>(token, options)?;
|
||||
Ok(claims)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::decode_token::decode_token;
|
||||
use crate::jwk_to_public_key::jwk_to_public_key;
|
||||
use coarsetime::Duration;
|
||||
use jwt_simple::claims::Audiences;
|
||||
use jwt_simple::prelude::VerificationOptions;
|
||||
use std::fs::read_to_string;
|
||||
use testing::test_file_path::test_file_path;
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
let jwk_file = test_file_path("test_data/crypto/google_signin.jwk").unwrap();
|
||||
let jwk_payload = read_to_string(jwk_file).unwrap();
|
||||
let key_map = jwk_to_public_key(&jwk_payload).unwrap();
|
||||
|
||||
let credential = "eyJhbGciOiJSUzI1NiIsImtpZCI6ImIyNjIwZDVlN2YxMzJiNTJhZmU4ODc1Y2RmMzc3NmMwNjQyNDlkMDQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiI3ODg4NDMwMzQyMzctdXFjZzh0YmdvZnJjZjF0bzM3ZTFicXBoZDkyNGphZjYuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiI3ODg4NDMwMzQyMzctdXFjZzh0YmdvZnJjZjF0bzM3ZTFicXBoZDkyNGphZjYuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMTMxMDE5Njc2MTIzOTY3OTM3NzciLCJlbWFpbCI6InZvY29kZXMyMDIwQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYmYiOjE3MjY3ODYxMDAsIm5hbWUiOiJWb2NvZGVzIFZvY29kZXMiLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUNnOG9jTHoyLTJPYUFtME1ReFI2ajhDTnItUG84X1hyLWFyeUFUaUNuNGMwaV9UdURtTF9nPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IlZvY29kZXMiLCJmYW1pbHlfbmFtZSI6IlZvY29kZXMiLCJpYXQiOjE3MjY3ODY0MDAsImV4cCI6MTcyNjc5MDAwMCwianRpIjoiNGQ0NGVlYWMwNmNlNzlmYzBhYjIyNzBjZmVlYTMwZDhhY2Y3NzYxMyJ9.EYg71yIkvhxFGc8ZVCXeTOAmPAtLYDphHnkdf1sh8b_Jz4Y7S1DpmiTqQ1ytxu7J1xNixvdwhuIDzSlCvlxaFl8475GvAlyPTNtZtmWbFD5SRM_XHLOynijOp8WQ4nej-CHvT1KjjqMfkZ1EeQMoWk1H72PxPg_RiUgzsklkUs1wOkLAySk7R3EIAl7bIzpoY_WH2pxv9ccFpBtKDHaDqHkxAWBUQX0-G7ZXZBPVz07V28ZfdbzFDapjZaUFbumazh_-J2-9AA6JkcteF4h_gpbBcLYAuxt5bWI5FECWbYe42khwb93WJ5SK12Tt0EPoyzIObJs14NWGAajtHTg3wA";
|
||||
let key = key_map.get("b2620d5e7f132b52afe8875cdf3776c064249d04").unwrap();
|
||||
|
||||
// NB: This key won't work:
|
||||
// let key = key_map.get("5aaff47c21d06e266cce395b2145c7c6d4730ea5").unwrap();
|
||||
|
||||
let options = VerificationOptions {
|
||||
time_tolerance: Some(Duration::from_days(365 * 30)),
|
||||
reject_before: None,
|
||||
accept_future: false,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let claims = decode_token(key, credential, Some(options)).unwrap();
|
||||
|
||||
// Custom fields
|
||||
assert_eq!(claims.custom.email, Some("vocodes2020@gmail.com".to_string()));
|
||||
assert_eq!(claims.custom.email_verified, Some(true));
|
||||
assert_eq!(claims.custom.azp, Some("788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com".to_string()));
|
||||
assert_eq!(claims.custom.name, Some("Vocodes Vocodes".to_string()));
|
||||
assert_eq!(claims.custom.picture, Some("https://lh3.googleusercontent.com/a/ACg8ocLz2-2OaAm0MQxR6j8CNr-Po8_Xr-aryATiCn4c0i_TuDmL_g=s96-c".to_string()));
|
||||
assert_eq!(claims.custom.given_name, Some("Vocodes".to_string()));
|
||||
assert_eq!(claims.custom.family_name, Some("Vocodes".to_string()));
|
||||
|
||||
// TODO: Why aren't these being decoded?
|
||||
//assert_eq!(claims.custom.sub, Some("113101967612396793777".to_string()));
|
||||
//assert_eq!(claims.custom.iss, Some("https://accounts.google.com".to_string()));
|
||||
//assert_eq!(claims.custom.aud, Some("788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com".to_string()));
|
||||
//assert_eq!(claims.custom.nbf, Some("".to_string()));
|
||||
//assert_eq!(claims.custom.jti, Some("".to_string()));
|
||||
//assert_eq!(claims.custom.iat, Some("".to_string()));
|
||||
//assert_eq!(claims.custom.exp, Some("".to_string()));
|
||||
|
||||
// Standard fields
|
||||
assert_eq!(claims.jwt_id, Some("4d44eeac06ce79fc0ab2270cfeea30d8acf77613".to_string()));
|
||||
assert_eq!(claims.issuer, Some("https://accounts.google.com".to_string()));
|
||||
assert_eq!(claims.subject, Some("113101967612396793777".to_string()));
|
||||
assert_eq!(claims.issued_at.unwrap().as_secs(), 1726786400);
|
||||
|
||||
match claims.audiences.unwrap() {
|
||||
Audiences::AsString(audience) => assert_eq!(audience, "788843034237-uqcg8tbgofrcf1to37e1bqphd924jaf6.apps.googleusercontent.com"),
|
||||
Audiences::AsSet(_audiences) => panic!("Expected a single audience"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
use crate::certs::jwk_to_public_key::jwk_to_public_key;
|
||||
use crate::certs::key_map::KeyMap;
|
||||
use errors::{anyhow, AnyhowResult};
|
||||
|
||||
const GOOGLE_CERTS_URL : &str = "https://www.googleapis.com/oauth2/v3/certs";
|
||||
|
||||
pub async fn download_cert_key_set() -> AnyhowResult<KeyMap> {
|
||||
let certs = download_certs().await?;
|
||||
let key_map = jwk_to_public_key(&certs)?;
|
||||
Ok(key_map)
|
||||
}
|
||||
|
||||
pub async fn download_certs() -> AnyhowResult<String> {
|
||||
let response = reqwest::get(GOOGLE_CERTS_URL).await?;
|
||||
|
||||
if !response.status().is_success() {
|
||||
return Err(anyhow!("Failed to download Google certs: {:?}", response.status()));
|
||||
}
|
||||
|
||||
let body = response.text().await?;
|
||||
Ok(body)
|
||||
}
|
||||
@@ -18,5 +18,7 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
pub mod decode_token;
|
||||
pub mod jwk_to_public_key;
|
||||
pub mod certs;
|
||||
pub mod claims;
|
||||
pub mod decode_and_verify_token_claims;
|
||||
pub mod download_certs;
|
||||
Reference in new issue
Block a user