Fix: Replace custom JWT parser causing decoding issues (#3165)

Co-authored-by: Micha de Vries <micha@devrie.sh>
This commit is contained in:
Gerard Guillemas Martos 2023-12-19 09:53:10 +01:00 committed by GitHub
parent d4cc3272da
commit cf08b0607f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 470 additions and 131 deletions

8
Cargo.lock generated
View file

@ -6705,18 +6705,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.7.26"
version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0"
checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.26"
version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
dependencies = [
"proc-macro2",
"quote",

310
lib/fuzz/Cargo.lock generated
View file

@ -44,6 +44,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
@ -58,6 +59,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "android-tzdata"
version = "0.1.1"
@ -143,9 +150,9 @@ dependencies = [
[[package]]
name = "async-executor"
version = "1.7.2"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc5ea910c42e5ab19012bab31f53cb4d63d54c3a27730f9a833a88efcf4bb52d"
checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c"
dependencies = [
"async-lock",
"async-task",
@ -183,6 +190,17 @@ version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1"
[[package]]
name = "async-trait"
version = "0.1.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "async_io_stream"
version = "0.3.3"
@ -244,9 +262,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bcrypt"
version = "0.14.0"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9df288bec72232f78c1ec5fe4e8f1d108aa0265476e93097593c803c8c02062a"
checksum = "28d1c9c15093eb224f0baa400f38fcd713fc1391a6f1c389d886beef146d60a3"
dependencies = [
"base64",
"blowfish",
@ -684,15 +702,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "distances"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e326dfe6005e22948261065eec25180c39787702a73db3a3e63d4b8bee5604d"
dependencies = [
"rand",
]
[[package]]
name = "dmp"
version = "0.2.0"
@ -702,6 +711,12 @@ dependencies = [
"urlencoding",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "earcutr"
version = "0.4.3"
@ -808,14 +823,13 @@ checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
[[package]]
name = "flume"
version = "0.10.14"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"futures-core",
"futures-sink",
"nanorand",
"pin-project",
"spin 0.9.8",
]
@ -827,9 +841,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "form_urlencoded"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
@ -981,23 +995,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "geo"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d07d2288645058f3c78bc64eadd615335791cd5adb632e9865840afbc13dad"
dependencies = [
"earcutr",
"float_next_after",
"geo-types",
"geographiclib-rs",
"log",
"num-traits",
"robust 0.2.3",
"rstar 0.10.0",
"serde",
]
[[package]]
name = "geo"
version = "0.26.0"
@ -1010,11 +1007,29 @@ dependencies = [
"geographiclib-rs",
"log",
"num-traits",
"robust 1.1.0",
"rstar 0.11.0",
"robust",
"rstar",
"serde",
]
[[package]]
name = "geo"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4841b40fdbccd4b7042bd6195e4de91da54af34c50632e371bcbfcdfb558b873"
dependencies = [
"earcutr",
"float_next_after",
"geo-types",
"geographiclib-rs",
"log",
"num-traits",
"robust",
"rstar",
"serde",
"spade",
]
[[package]]
name = "geo-types"
version = "0.7.12"
@ -1023,8 +1038,7 @@ checksum = "567495020b114f1ce9bed679b29975aa0bfae06ac22beacd5cfde5dabe7b05d6"
dependencies = [
"approx",
"num-traits",
"rstar 0.10.0",
"rstar 0.11.0",
"rstar",
"serde",
]
@ -1074,20 +1088,15 @@ dependencies = [
"ahash 0.7.7",
]
[[package]]
name = "hashbrown"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
dependencies = [
"ahash 0.8.6",
]
[[package]]
name = "hashbrown"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156"
dependencies = [
"ahash 0.8.6",
"allocator-api2",
]
[[package]]
name = "heapless"
@ -1102,6 +1111,12 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.3.3"
@ -1123,6 +1138,12 @@ dependencies = [
"digest",
]
[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "iana-time-zone"
version = "0.1.58"
@ -1154,9 +1175,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
@ -1267,9 +1288,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.65"
version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8"
checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca"
dependencies = [
"wasm-bindgen",
]
@ -1380,15 +1401,6 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "lru"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670"
dependencies = [
"hashbrown 0.13.2",
]
[[package]]
name = "md-5"
version = "0.10.6"
@ -1564,6 +1576,27 @@ dependencies = [
"memchr",
]
[[package]]
name = "object_store"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2524735495ea1268be33d200e1ee97455096a0846295a21548cd2f3541de7050"
dependencies = [
"async-trait",
"bytes",
"chrono",
"futures",
"humantime",
"itertools 0.11.0",
"parking_lot",
"percent-encoding",
"snafu",
"tokio",
"tracing",
"url",
"walkdir",
]
[[package]]
name = "once_cell"
version = "1.18.0"
@ -1649,9 +1682,9 @@ dependencies = [
[[package]]
name = "percent-encoding"
version = "2.3.0"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "petgraph"
@ -1836,6 +1869,18 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "quick_cache"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f69f8d22fa3f34f3083d9a4375c038732c7a7e964de1beb81c544da92dfc40b8"
dependencies = [
"ahash 0.8.6",
"equivalent",
"hashbrown 0.14.2",
"parking_lot",
]
[[package]]
name = "quote"
version = "1.0.33"
@ -2077,12 +2122,6 @@ dependencies = [
"serde",
]
[[package]]
name = "robust"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5864e7ef1a6b7bcf1d6ca3f655e65e724ed3b52546a0d0a663c991522f552ea"
[[package]]
name = "robust"
version = "1.1.0"
@ -2109,17 +2148,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rstar"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f39465655a1e3d8ae79c6d9e007f4953bfc5d55297602df9dc38f9ae9f1359a"
dependencies = [
"heapless",
"num-traits",
"smallvec",
]
[[package]]
name = "rstar"
version = "0.11.0"
@ -2215,6 +2243,15 @@ dependencies = [
"cipher",
]
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -2256,18 +2293,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]]
name = "serde"
version = "1.0.192"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.192"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
@ -2395,12 +2432,46 @@ dependencies = [
"serde",
]
[[package]]
name = "snafu"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6"
dependencies = [
"doc-comment",
"snafu-derive",
]
[[package]]
name = "snafu-derive"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "snap"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831"
[[package]]
name = "spade"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87a3ef2efbc408c9051c1a27ce7edff430d74531d31a480b7ca4f618072c2670"
dependencies = [
"hashbrown 0.14.2",
"num-traits",
"robust",
"smallvec",
]
[[package]]
name = "spin"
version = "0.5.2"
@ -2484,7 +2555,7 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "surrealdb"
version = "1.0.0"
version = "1.0.1"
dependencies = [
"addr",
"any_ascii",
@ -2499,7 +2570,6 @@ dependencies = [
"cedar-policy",
"chrono",
"deunicode",
"distances",
"dmp",
"echodb",
"flume",
@ -2507,19 +2577,22 @@ dependencies = [
"futures",
"futures-concurrency",
"fuzzy-matcher",
"geo 0.25.1",
"indexmap 1.9.3",
"geo 0.27.0",
"hex",
"indexmap 2.1.0",
"ipnet",
"lexicmp",
"lru",
"md-5",
"nanoid",
"nom",
"num_cpus",
"object_store",
"once_cell",
"path-clean",
"pbkdf2",
"pharos",
"pin-project-lite",
"quick_cache",
"radix_trie",
"rand",
"regex",
@ -2879,9 +2952,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "url"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",
@ -2896,9 +2969,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]]
name = "uuid"
version = "1.6.0"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58fe91d841bc04822c9801002db4ea904b9e4b8e6bbad25127b46eff8dc516b"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
dependencies = [
"atomic",
"getrandom",
@ -2912,6 +2985,16 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "walkdir"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@ -2920,9 +3003,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.88"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce"
checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -2930,9 +3013,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.88"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217"
checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826"
dependencies = [
"bumpalo",
"log",
@ -2945,9 +3028,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.38"
version = "0.4.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02"
checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12"
dependencies = [
"cfg-if",
"js-sys",
@ -2957,9 +3040,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.88"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2"
checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -2967,9 +3050,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.88"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907"
checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
dependencies = [
"proc-macro2",
"quote",
@ -2980,9 +3063,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.88"
version = "0.2.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b"
checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
[[package]]
name = "wasmtimer"
@ -3023,6 +3106,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@ -3143,18 +3235,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.7.26"
version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0"
checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.26"
version = "0.7.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a"
dependencies = [
"proc-macro2",
"quote",

View file

@ -5,15 +5,12 @@ use crate::kvs::{Datastore, LockType::*, TransactionType::*};
use crate::sql::{statements::DefineUserStatement, Algorithm, Value};
use crate::syn;
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use base64_lib::Engine;
use chrono::Utc;
use jsonwebtoken::{decode, DecodingKey, Validation};
use once_cell::sync::Lazy;
use std::str::{self, FromStr};
use std::sync::Arc;
use super::base::BASE64;
fn config(algo: Algorithm, code: String) -> Result<(DecodingKey, Validation), Error> {
match algo {
Algorithm::Hs256 => Ok((
@ -161,8 +158,8 @@ pub async fn token(kvs: &Datastore, session: &mut Session, token: &str) -> Resul
trace!("Attempting token authentication");
// Decode the token without verifying
let token_data = decode::<Claims>(token, &KEY, &DUD)?;
// Parse the token and catch any errors
let value = parse(token)?;
// Convert the token to a SurrealQL object value
let value = token_data.claims.clone().into();
// Check if the auth token can be used
if let Some(nbf) = token_data.claims.nbf {
if nbf > Utc::now().timestamp() {
@ -423,17 +420,6 @@ pub async fn token(kvs: &Datastore, session: &mut Session, token: &str) -> Resul
}
}
pub fn parse(value: &str) -> Result<Value, Error> {
// Extract the middle part of the token
let value = value.splitn(3, '.').skip(1).take(1).next().ok_or(Error::InvalidAuth)?;
// Decode the base64 token data content
let value = BASE64.decode(value).map_err(|_| Error::InvalidAuth)?;
// Convert the decoded data to a string
let value = str::from_utf8(&value).map_err(|_| Error::InvalidAuth)?;
// Parse the token data into SurrealQL
syn::json(value).map_err(|_| Error::InvalidAuth)
}
pub async fn verify_root_creds(
ds: &Datastore,
user: &str,
@ -837,7 +823,7 @@ mod tests {
}
//
// Test with invalid token
// Test with invalid signature
//
{
// Prepare the claims object
@ -945,7 +931,7 @@ mod tests {
}
//
// Test with invalid token
// Test with invalid signature
//
{
// Prepare the claims object
@ -977,6 +963,267 @@ mod tests {
}
}
#[tokio::test]
async fn test_token_scope() {
let secret = "jwt_secret";
let key = EncodingKey::from_secret(secret.as_ref());
let claims = Claims {
iss: Some("surrealdb-test".to_string()),
iat: Some(Utc::now().timestamp()),
nbf: Some(Utc::now().timestamp()),
exp: Some((Utc::now() + Duration::hours(1)).timestamp()),
tk: Some("token".to_string()),
ns: Some("test".to_string()),
db: Some("test".to_string()),
sc: Some("test".to_string()),
..Claims::default()
};
let ds = Datastore::new("memory").await.unwrap();
let sess = Session::owner().with_ns("test").with_db("test");
ds.execute(
format!("DEFINE TOKEN token ON SCOPE test TYPE HS512 VALUE '{secret}';").as_str(),
&sess,
None,
)
.await
.unwrap();
//
// Test without roles defined
// Roles should be ignored in scope authentication
//
{
// Prepare the claims object
let mut claims = claims.clone();
claims.roles = None;
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
assert_eq!(sess.au.level().ns(), Some("test"));
assert_eq!(sess.au.level().db(), Some("test"));
assert!(!sess.au.has_role(&Role::Viewer), "Auth user expected to not have Viewer role");
assert!(!sess.au.has_role(&Role::Editor), "Auth user expected to not have Editor role");
assert!(!sess.au.has_role(&Role::Owner), "Auth user expected to not have Owner role");
}
//
// Test with roles defined
// Roles should be ignored in scope authentication
//
{
// Prepare the claims object
let mut claims = claims.clone();
claims.roles = Some(vec!["editor".to_string(), "owner".to_string()]);
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
assert_eq!(sess.au.level().ns(), Some("test"));
assert_eq!(sess.au.level().db(), Some("test"));
assert!(!sess.au.has_role(&Role::Viewer), "Auth user expected to not have Viewer role");
assert!(!sess.au.has_role(&Role::Editor), "Auth user expected to not have Editor role");
assert!(!sess.au.has_role(&Role::Owner), "Auth user expected to not have Owner role");
}
//
// Test with invalid signature
//
{
// Prepare the claims object
let claims = claims.clone();
// Create the token
let key = EncodingKey::from_secret("invalid".as_ref());
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_err(), "Unexpected success signing in with token: {:?}", res);
}
//
// Test with valid token invalid sc
//
{
// Prepare the claims object
let mut claims = claims.clone();
claims.sc = Some("invalid".to_string());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_err(), "Unexpected success signing in with token: {:?}", res);
}
//
// Test with invalid id
//
{
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some("##_INVALID_##".to_string());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_err(), "Unexpected success signing in with token: {:?}", res);
}
//
// Test with generic user identifier
//
{
let resource_id = "user:2k9qnabxuxh8k4d5gfto".to_string();
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some(resource_id.clone());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
let user_id = syn::thing(&resource_id).unwrap();
assert_eq!(sess.sd, Some(Value::from(user_id)));
}
//
// Test with custom user numeric identifiers of varying sizes
//
{
let ids = vec!["1", "2", "100", "10000000"];
for id in ids.iter() {
let resource_id = format!("user:{id}");
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some(resource_id.clone());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
let user_id = syn::thing(&resource_id).unwrap();
assert_eq!(sess.sd, Some(Value::from(user_id)));
}
}
//
// Test with custom user string identifiers of varying lengths
//
{
let ids = vec!["username", "username1", "username10", "username100"];
for id in ids.iter() {
let resource_id = format!("user:{id}");
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some(resource_id.clone());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
let user_id = syn::thing(&resource_id).unwrap();
assert_eq!(sess.sd, Some(Value::from(user_id)));
}
}
//
// Test with custom user string identifiers of varying lengths with special characters
//
{
let ids = vec!["user.name", "user.name1", "user.name10", "user.name100"];
for id in ids.iter() {
// Enclose special characters in "⟨brackets⟩"
let resource_id = format!("user:⟨{id}");
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some(resource_id.clone());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
let user_id = syn::thing(&resource_id).unwrap();
assert_eq!(sess.sd, Some(Value::from(user_id)));
}
}
//
// Test with custom UUID user identifier
//
{
let id = "83149446-95f5-4c0d-9f42-136e7b272456";
// Enclose special characters in "⟨brackets⟩"
let resource_id = format!("user:⟨{id}");
// Prepare the claims object
let mut claims = claims.clone();
claims.id = Some(resource_id.clone());
// Create the token
let enc = encode(&HEADER, &claims, &key).unwrap();
// Signin with the token
let mut sess = Session::default();
let res = token(&ds, &mut sess, &enc).await;
assert!(res.is_ok(), "Failed to signin with token: {:?}", res);
assert_eq!(sess.ns, Some("test".to_string()));
assert_eq!(sess.db, Some("test".to_string()));
assert_eq!(sess.sc, Some("test".to_string()));
assert_eq!(sess.au.id(), "token");
assert!(sess.au.is_scope());
let user_id = syn::thing(&resource_id).unwrap();
assert_eq!(sess.sd, Some(Value::from(user_id)));
}
}
#[test]
fn test_verify_pass() {
let salt = SaltString::generate(&mut rand::thread_rng());