Use signature field for verification
Instead of looking for a "secret" field hmac is used. Therefore the raw payload is hashed with all secrets consecutively in order to validate its content. If the content is certified the established behaviour is pursued..
This commit is contained in:
parent
a130bdc125
commit
ee32424f8c
4 changed files with 297 additions and 372 deletions
272
Cargo.lock
generated
272
Cargo.lock
generated
|
@ -91,7 +91,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.3.9",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -172,12 +172,6 @@ version = "1.0.67"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -234,7 +228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
|
checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -315,7 +309,7 @@ checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"redox_users",
|
"redox_users",
|
||||||
"winapi 0.3.9",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -337,53 +331,6 @@ dependencies = [
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "filetime"
|
|
||||||
version = "0.2.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 1.0.0",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall 0.2.5",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fsevent"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"fsevent-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fsevent-sys"
|
|
||||||
version = "2.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fuchsia-zircon"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"fuchsia-zircon-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fuchsia-zircon-sys"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "funty"
|
name = "funty"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -406,7 +353,7 @@ version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
@ -417,7 +364,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
@ -453,6 +400,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hkdf"
|
name = "hkdf"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -537,51 +490,12 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "inotify"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"inotify-sys",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "inotify-sys"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iovec"
|
|
||||||
version = "0.1.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "kernel32-sys"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.2.8",
|
|
||||||
"winapi-build",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "language-tags"
|
name = "language-tags"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -594,12 +508,6 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazycell"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lexical-core"
|
name = "lexical-core"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
|
@ -608,7 +516,7 @@ checksum = "21f866863575d0e1d654fbeeabdc927292fdf862873dc3c96c6f753357e13374"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"ryu",
|
"ryu",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
@ -640,7 +548,7 @@ version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -664,60 +572,6 @@ dependencies = [
|
||||||
"log 0.3.9",
|
"log 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio"
|
|
||||||
version = "0.6.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"fuchsia-zircon",
|
|
||||||
"fuchsia-zircon-sys",
|
|
||||||
"iovec",
|
|
||||||
"kernel32-sys",
|
|
||||||
"libc",
|
|
||||||
"log 0.4.14",
|
|
||||||
"miow",
|
|
||||||
"net2",
|
|
||||||
"slab",
|
|
||||||
"winapi 0.2.8",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio-extras"
|
|
||||||
version = "2.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
|
|
||||||
dependencies = [
|
|
||||||
"lazycell",
|
|
||||||
"log 0.4.14",
|
|
||||||
"mio",
|
|
||||||
"slab",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "miow"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
|
|
||||||
dependencies = [
|
|
||||||
"kernel32-sys",
|
|
||||||
"net2",
|
|
||||||
"winapi 0.2.8",
|
|
||||||
"ws2_32-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "net2"
|
|
||||||
version = "0.2.37"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if 0.1.10",
|
|
||||||
"libc",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "6.1.2"
|
version = "6.1.2"
|
||||||
|
@ -731,24 +585,6 @@ dependencies = [
|
||||||
"version_check 0.9.3",
|
"version_check 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "notify"
|
|
||||||
version = "4.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"filetime",
|
|
||||||
"fsevent",
|
|
||||||
"fsevent-sys",
|
|
||||||
"inotify",
|
|
||||||
"libc",
|
|
||||||
"mio",
|
|
||||||
"mio-extras",
|
|
||||||
"walkdir",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -904,15 +740,6 @@ version = "0.1.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -920,7 +747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.16",
|
"getrandom 0.1.16",
|
||||||
"redox_syscall 0.1.57",
|
"redox_syscall",
|
||||||
"rust-argon2",
|
"rust-argon2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -989,19 +816,6 @@ dependencies = [
|
||||||
"yansi",
|
"yansi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rocket_contrib"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d7954a707f9ca18aa74ca8c1f5d1f900f52a4dceb68e96e3112143f759cfd20e"
|
|
||||||
dependencies = [
|
|
||||||
"log 0.4.14",
|
|
||||||
"notify",
|
|
||||||
"rocket",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rocket_http"
|
name = "rocket_http"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
@ -1059,15 +873,6 @@ version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "same-file"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sct"
|
name = "sct"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -1128,18 +933,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
|
checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"cpuid-bool 0.1.2",
|
"cpuid-bool 0.1.2",
|
||||||
"digest",
|
"digest",
|
||||||
"opaque-debug",
|
"opaque-debug",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "slab"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
@ -1208,7 +1007,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"winapi 0.3.9",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1331,17 +1130,6 @@ version = "0.9.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "walkdir"
|
|
||||||
version = "2.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
|
|
||||||
dependencies = [
|
|
||||||
"same-file",
|
|
||||||
"winapi 0.3.9",
|
|
||||||
"winapi-util",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.9.0+wasi-snapshot-preview1"
|
version = "0.9.0+wasi-snapshot-preview1"
|
||||||
|
@ -1361,14 +1149,16 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"dirs",
|
"dirs",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"hex",
|
||||||
|
"hmac",
|
||||||
"log 0.4.14",
|
"log 0.4.14",
|
||||||
"nom",
|
"nom",
|
||||||
"regex",
|
"regex",
|
||||||
"rocket",
|
"rocket",
|
||||||
"rocket_contrib",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1391,12 +1181,6 @@ dependencies = [
|
||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.2.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -1407,12 +1191,6 @@ dependencies = [
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-build"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -1425,7 +1203,7 @@ version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1434,16 +1212,6 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ws2_32-sys"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
|
||||||
dependencies = [
|
|
||||||
"winapi 0.2.8",
|
|
||||||
"winapi-build",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wyz"
|
name = "wyz"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
|
@ -12,7 +12,6 @@ tls = ["rocket/tls"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = "0.4"
|
rocket = "0.4"
|
||||||
rocket_contrib = { version = "0.4", default-features = false, features = ["json"] }
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_yaml = "0.8"
|
serde_yaml = "0.8"
|
||||||
|
@ -22,3 +21,6 @@ anyhow = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
nom = "6"
|
nom = "6"
|
||||||
|
hmac = "0.10"
|
||||||
|
sha2 = "0.9"
|
||||||
|
hex = "0.4"
|
||||||
|
|
12
README.md
12
README.md
|
@ -55,11 +55,12 @@ Configuration syntax is YAML and has to be done in following order:
|
||||||
|
|
||||||
Right now there is only the configuration parameter for hooks, here
|
Right now there is only the configuration parameter for hooks, here
|
||||||
each hook has to be configured, It contains following fields:
|
each hook has to be configured, It contains following fields:
|
||||||
- command: Optional string for a command to be executed when all
|
- command: String for a command to be executed when all filters
|
||||||
filters match. Pointers ([RFC
|
match. Pointers ([RFC 6901](https://tools.ietf.org/html/rfc6901)) to
|
||||||
6901](https://tools.ietf.org/html/rfc6901)) to JSON fields may be
|
JSON fields may be used to be replaced with data from the JSON data
|
||||||
used to be replaced with data from the JSON data with `{{
|
with `{{ /field/pointed/to }}`. Further `{{ event }}` and `{{
|
||||||
/field/pointed/to }}`
|
signature }}` are valid variables as they contain the values from
|
||||||
|
the regarding header fields of the http request.
|
||||||
- secrets: List of secrets.
|
- secrets: List of secrets.
|
||||||
- filters: List of filters.
|
- filters: List of filters.
|
||||||
|
|
||||||
|
@ -81,7 +82,6 @@ Whereas `<config_dir>` depends on the platform:
|
||||||
- Windows: `{FOLDERID_RoamingAppData}`
|
- Windows: `{FOLDERID_RoamingAppData}`
|
||||||
|
|
||||||
# TODOs
|
# TODOs
|
||||||
## Use `lazy_static` or `once_cell` for compiled regexes
|
|
||||||
## Use `clap` to parse command line arguments
|
## Use `clap` to parse command line arguments
|
||||||
## Implement the functionality to reply to certain webhooks
|
## Implement the functionality to reply to certain webhooks
|
||||||
## Configure rocket via config.yml
|
## Configure rocket via config.yml
|
||||||
|
|
357
src/main.rs
357
src/main.rs
|
@ -1,7 +1,8 @@
|
||||||
#![feature(proc_macro_hygiene, decl_macro)]
|
#![feature(proc_macro_hygiene, decl_macro)]
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use log::{debug, info, trace, warn};
|
use hmac::{Hmac, Mac, NewMac};
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
use nom::{
|
use nom::{
|
||||||
branch::alt,
|
branch::alt,
|
||||||
bytes::complete::{tag, take_until},
|
bytes::complete::{tag, take_until},
|
||||||
|
@ -11,12 +12,24 @@ use nom::{
|
||||||
Finish, IResult,
|
Finish, IResult,
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rocket::{fairing::AdHoc, get, http::Status, post, routes, Response, State};
|
use rocket::{
|
||||||
use rocket_contrib::json::Json;
|
data::{self, FromDataSimple},
|
||||||
|
fairing::AdHoc,
|
||||||
|
get,
|
||||||
|
http::{HeaderMap, Status},
|
||||||
|
post, routes, Data,
|
||||||
|
Outcome::{Failure, Success},
|
||||||
|
Request, Response, State,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use sha2::Sha256;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap, fs::File, io::BufReader, net::SocketAddr, process::Command,
|
collections::HashMap,
|
||||||
|
fs::File,
|
||||||
|
io::{BufReader, Read},
|
||||||
|
net::SocketAddr,
|
||||||
|
process::Command,
|
||||||
str::from_utf8,
|
str::from_utf8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,7 +40,7 @@ struct Config {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
struct Hook {
|
struct Hook {
|
||||||
command: Option<String>,
|
command: String,
|
||||||
secrets: Vec<String>,
|
secrets: Vec<String>,
|
||||||
filters: HashMap<String, Filter>,
|
filters: HashMap<String, Filter>,
|
||||||
}
|
}
|
||||||
|
@ -38,28 +51,28 @@ struct Filter {
|
||||||
regex: String,
|
regex: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug)]
|
||||||
struct Data(serde_json::Value);
|
struct Hooks(HashMap<String, Vec<String>>);
|
||||||
|
|
||||||
#[get("/")]
|
fn replace_parameter(input: &str, headers: &HeaderMap, data: &serde_json::Value) -> Result<String> {
|
||||||
fn index() -> &'static str {
|
|
||||||
"Hello, webhookey!"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_parameter(input: &str, data: &serde_json::Value) -> Result<String> {
|
|
||||||
let parse: IResult<&str, Vec<&str>> = many0(alt((
|
let parse: IResult<&str, Vec<&str>> = many0(alt((
|
||||||
map_res(
|
map_res(
|
||||||
delimited(tag("{{"), take_until("}}"), tag("}}")),
|
delimited(tag("{{"), take_until("}}"), tag("}}")),
|
||||||
|param: &str| {
|
|param: &str| match param.trim() {
|
||||||
if let Some(value) = data.pointer(param.trim()) {
|
"event" => {
|
||||||
if let Some(value) = value.as_str() {
|
if let Some(event) = headers.get_one("X-Gitea-Event") {
|
||||||
Ok(value)
|
Ok(event)
|
||||||
} else {
|
} else {
|
||||||
bail!("Could not convert field `{}` to string", param.trim());
|
bail!("Could not extract event parameter from header");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
bail!("Could not find `{}` in received data", param.trim());
|
|
||||||
}
|
}
|
||||||
|
pointer => match data.pointer(pointer) {
|
||||||
|
Some(value) => match value.as_str() {
|
||||||
|
Some(value) => Ok(value),
|
||||||
|
_ => bail!("Could not convert value `{}` to string", value),
|
||||||
|
},
|
||||||
|
_ => bail!("Could not convert field `{}` to string", param.trim()),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
take_until("{{"),
|
take_until("{{"),
|
||||||
|
@ -73,92 +86,224 @@ fn replace_parameter(input: &str, data: &serde_json::Value) -> Result<String> {
|
||||||
Ok(result.join(""))
|
Ok(result.join(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_hook(name: &str, hook: &Hook, data: &serde_json::Value) -> Result<()> {
|
impl FromDataSimple for Hooks {
|
||||||
debug!("Running hook `{}`", name);
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
for (filter_name, filter) in hook.filters.iter() {
|
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
|
||||||
debug!("Matching filter `{}`", filter_name);
|
let config = request.guard::<State<Config>>().unwrap(); // should never fail
|
||||||
|
|
||||||
|
let mut hooks = HashMap::new();
|
||||||
|
|
||||||
|
if let Some(signature) = request.headers().get_one("X-Gitea-Signature") {
|
||||||
|
let mut data = data.open();
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
|
||||||
|
match data.read_to_end(&mut buffer) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not read to end of data: {}", &e);
|
||||||
|
return Failure((
|
||||||
|
Status::BadRequest,
|
||||||
|
anyhow!("Could not read to end of data: {}", &e),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!("Data received: {:?}", from_utf8(&buffer));
|
||||||
|
|
||||||
|
let mut valid = false;
|
||||||
|
|
||||||
|
for (hook_name, hook) in &config.hooks {
|
||||||
|
let mut commands = Vec::new();
|
||||||
|
|
||||||
|
for secret in &hook.secrets {
|
||||||
|
let mut mac = match Hmac::<Sha256>::new_varkey(&secret.as_bytes()) {
|
||||||
|
Ok(mac) => mac,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not instantiate hasher: {}", e);
|
||||||
|
return Failure((
|
||||||
|
Status::InternalServerError,
|
||||||
|
anyhow!("Could not instantiate hasher: {}", e),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mac.update(&buffer);
|
||||||
|
|
||||||
|
match &hex::decode(&signature.as_bytes()) {
|
||||||
|
Ok(raw_signature) => {
|
||||||
|
if mac.verify(&raw_signature) == Ok(()) {
|
||||||
|
trace!(
|
||||||
|
"Valid signature found for hook `{}`: {}",
|
||||||
|
hook_name,
|
||||||
|
signature
|
||||||
|
);
|
||||||
|
|
||||||
|
valid = true;
|
||||||
|
|
||||||
|
let data: serde_json::Value = match serde_json::from_slice(&buffer)
|
||||||
|
{
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(e) => {
|
||||||
|
error!("Could not parse json: {}", e);
|
||||||
|
return Failure((
|
||||||
|
Status::BadRequest,
|
||||||
|
anyhow!("Could not parse json: {}", e),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (filter_name, filter) in &hook.filters {
|
||||||
|
trace!(
|
||||||
|
"Matching filter `{}` of hook `{}`",
|
||||||
|
filter_name,
|
||||||
|
hook_name
|
||||||
|
);
|
||||||
|
|
||||||
|
let regex = match Regex::new(&filter.regex) {
|
||||||
|
Ok(regex) => regex,
|
||||||
|
Err(e) => {
|
||||||
|
error!(
|
||||||
|
"Could not compile regex `{}`: {}",
|
||||||
|
&filter.regex, e
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(value) = data.pointer(&filter.pointer) {
|
if let Some(value) = data.pointer(&filter.pointer) {
|
||||||
let regex = Regex::new(&filter.regex)?;
|
|
||||||
|
|
||||||
if let Some(value) = value.as_str() {
|
if let Some(value) = value.as_str() {
|
||||||
if !regex.is_match(value) {
|
if regex.is_match(value) {
|
||||||
info!("Filter `{}` in hook `{}` did not match", filter_name, name);
|
debug!(
|
||||||
return Ok(());
|
"Filter `{}` of hook `{}` matched",
|
||||||
|
filter_name, hook_name
|
||||||
|
);
|
||||||
|
|
||||||
|
match replace_parameter(
|
||||||
|
&hook.command.to_string(),
|
||||||
|
&request.headers(),
|
||||||
|
&data,
|
||||||
|
) {
|
||||||
|
Ok(command) => commands.push(command),
|
||||||
|
Err(e) => error!(
|
||||||
|
"Could not replace all parameter in hook `{}`: {}",
|
||||||
|
hook_name, e
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
anyhow!(
|
anyhow!(
|
||||||
"Could not parse pointer in hook `{}` from filter `{}`",
|
"Could not parse pointer in hook `{}` from filter `{}`",
|
||||||
name,
|
hook_name,
|
||||||
filter_name
|
filter_name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trace!(
|
||||||
|
"Filter `{}` of hook `{}` did not match",
|
||||||
|
filter_name,
|
||||||
|
hook_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Invalid configuration: {}", e);
|
||||||
|
return Failure((
|
||||||
|
Status::InternalServerError,
|
||||||
|
anyhow!("Invalid configuration: {}", e),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(command) = &hook.command {
|
if !commands.is_empty() {
|
||||||
let command = replace_parameter(&command, data)?;
|
hooks.insert(hook_name.to_string(), commands);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info!("Execute `{}` from hook `{}`", command, name);
|
if hooks.is_empty() {
|
||||||
|
if valid {
|
||||||
|
warn!(
|
||||||
|
"Unmatched hook from {:?} with signature {:?}",
|
||||||
|
&request.client_ip(),
|
||||||
|
&request.headers().get_one("X-Gitea-Signature")
|
||||||
|
);
|
||||||
|
Failure((
|
||||||
|
Status::NotFound,
|
||||||
|
anyhow!(
|
||||||
|
"Unmatched hook from {:?} with signature {:?}",
|
||||||
|
&request.client_ip(),
|
||||||
|
&request.headers().get_one("X-Gitea-Signature")
|
||||||
|
),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
warn!(
|
||||||
|
"Unauthorized request from {:?} with signature {:?}",
|
||||||
|
&request.client_ip(),
|
||||||
|
&request.headers().get_one("X-Gitea-Signature")
|
||||||
|
);
|
||||||
|
Failure((
|
||||||
|
Status::Unauthorized,
|
||||||
|
anyhow!(
|
||||||
|
"Unauthorized request from {:?} with signature {:?}",
|
||||||
|
&request.client_ip(),
|
||||||
|
&request.headers().get_one("X-Gitea-Signature")
|
||||||
|
),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Success(Hooks(hooks))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Failure((
|
||||||
|
Status::BadRequest,
|
||||||
|
anyhow!("Could not extract signature from header"),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
fn index() -> &'static str {
|
||||||
|
"Hello, webhookey!"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/", format = "json", data = "<hooks>")]
|
||||||
|
fn receive_hook<'a>(address: SocketAddr, hooks: Hooks) -> Result<Response<'a>> {
|
||||||
|
info!("Post request received from: {}", address);
|
||||||
|
|
||||||
|
for hook in hooks.0 {
|
||||||
|
for command in hook.1 {
|
||||||
|
info!("Execute `{}` from hook `{}`", &command, &hook.0);
|
||||||
|
|
||||||
let command = command.split(' ').collect::<Vec<&str>>();
|
let command = command.split(' ').collect::<Vec<&str>>();
|
||||||
let exec_command = Command::new(&command[0]).args(&command[1..]).output()?;
|
match Command::new(&command[0]).args(&command[1..]).output() {
|
||||||
|
Ok(executed) => {
|
||||||
info!(
|
info!(
|
||||||
"Command `{}` exited with return code: {}",
|
"Command `{}` exited with return code: {}",
|
||||||
&command[0], &exec_command.status
|
&command[0], &executed.status
|
||||||
);
|
);
|
||||||
trace!(
|
trace!(
|
||||||
"Output of command `{}` on stdout: {:?}",
|
"Output of command `{}` on stdout: {:?}",
|
||||||
&command[0],
|
&command[0],
|
||||||
from_utf8(&exec_command.stdout)?
|
from_utf8(&executed.stdout)?
|
||||||
);
|
);
|
||||||
debug!(
|
debug!(
|
||||||
"Output of command `{}` on stderr: {:?}",
|
"Output of command `{}` on stderr: {:?}",
|
||||||
&command[0],
|
&command[0],
|
||||||
from_utf8(&exec_command.stderr)?
|
from_utf8(&executed.stderr)?
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
Ok(())
|
error!("Execution of `{}` failed: {}", command[0], e);
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/", format = "json", data = "<data>")]
|
|
||||||
fn receive_hook(address: SocketAddr, config: State<Config>, data: Json<Data>) -> Result<Response> {
|
|
||||||
info!("Post request received from: {}", address);
|
|
||||||
|
|
||||||
let mut response = Response::new();
|
|
||||||
let data = serde_json::to_value(data.0)?;
|
|
||||||
|
|
||||||
trace!("Data received from: {}\n{}", address, data);
|
|
||||||
|
|
||||||
if let Some(secret) = data.pointer("/secret") {
|
|
||||||
if let Some(secret) = secret.as_str() {
|
|
||||||
let hooks: HashMap<&String, &Hook> = config
|
|
||||||
.hooks
|
|
||||||
.iter()
|
|
||||||
.filter(|(_hook_name, hook)| hook.secrets.contains(&secret.to_string()))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if hooks.is_empty() {
|
|
||||||
warn!("Secret from {} did not match any hook", address);
|
|
||||||
response.set_status(Status::Unauthorized);
|
|
||||||
} else {
|
|
||||||
for (hook_name, hook) in hooks {
|
|
||||||
execute_hook(&hook_name, &hook, &data)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
warn!("Data received from {} contains invalid data", address);
|
|
||||||
response.set_status(Status::BadRequest);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
warn!("Data received from {} did not contain a secret", address);
|
|
||||||
response.set_status(Status::NotFound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(response)
|
Ok(Response::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_config() -> Result<File> {
|
fn get_config() -> Result<File> {
|
||||||
|
@ -210,7 +355,10 @@ fn main() -> Result<()> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use rocket::{http::ContentType, local::Client};
|
use rocket::{
|
||||||
|
http::{ContentType, Header},
|
||||||
|
local::Client,
|
||||||
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -230,7 +378,7 @@ mod tests {
|
||||||
hooks.insert(
|
hooks.insert(
|
||||||
"test_hook".to_string(),
|
"test_hook".to_string(),
|
||||||
Hook {
|
Hook {
|
||||||
command: None,
|
command: "".to_string(),
|
||||||
secrets: vec!["valid".to_string()],
|
secrets: vec!["valid".to_string()],
|
||||||
filters: HashMap::new(),
|
filters: HashMap::new(),
|
||||||
},
|
},
|
||||||
|
@ -246,33 +394,33 @@ mod tests {
|
||||||
let client = Client::new(rocket).unwrap();
|
let client = Client::new(rocket).unwrap();
|
||||||
let response = client
|
let response = client
|
||||||
.post("/")
|
.post("/")
|
||||||
|
.header(Header::new(
|
||||||
|
"X-Gitea-Signature",
|
||||||
|
"28175a0035f637f3cbb85afee9f9d319631580e7621cf790cd16ca063a2f820e",
|
||||||
|
))
|
||||||
.header(ContentType::JSON)
|
.header(ContentType::JSON)
|
||||||
.remote("127.0.0.1:8000".parse().unwrap())
|
.remote("127.0.0.1:8000".parse().unwrap())
|
||||||
.body(r#"{ "secret": "valid" }"#)
|
.body(&serde_json::to_string(&json!({ "foo": "bar" })).unwrap())
|
||||||
.dispatch();
|
|
||||||
|
|
||||||
assert_eq!(response.status(), Status::Ok);
|
|
||||||
|
|
||||||
let response = client
|
|
||||||
.post("/")
|
|
||||||
.header(ContentType::JSON)
|
|
||||||
.remote("127.0.0.1:8000".parse().unwrap())
|
|
||||||
.body(r#"{ "secret": "invalid" }"#)
|
|
||||||
.dispatch();
|
|
||||||
|
|
||||||
assert_eq!(response.status(), Status::Unauthorized);
|
|
||||||
|
|
||||||
let response = client
|
|
||||||
.post("/")
|
|
||||||
.header(ContentType::JSON)
|
|
||||||
.remote("127.0.0.1:8000".parse().unwrap())
|
|
||||||
.body(r#"{ "not_secret": "invalid" }"#)
|
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
assert_eq!(response.status(), Status::NotFound);
|
assert_eq!(response.status(), Status::NotFound);
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.post("/")
|
.post("/")
|
||||||
|
.header(Header::new("X-Gitea-Signature", "beef"))
|
||||||
|
.header(ContentType::JSON)
|
||||||
|
.remote("127.0.0.1:8000".parse().unwrap())
|
||||||
|
.body(&serde_json::to_string(&json!({ "foo": "bar" })).unwrap())
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/")
|
||||||
|
.header(Header::new(
|
||||||
|
"X-Gitea-Signature",
|
||||||
|
"c5c315d76318362ec129ca629b50b626bba09ad3d7ba4cc0f4c0afe4a90537a0",
|
||||||
|
))
|
||||||
.header(ContentType::JSON)
|
.header(ContentType::JSON)
|
||||||
.remote("127.0.0.1:8000".parse().unwrap())
|
.remote("127.0.0.1:8000".parse().unwrap())
|
||||||
.body(r#"{ "not_secret": "invalid" "#)
|
.body(r#"{ "not_secret": "invalid" "#)
|
||||||
|
@ -283,44 +431,48 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_command() {
|
fn parse_command() {
|
||||||
|
let mut map = HeaderMap::new();
|
||||||
|
map.add_raw("X-Gitea-Event", "something");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter("command", &serde_json::Value::Null).unwrap(),
|
replace_parameter("command", &map, &serde_json::Value::Null).unwrap(),
|
||||||
"command"
|
"command"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter(" command", &serde_json::Value::Null).unwrap(),
|
replace_parameter(" command", &map, &serde_json::Value::Null).unwrap(),
|
||||||
" command"
|
" command"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter("command ", &serde_json::Value::Null).unwrap(),
|
replace_parameter("command ", &map, &serde_json::Value::Null).unwrap(),
|
||||||
"command "
|
"command "
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter(" command ", &serde_json::Value::Null).unwrap(),
|
replace_parameter(" command ", &map, &serde_json::Value::Null).unwrap(),
|
||||||
" command "
|
" command "
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter("command command ", &serde_json::Value::Null).unwrap(),
|
replace_parameter("command command ", &map, &serde_json::Value::Null).unwrap(),
|
||||||
"command command "
|
"command command "
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter("{{ /foo }} command", &json!({ "foo": "bar" })).unwrap(),
|
replace_parameter("{{ /foo }} command", &map, &json!({ "foo": "bar" })).unwrap(),
|
||||||
"bar command"
|
"bar command"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter(" command {{ /foo }} ", &json!({ "foo": "bar" })).unwrap(),
|
replace_parameter(" command {{ /foo }} ", &map, &json!({ "foo": "bar" })).unwrap(),
|
||||||
" command bar "
|
" command bar "
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter(
|
replace_parameter(
|
||||||
"{{ /foo }} command{{/field1/foo}}",
|
"{{ /foo }} command{{/field1/foo}}",
|
||||||
|
&map,
|
||||||
&json!({ "foo": "bar", "field1": { "foo": "baz" } })
|
&json!({ "foo": "bar", "field1": { "foo": "baz" } })
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
@ -328,17 +480,20 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter(" command {{ /foo }} ", &json!({ "foo": "bar" })).unwrap(),
|
replace_parameter(" command {{ /foo }} ", &map, &json!({ "foo": "bar" })).unwrap(),
|
||||||
" command bar "
|
" command bar "
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
replace_parameter(
|
replace_parameter(
|
||||||
" {{ /field1/foo }} command",
|
" {{ /field1/foo }} command",
|
||||||
|
&map,
|
||||||
&json!({ "field1": { "foo": "bar" } })
|
&json!({ "field1": { "foo": "bar" } })
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
" bar command"
|
" bar command"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add tests with header fields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue