mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 20:15:07 +08:00
Merge pull request #464 from meilisearch/simplify-keys
Simplify keys & add launcher resume
This commit is contained in:
commit
8e6560d102
76
Cargo.lock
generated
76
Cargo.lock
generated
@ -153,6 +153,25 @@ name = "bitflags"
|
|||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-padding"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "broadcaster"
|
name = "broadcaster"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
@ -182,6 +201,11 @@ name = "bumpalo"
|
|||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-tools"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
@ -414,6 +438,14 @@ name = "deunicode"
|
|||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "discard"
|
name = "discard"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -470,6 +502,11 @@ dependencies = [
|
|||||||
"synstructure 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"synstructure 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fake-simd"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.6"
|
version = "1.0.6"
|
||||||
@ -640,6 +677,14 @@ dependencies = [
|
|||||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getopts"
|
name = "getopts"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@ -1043,6 +1088,7 @@ dependencies = [
|
|||||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_qs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_qs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"siphasher 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"siphasher 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"sysinfo 0.9.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -1202,6 +1248,11 @@ name = "once_cell"
|
|||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opaque-debug"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@ -1649,6 +1700,17 @@ name = "sha1"
|
|||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha2"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -2043,6 +2105,11 @@ name = "try-lock"
|
|||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
@ -2377,9 +2444,12 @@ dependencies = [
|
|||||||
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||||
"checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92"
|
"checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92"
|
||||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||||
|
"checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||||
"checksum broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "07a1446420a56f1030271649ba0da46d23239b3a68c73591cea5247f15a788a0"
|
"checksum broadcaster 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "07a1446420a56f1030271649ba0da46d23239b3a68c73591cea5247f15a788a0"
|
||||||
"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
|
"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
|
||||||
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
|
"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708"
|
||||||
|
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||||
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
||||||
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||||
@ -2406,6 +2476,7 @@ dependencies = [
|
|||||||
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
||||||
"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97"
|
"checksum data-encoding 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f47ca1860a761136924ddd2422ba77b2ea54fe8cc75b9040804a0d9d32ad97"
|
||||||
"checksum deunicode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a0f5bbdedde60605d0719b998e282af68e2b1c50203110211fe4abe857560"
|
"checksum deunicode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a0f5bbdedde60605d0719b998e282af68e2b1c50203110211fe4abe857560"
|
||||||
|
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||||
"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
"checksum discard 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||||
"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
|
"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
|
||||||
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||||
@ -2413,6 +2484,7 @@ dependencies = [
|
|||||||
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
|
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
|
||||||
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
|
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
|
||||||
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
|
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
|
||||||
|
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||||
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
|
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
|
||||||
"checksum fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "927fb434ff9f0115b215dc0efd2e4fbdd7448522a92a1aa37c77d6a2f8f1ebd6"
|
"checksum fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "927fb434ff9f0115b215dc0efd2e4fbdd7448522a92a1aa37c77d6a2f8f1ebd6"
|
||||||
@ -2435,6 +2507,7 @@ dependencies = [
|
|||||||
"checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6"
|
"checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6"
|
||||||
"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
|
"checksum futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76"
|
||||||
"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
|
"checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d"
|
||||||
|
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||||
"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
|
||||||
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
||||||
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
|
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
|
||||||
@ -2484,6 +2557,7 @@ dependencies = [
|
|||||||
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
|
||||||
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
|
"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
|
||||||
"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
|
"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
|
||||||
|
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||||
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
||||||
"checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242"
|
"checksum page_size 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f89ef58b3d32420dbd1a43d2f38ae92f6239ef12bb556ab09ca55445f5a67242"
|
||||||
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
|
"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
|
||||||
@ -2539,6 +2613,7 @@ dependencies = [
|
|||||||
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
"checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2"
|
||||||
"checksum serde_qs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "36278a86e341c46a42b0413ac3aa781902af93f5f4b10af098c704f4b96d81d8"
|
"checksum serde_qs 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "36278a86e341c46a42b0413ac3aa781902af93f5f4b10af098c704f4b96d81d8"
|
||||||
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
|
||||||
|
"checksum sha2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
|
||||||
"checksum siphasher 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83da420ee8d1a89e640d0948c646c1c088758d3a3c538f943bfa97bdac17929d"
|
"checksum siphasher 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "83da420ee8d1a89e640d0948c646c1c088758d3a3c538f943bfa97bdac17929d"
|
||||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||||
"checksum slice-group-by 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1f7474f0b646d228360ab62ed974744617bc869d959eac8403bfa3665931a7fb"
|
"checksum slice-group-by 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1f7474f0b646d228360ab62ed974744617bc869d959eac8403bfa3665931a7fb"
|
||||||
@ -2579,6 +2654,7 @@ dependencies = [
|
|||||||
"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
|
"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e"
|
||||||
"checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf"
|
"checksum toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf"
|
||||||
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||||
|
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||||
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||||
"checksum unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf"
|
"checksum unicode-normalization 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf"
|
||||||
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
|
@ -41,6 +41,7 @@ tide = "0.6.0"
|
|||||||
ureq = { version = "0.11.2", features = ["tls"], default-features = false }
|
ureq = { version = "0.11.2", features = ["tls"], default-features = false }
|
||||||
walkdir = "2.2.9"
|
walkdir = "2.2.9"
|
||||||
whoami = "0.6"
|
whoami = "0.6"
|
||||||
|
sha2 = "0.8.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
http-service-mock = "0.4.0"
|
http-service-mock = "0.4.0"
|
||||||
|
@ -7,6 +7,7 @@ use heed::types::{SerdeBincode, Str};
|
|||||||
use log::error;
|
use log::error;
|
||||||
use meilisearch_core::{Database, Error as MError, MResult, MainT, UpdateT};
|
use meilisearch_core::{Database, Error as MError, MResult, MainT, UpdateT};
|
||||||
use sysinfo::Pid;
|
use sysinfo::Pid;
|
||||||
|
use sha2::Digest;
|
||||||
|
|
||||||
use crate::option::Opt;
|
use crate::option::Opt;
|
||||||
use crate::routes::index::index_update_callback;
|
use crate::routes::index::index_update_callback;
|
||||||
@ -32,10 +33,34 @@ impl Deref for Data {
|
|||||||
pub struct DataInner {
|
pub struct DataInner {
|
||||||
pub db: Arc<Database>,
|
pub db: Arc<Database>,
|
||||||
pub db_path: String,
|
pub db_path: String,
|
||||||
pub api_key: Option<String>,
|
pub api_keys: ApiKeys,
|
||||||
pub server_pid: Pid,
|
pub server_pid: Pid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct ApiKeys {
|
||||||
|
pub public: Option<String>,
|
||||||
|
pub private: Option<String>,
|
||||||
|
pub master: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ApiKeys {
|
||||||
|
pub fn generate_missing_api_keys(&mut self) {
|
||||||
|
if let Some(master_key) = &self.master {
|
||||||
|
if self.private.is_none() {
|
||||||
|
let key = format!("{}-private", master_key);
|
||||||
|
let sha = sha2::Sha256::digest(key.as_bytes());
|
||||||
|
self.private = Some(format!("{:x}", sha));
|
||||||
|
}
|
||||||
|
if self.public.is_none() {
|
||||||
|
let key = format!("{}-public", master_key);
|
||||||
|
let sha = sha2::Sha256::digest(key.as_bytes());
|
||||||
|
self.public = Some(format!("{:x}", sha));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DataInner {
|
impl DataInner {
|
||||||
pub fn is_indexing(&self, reader: &heed::RoTxn<UpdateT>, index: &str) -> MResult<Option<bool>> {
|
pub fn is_indexing(&self, reader: &heed::RoTxn<UpdateT>, index: &str) -> MResult<Option<bool>> {
|
||||||
match self.db.open_index(&index) {
|
match self.db.open_index(&index) {
|
||||||
@ -107,15 +132,22 @@ impl DataInner {
|
|||||||
impl Data {
|
impl Data {
|
||||||
pub fn new(opt: Opt) -> Data {
|
pub fn new(opt: Opt) -> Data {
|
||||||
let db_path = opt.db_path.clone();
|
let db_path = opt.db_path.clone();
|
||||||
let api_key = opt.api_key.clone();
|
|
||||||
let server_pid = sysinfo::get_current_pid().unwrap();
|
let server_pid = sysinfo::get_current_pid().unwrap();
|
||||||
|
|
||||||
let db = Arc::new(Database::open_or_create(opt.db_path).unwrap());
|
let db = Arc::new(Database::open_or_create(opt.db_path).unwrap());
|
||||||
|
|
||||||
|
let mut api_keys = ApiKeys {
|
||||||
|
master: opt.master_key.clone(),
|
||||||
|
private: None,
|
||||||
|
public: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
api_keys.generate_missing_api_keys();
|
||||||
|
|
||||||
let inner_data = DataInner {
|
let inner_data = DataInner {
|
||||||
db: db.clone(),
|
db: db.clone(),
|
||||||
db_path,
|
db_path,
|
||||||
api_key,
|
api_keys,
|
||||||
server_pid,
|
server_pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::models::token::*;
|
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
use chrono::Utc;
|
|
||||||
use heed::types::{SerdeBincode, Str};
|
|
||||||
use meilisearch_core::Index;
|
use meilisearch_core::Index;
|
||||||
use tide::Request;
|
use tide::Request;
|
||||||
|
|
||||||
|
pub enum ACL {
|
||||||
|
Admin,
|
||||||
|
Private,
|
||||||
|
Public
|
||||||
|
}
|
||||||
|
|
||||||
pub trait RequestExt {
|
pub trait RequestExt {
|
||||||
fn is_allowed(&self, acl: ACL) -> SResult<()>;
|
fn is_allowed(&self, acl: ACL) -> SResult<()>;
|
||||||
fn header(&self, name: &str) -> SResult<String>;
|
|
||||||
fn url_param(&self, name: &str) -> SResult<String>;
|
fn url_param(&self, name: &str) -> SResult<String>;
|
||||||
fn index(&self) -> SResult<Index>;
|
fn index(&self) -> SResult<Index>;
|
||||||
fn identifier(&self) -> SResult<String>;
|
fn identifier(&self) -> SResult<String>;
|
||||||
@ -16,73 +18,36 @@ pub trait RequestExt {
|
|||||||
|
|
||||||
impl RequestExt for Request<Data> {
|
impl RequestExt for Request<Data> {
|
||||||
fn is_allowed(&self, acl: ACL) -> SResult<()> {
|
fn is_allowed(&self, acl: ACL) -> SResult<()> {
|
||||||
let api_key = match &self.state().api_key {
|
let user_api_key = self.header("X-Meili-API-Key");
|
||||||
Some(api_key) => api_key,
|
|
||||||
None => return Ok(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let user_api_key = self
|
match acl {
|
||||||
.header("X-Meili-API-Key")
|
ACL::Admin => {
|
||||||
.ok_or(ResponseError::missing_header("X-Meili-API-Key"))?;
|
if user_api_key == self.state().api_keys.master.as_deref() {
|
||||||
|
return Ok(())
|
||||||
if user_api_key == *api_key {
|
}
|
||||||
return Ok(());
|
},
|
||||||
}
|
ACL::Private => {
|
||||||
let request_index: Option<String> = None; //self.param::<String>("index").ok();
|
if user_api_key == self.state().api_keys.master.as_deref() {
|
||||||
|
return Ok(())
|
||||||
let db = &self.state().db;
|
}
|
||||||
let reader = db.main_read_txn()?;
|
if user_api_key == self.state().api_keys.private.as_deref() {
|
||||||
|
return Ok(())
|
||||||
let token_key = format!("{}{}", TOKEN_PREFIX_KEY, user_api_key);
|
}
|
||||||
|
},
|
||||||
let token_config = db
|
ACL::Public => {
|
||||||
.common_store()
|
if user_api_key == self.state().api_keys.master.as_deref() {
|
||||||
.get::<_, Str, SerdeBincode<Token>>(&reader, &token_key)?
|
return Ok(())
|
||||||
.ok_or(ResponseError::invalid_token(format!(
|
}
|
||||||
"Api key does not exist: {}",
|
if user_api_key == self.state().api_keys.private.as_deref() {
|
||||||
user_api_key
|
return Ok(())
|
||||||
)))?;
|
}
|
||||||
|
if user_api_key == self.state().api_keys.public.as_deref() {
|
||||||
if token_config.revoked {
|
return Ok(())
|
||||||
return Err(ResponseError::invalid_token("token revoked"));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(index) = request_index {
|
|
||||||
if !token_config
|
|
||||||
.indexes
|
|
||||||
.iter()
|
|
||||||
.any(|r| match_wildcard(&r, &index))
|
|
||||||
{
|
|
||||||
return Err(ResponseError::invalid_token(
|
|
||||||
"token is not allowed to access to this index",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if token_config.expires_at < Utc::now() {
|
Err(ResponseError::InvalidToken(user_api_key.unwrap_or("Need a token").to_owned()))
|
||||||
return Err(ResponseError::invalid_token("token expired"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if token_config.acl.contains(&ACL::All) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
if !token_config.acl.contains(&acl) {
|
|
||||||
return Err(ResponseError::invalid_token("no permission"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn header(&self, name: &str) -> SResult<String> {
|
|
||||||
let header = self
|
|
||||||
.headers()
|
|
||||||
.get(name)
|
|
||||||
.ok_or(ResponseError::missing_header(name))?
|
|
||||||
.to_str()
|
|
||||||
.map_err(|_| ResponseError::missing_header("X-Meili-API-Key"))?
|
|
||||||
.to_string();
|
|
||||||
Ok(header)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn url_param(&self, name: &str) -> SResult<String> {
|
fn url_param(&self, name: &str) -> SResult<String> {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use std::env::VarError::NotPresent;
|
|
||||||
use std::{env, thread};
|
use std::{env, thread};
|
||||||
|
|
||||||
use async_std::task;
|
use async_std::task;
|
||||||
@ -19,20 +18,35 @@ mod analytics;
|
|||||||
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
|
||||||
|
|
||||||
pub fn main() -> Result<(), MainError> {
|
pub fn main() -> Result<(), MainError> {
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
let opt = Opt::from_args();
|
let opt = Opt::from_args();
|
||||||
let data = Data::new(opt.clone());
|
|
||||||
|
|
||||||
if env::var("MEILI_NO_ANALYTICS") == Err(NotPresent) {
|
match opt.env.as_ref() {
|
||||||
|
"production" => {
|
||||||
|
if opt.master_key.is_none() {
|
||||||
|
return Err("In production mode, the environment variable MEILI_MASTER_KEY is mandatory".into());
|
||||||
|
}
|
||||||
|
env_logger::init();
|
||||||
|
},
|
||||||
|
"development" => {
|
||||||
|
env_logger::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !opt.no_analytics {
|
||||||
thread::spawn(analytics::analytics_sender);
|
thread::spawn(analytics::analytics_sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let data = Data::new(opt.clone());
|
||||||
|
|
||||||
let data_cloned = data.clone();
|
let data_cloned = data.clone();
|
||||||
data.db.set_update_callback(Box::new(move |name, status| {
|
data.db.set_update_callback(Box::new(move |name, status| {
|
||||||
index_update_callback(name, &data_cloned, status);
|
index_update_callback(name, &data_cloned, status);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
print_launch_resume(&opt, &data);
|
||||||
|
|
||||||
let mut app = tide::with_state(data);
|
let mut app = tide::with_state(data);
|
||||||
|
|
||||||
app.middleware(Cors::new());
|
app.middleware(Cors::new());
|
||||||
@ -40,8 +54,48 @@ pub fn main() -> Result<(), MainError> {
|
|||||||
|
|
||||||
routes::load_routes(&mut app);
|
routes::load_routes(&mut app);
|
||||||
|
|
||||||
info!("Server HTTP enabled");
|
|
||||||
|
|
||||||
task::block_on(app.listen(opt.http_addr))?;
|
task::block_on(app.listen(opt.http_addr))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn print_launch_resume(opt: &Opt, data: &Data) {
|
||||||
|
let ascii_name = r#"
|
||||||
|
888b d888 d8b 888 d8b .d8888b. 888
|
||||||
|
8888b d8888 Y8P 888 Y8P d88P Y88b 888
|
||||||
|
88888b.d88888 888 Y88b. 888
|
||||||
|
888Y88888P888 .d88b. 888 888 888 "Y888b. .d88b. 8888b. 888d888 .d8888b 88888b.
|
||||||
|
888 Y888P 888 d8P Y8b 888 888 888 "Y88b. d8P Y8b "88b 888P" d88P" 888 "88b
|
||||||
|
888 Y8P 888 88888888 888 888 888 "888 88888888 .d888888 888 888 888 888
|
||||||
|
888 " 888 Y8b. 888 888 888 Y88b d88P Y8b. 888 888 888 Y88b. 888 888
|
||||||
|
888 888 "Y8888 888 888 888 "Y8888P" "Y8888 "Y888888 888 "Y8888P 888 888
|
||||||
|
"#;
|
||||||
|
|
||||||
|
println!("{}", ascii_name);
|
||||||
|
|
||||||
|
info!("Database path: {:?}", opt.db_path);
|
||||||
|
info!("Start server on: {:?}", opt.http_addr);
|
||||||
|
info!("Environment: {:?}", opt.env);
|
||||||
|
info!("Commit SHA: {:?}", env!("VERGEN_SHA").to_string());
|
||||||
|
info!("Build date: {:?}", env!("VERGEN_BUILD_TIMESTAMP").to_string());
|
||||||
|
info!("Package version: {:?}", env!("CARGO_PKG_VERSION").to_string());
|
||||||
|
|
||||||
|
if let Some(master_key) = &data.api_keys.master {
|
||||||
|
info!("Master Key: {:?}", master_key);
|
||||||
|
|
||||||
|
if let Some(private_key) = &data.api_keys.private {
|
||||||
|
info!("Private Key: {:?}", private_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(public_key) = &data.api_keys.public {
|
||||||
|
info!("Public Key: {:?}", public_key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("No master key found; The server will have no securities.\
|
||||||
|
If you need some protection in development mode, please export a key. export MEILI_MASTER_KEY=xxx");
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("If you need extra information; Please refer to the documentation: http://docs.meilisearch.com");
|
||||||
|
info!("If you want to support us or help us; Please consult our Github repo: http://github.com/meilisearch/meilisearch");
|
||||||
|
info!("If you want to contact us; Please chat with us on http://meilisearch.com or by email to bonjour@meilisearch.com");
|
||||||
|
}
|
||||||
|
@ -1,2 +1 @@
|
|||||||
pub mod token;
|
|
||||||
pub mod update_operation;
|
pub mod update_operation;
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
use chrono::{DateTime, Utc};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
pub const TOKEN_PREFIX_KEY: &str = "_token_";
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub enum ACL {
|
|
||||||
IndexesRead,
|
|
||||||
IndexesWrite,
|
|
||||||
DocumentsRead,
|
|
||||||
DocumentsWrite,
|
|
||||||
SettingsRead,
|
|
||||||
SettingsWrite,
|
|
||||||
Admin,
|
|
||||||
#[serde(rename = "*")]
|
|
||||||
All,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Wildcard = String;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Token {
|
|
||||||
pub key: String,
|
|
||||||
pub description: String,
|
|
||||||
pub acl: Vec<ACL>,
|
|
||||||
pub indexes: Vec<Wildcard>,
|
|
||||||
pub created_at: DateTime<Utc>,
|
|
||||||
pub updated_at: DateTime<Utc>,
|
|
||||||
pub expires_at: DateTime<Utc>,
|
|
||||||
pub revoked: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cleanup_wildcard(input: &str) -> (bool, &str, bool) {
|
|
||||||
let first = input.chars().next().filter(|&c| c == '*').is_some();
|
|
||||||
let last = input.chars().last().filter(|&c| c == '*').is_some();
|
|
||||||
let bound_last = std::cmp::max(input.len().saturating_sub(last as usize), first as usize);
|
|
||||||
let output = input.get(first as usize..bound_last).unwrap();
|
|
||||||
(first, output, last)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn match_wildcard(pattern: &str, input: &str) -> bool {
|
|
||||||
let (first, pattern, last) = cleanup_wildcard(pattern);
|
|
||||||
|
|
||||||
match (first, last) {
|
|
||||||
(false, false) => pattern == input,
|
|
||||||
(true, false) => input.ends_with(pattern),
|
|
||||||
(false, true) => input.starts_with(pattern),
|
|
||||||
(true, true) => input.contains(pattern),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_match_wildcard() {
|
|
||||||
assert!(match_wildcard("*", "qqq"));
|
|
||||||
assert!(match_wildcard("*", ""));
|
|
||||||
assert!(match_wildcard("*ab", "qqqab"));
|
|
||||||
assert!(match_wildcard("*ab*", "qqqabqq"));
|
|
||||||
assert!(match_wildcard("ab*", "abqqq"));
|
|
||||||
assert!(match_wildcard("**", "ab"));
|
|
||||||
assert!(match_wildcard("ab", "ab"));
|
|
||||||
assert!(match_wildcard("ab*", "ab"));
|
|
||||||
assert!(match_wildcard("*ab", "ab"));
|
|
||||||
assert!(match_wildcard("*ab*", "ab"));
|
|
||||||
assert!(match_wildcard("*😆*", "ab😆dsa"));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
const POSSIBLE_ENV: [&str; 2] = ["development", "production"];
|
||||||
|
|
||||||
#[derive(Debug, Clone, StructOpt)]
|
#[derive(Debug, Clone, StructOpt)]
|
||||||
pub struct Opt {
|
pub struct Opt {
|
||||||
/// The destination where the database must be created.
|
/// The destination where the database must be created.
|
||||||
@ -11,8 +13,15 @@ pub struct Opt {
|
|||||||
pub http_addr: String,
|
pub http_addr: String,
|
||||||
|
|
||||||
/// The master key allowing you to do everything on the server.
|
/// The master key allowing you to do everything on the server.
|
||||||
#[structopt(long, env = "MEILI_API_KEY")]
|
#[structopt(long, env = "MEILI_MASTER_KEY")]
|
||||||
pub api_key: Option<String>,
|
pub master_key: Option<String>,
|
||||||
|
|
||||||
|
/// This environment variable must be set to `production` if your are running in production.
|
||||||
|
/// Could be `production` or `development`
|
||||||
|
/// - `production`: Force api keys
|
||||||
|
/// - `development`: Show logs in "info" mode + not mendatory to specify the api keys
|
||||||
|
#[structopt(long, env = "MEILI_ENV", default_value = "development", possible_values = &POSSIBLE_ENV)]
|
||||||
|
pub env: String,
|
||||||
|
|
||||||
/// Do not send analytics to Meili.
|
/// Do not send analytics to Meili.
|
||||||
#[structopt(long, env = "MEILI_NO_ANALYTICS")]
|
#[structopt(long, env = "MEILI_NO_ANALYTICS")]
|
||||||
|
@ -8,11 +8,11 @@ use tide::{Request, Response};
|
|||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get_document(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_document(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsRead)?;
|
ctx.is_allowed(Public)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ pub struct IndexUpdateResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_document(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_document(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let identifier = ctx.identifier()?;
|
let identifier = ctx.identifier()?;
|
||||||
@ -66,7 +66,7 @@ struct BrowseQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_documents(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_all_documents(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let query: BrowseQuery = ctx.query().unwrap_or_default();
|
let query: BrowseQuery = ctx.query().unwrap_or_default();
|
||||||
@ -125,7 +125,7 @@ struct UpdateDocumentsQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn update_multiple_documents(mut ctx: Request<Data>, is_partial: bool) -> SResult<Response> {
|
async fn update_multiple_documents(mut ctx: Request<Data>, is_partial: bool) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ pub async fn add_or_update_multiple_documents(ctx: Request<Data>) -> SResult<Res
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_multiple_documents(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_multiple_documents(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let data: Vec<Value> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let data: Vec<Value> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -204,7 +204,7 @@ pub async fn delete_multiple_documents(mut ctx: Request<Data>) -> SResult<Respon
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn clear_all_documents(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn clear_all_documents(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(DocumentsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
use heed::types::{Str, Unit};
|
use heed::types::{Str, Unit};
|
||||||
|
@ -9,7 +9,7 @@ use tide::{Request, Response};
|
|||||||
|
|
||||||
use crate::error::{IntoInternalError, ResponseError, SResult};
|
use crate::error::{IntoInternalError, ResponseError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
fn generate_uid() -> String {
|
fn generate_uid() -> String {
|
||||||
@ -22,7 +22,7 @@ fn generate_uid() -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_indexes(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn list_indexes(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let indexes_uids = ctx.state().db.indexes_uids();
|
let indexes_uids = ctx.state().db.indexes_uids();
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ struct IndexResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_index(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_index(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ struct IndexCreateResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_index(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn create_index(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let body = ctx
|
let body = ctx
|
||||||
.body_json::<IndexCreateRequest>()
|
.body_json::<IndexCreateRequest>()
|
||||||
@ -201,7 +201,7 @@ struct UpdateIndexResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_index(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_index(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let body = ctx
|
let body = ctx
|
||||||
.body_json::<UpdateIndexRequest>()
|
.body_json::<UpdateIndexRequest>()
|
||||||
@ -250,7 +250,7 @@ pub async fn update_index(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_update_status(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_update_status(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.update_read_txn()?;
|
let reader = db.update_read_txn()?;
|
||||||
@ -273,7 +273,7 @@ pub async fn get_update_status(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_updates_status(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_all_updates_status(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.update_read_txn()?;
|
let reader = db.update_read_txn()?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
@ -282,7 +282,7 @@ pub async fn get_all_updates_status(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_index(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_index(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(IndexesWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let _ = ctx.index()?;
|
let _ = ctx.index()?;
|
||||||
let index_uid = ctx.url_param("index")?;
|
let index_uid = ctx.url_param("index")?;
|
||||||
ctx.state().db.delete_index(&index_uid)?;
|
ctx.state().db.delete_index(&index_uid)?;
|
||||||
|
@ -1,172 +1,18 @@
|
|||||||
use chrono::serde::ts_seconds;
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use heed::types::{SerdeBincode, Str};
|
|
||||||
use rand::seq::SliceRandom;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use tide::{Request, Response};
|
use tide::{Request, Response};
|
||||||
|
use serde_json::json;
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::SResult;
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::models::token::*;
|
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
fn generate_api_key() -> String {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
let sample = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
||||||
sample
|
|
||||||
.choose_multiple(&mut rng, 40)
|
|
||||||
.map(|c| *c as char)
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn list(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn list(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(Admin)?;
|
ctx.is_allowed(Admin)?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let keys = &ctx.state().api_keys;
|
||||||
let reader = db.main_read_txn()?;
|
|
||||||
|
|
||||||
let common_store = db.common_store();
|
Ok(tide::Response::new(200)
|
||||||
|
.body_json(&json!({
|
||||||
let mut response: Vec<Token> = Vec::new();
|
"private": keys.private,
|
||||||
|
"public": keys.public,
|
||||||
let iter =
|
}))?)
|
||||||
common_store.prefix_iter::<_, Str, SerdeBincode<Token>>(&reader, TOKEN_PREFIX_KEY)?;
|
|
||||||
|
|
||||||
for result in iter {
|
|
||||||
let (_, token) = result?;
|
|
||||||
response.push(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(tide::Response::new(200).body_json(&response).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
|
||||||
ctx.is_allowed(Admin)?;
|
|
||||||
let request_key = ctx.url_param("key")?;
|
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
|
||||||
let reader = db.main_read_txn()?;
|
|
||||||
|
|
||||||
let token_key = format!("{}{}", TOKEN_PREFIX_KEY, request_key);
|
|
||||||
|
|
||||||
let token_config = db
|
|
||||||
.common_store()
|
|
||||||
.get::<_, Str, SerdeBincode<Token>>(&reader, &token_key)?
|
|
||||||
.ok_or(ResponseError::not_found(format!(
|
|
||||||
"token key: {}",
|
|
||||||
token_key
|
|
||||||
)))?;
|
|
||||||
|
|
||||||
Ok(tide::Response::new(200).body_json(&token_config).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
|
||||||
pub struct CreatedRequest {
|
|
||||||
description: String,
|
|
||||||
acl: Vec<ACL>,
|
|
||||||
indexes: Vec<Wildcard>,
|
|
||||||
#[serde(with = "ts_seconds")]
|
|
||||||
expires_at: DateTime<Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn create(mut ctx: Request<Data>) -> SResult<Response> {
|
|
||||||
ctx.is_allowed(Admin)?;
|
|
||||||
|
|
||||||
let data: CreatedRequest = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
|
||||||
|
|
||||||
let key = generate_api_key();
|
|
||||||
let token_key = format!("{}{}", TOKEN_PREFIX_KEY, key);
|
|
||||||
|
|
||||||
let token_definition = Token {
|
|
||||||
key,
|
|
||||||
description: data.description,
|
|
||||||
acl: data.acl,
|
|
||||||
indexes: data.indexes,
|
|
||||||
expires_at: data.expires_at,
|
|
||||||
created_at: Utc::now(),
|
|
||||||
updated_at: Utc::now(),
|
|
||||||
revoked: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
|
||||||
let mut writer = db.main_write_txn()?;
|
|
||||||
|
|
||||||
db.common_store().put::<_, Str, SerdeBincode<Token>>(
|
|
||||||
&mut writer,
|
|
||||||
&token_key,
|
|
||||||
&token_definition,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
writer.commit()?;
|
|
||||||
Ok(tide::Response::new(201)
|
|
||||||
.body_json(&token_definition)
|
|
||||||
.unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
|
||||||
pub struct UpdatedRequest {
|
|
||||||
description: Option<String>,
|
|
||||||
acl: Option<Vec<ACL>>,
|
|
||||||
indexes: Option<Vec<Wildcard>>,
|
|
||||||
expires_at: Option<DateTime<Utc>>,
|
|
||||||
revoked: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
|
||||||
ctx.is_allowed(Admin)?;
|
|
||||||
let request_key = ctx.url_param("key")?;
|
|
||||||
|
|
||||||
let data: UpdatedRequest = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
|
||||||
let mut writer = db.main_write_txn()?;
|
|
||||||
|
|
||||||
let common_store = db.common_store();
|
|
||||||
|
|
||||||
let token_key = format!("{}{}", TOKEN_PREFIX_KEY, request_key);
|
|
||||||
|
|
||||||
let mut token_config = common_store
|
|
||||||
.get::<_, Str, SerdeBincode<Token>>(&writer, &token_key)?
|
|
||||||
.ok_or(ResponseError::not_found(format!(
|
|
||||||
"token key: {}",
|
|
||||||
token_key
|
|
||||||
)))?;
|
|
||||||
|
|
||||||
// apply the modifications
|
|
||||||
if let Some(description) = data.description {
|
|
||||||
token_config.description = description;
|
|
||||||
}
|
|
||||||
if let Some(acl) = data.acl {
|
|
||||||
token_config.acl = acl;
|
|
||||||
}
|
|
||||||
if let Some(indexes) = data.indexes {
|
|
||||||
token_config.indexes = indexes;
|
|
||||||
}
|
|
||||||
if let Some(expires_at) = data.expires_at {
|
|
||||||
token_config.expires_at = expires_at;
|
|
||||||
}
|
|
||||||
if let Some(revoked) = data.revoked {
|
|
||||||
token_config.revoked = revoked;
|
|
||||||
}
|
|
||||||
|
|
||||||
token_config.updated_at = Utc::now();
|
|
||||||
common_store.put::<_, Str, SerdeBincode<Token>>(&mut writer, &token_key, &token_config)?;
|
|
||||||
writer.commit()?;
|
|
||||||
|
|
||||||
Ok(tide::Response::new(200).body_json(&token_config).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
|
||||||
ctx.is_allowed(Admin)?;
|
|
||||||
let request_key = ctx.url_param("key")?;
|
|
||||||
let db = &ctx.state().db;
|
|
||||||
let mut writer = db.main_write_txn()?;
|
|
||||||
let common_store = db.common_store();
|
|
||||||
let token_key = format!("{}{}", TOKEN_PREFIX_KEY, request_key);
|
|
||||||
common_store.delete::<_, Str>(&mut writer, &token_key)?;
|
|
||||||
writer.commit()?;
|
|
||||||
Ok(tide::Response::new(204))
|
|
||||||
}
|
}
|
||||||
|
@ -118,13 +118,7 @@ pub fn load_routes(app: &mut tide::Server<Data>) {
|
|||||||
.get(|ctx| into_response(stats::index_stats(ctx)));
|
.get(|ctx| into_response(stats::index_stats(ctx)));
|
||||||
|
|
||||||
app.at("/keys/")
|
app.at("/keys/")
|
||||||
.get(|ctx| into_response(key::list(ctx)))
|
.get(|ctx| into_response(key::list(ctx)));
|
||||||
.post(|ctx| into_response(key::create(ctx)));
|
|
||||||
|
|
||||||
app.at("/keys/:key")
|
|
||||||
.get(|ctx| into_response(key::get(ctx)))
|
|
||||||
.put(|ctx| into_response(key::update(ctx)))
|
|
||||||
.delete(|ctx| into_response(key::delete(ctx)));
|
|
||||||
|
|
||||||
app.at("/health")
|
app.at("/health")
|
||||||
.get(|ctx| into_response(health::get_health(ctx)))
|
.get(|ctx| into_response(health::get_health(ctx)))
|
||||||
|
@ -7,6 +7,7 @@ use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tide::{Request, Response};
|
use tide::{Request, Response};
|
||||||
|
|
||||||
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchHit};
|
use crate::helpers::meilisearch::{Error, IndexSearchExt, SearchHit};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
@ -28,7 +29,7 @@ struct SearchQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search_with_url_query(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn search_with_url_query(ctx: Request<Data>) -> SResult<Response> {
|
||||||
// ctx.is_allowed(DocumentsRead)?;
|
ctx.is_allowed(Public)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
@ -143,7 +144,7 @@ struct SearchMultiBodyResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search_multi_index(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn search_multi_index(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
// ctx.is_allowed(DocumentsRead)?;
|
ctx.is_allowed(Public)?;
|
||||||
let body = ctx
|
let body = ctx
|
||||||
.body_json::<SearchMultiBody>()
|
.body_json::<SearchMultiBody>()
|
||||||
.await
|
.await
|
||||||
|
@ -5,12 +5,12 @@ use tide::{Request, Response};
|
|||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::routes::document::IndexUpdateResponse;
|
use crate::routes::document::IndexUpdateResponse;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get_all(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_all(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -106,7 +106,7 @@ pub struct UpdateSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_all(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_all(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let settings_update: UpdateSettings =
|
let settings_update: UpdateSettings =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -131,7 +131,7 @@ pub async fn update_all(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_all(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_all(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let mut writer = db.update_write_txn()?;
|
let mut writer = db.update_write_txn()?;
|
||||||
@ -156,7 +156,7 @@ pub async fn delete_all(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_rules(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_rules(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -170,7 +170,7 @@ pub async fn get_rules(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_rules(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_rules(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let ranking_rules: Option<Vec<String>> =
|
let ranking_rules: Option<Vec<String>> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -190,7 +190,7 @@ pub async fn update_rules(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_rules(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_rules(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let mut writer = db.update_write_txn()?;
|
let mut writer = db.update_write_txn()?;
|
||||||
@ -209,7 +209,7 @@ pub async fn delete_rules(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_distinct(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_distinct(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -222,7 +222,7 @@ pub async fn get_distinct(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_distinct(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_distinct(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let ranking_distinct: Option<String> =
|
let ranking_distinct: Option<String> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -242,7 +242,7 @@ pub async fn update_distinct(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_distinct(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_distinct(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let mut writer = db.update_write_txn()?;
|
let mut writer = db.update_write_txn()?;
|
||||||
@ -261,7 +261,7 @@ pub async fn delete_distinct(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_identifier(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_identifier(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -274,7 +274,7 @@ pub async fn get_identifier(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_searchable(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_searchable(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -290,7 +290,7 @@ pub async fn get_searchable(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_searchable(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_searchable(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let searchable_attributes: Option<Vec<String>> =
|
let searchable_attributes: Option<Vec<String>> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -310,7 +310,7 @@ pub async fn update_searchable(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_searchable(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_searchable(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ pub async fn delete_searchable(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn displayed(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn displayed(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -348,7 +348,7 @@ pub async fn displayed(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_displayed(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_displayed(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let displayed_attributes: Option<HashSet<String>> =
|
let displayed_attributes: Option<HashSet<String>> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -368,7 +368,7 @@ pub async fn update_displayed(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_displayed(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete_displayed(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ pub async fn delete_displayed(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_index_new_fields(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get_index_new_fields(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -401,7 +401,7 @@ pub async fn get_index_new_fields(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_index_new_fields(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update_index_new_fields(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let index_new_fields: Option<bool> =
|
let index_new_fields: Option<bool> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
|
@ -10,7 +10,7 @@ use walkdir::WalkDir;
|
|||||||
|
|
||||||
use crate::error::{IntoInternalError, SResult};
|
use crate::error::{IntoInternalError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -5,12 +5,12 @@ use tide::{Request, Response};
|
|||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::routes::document::IndexUpdateResponse;
|
use crate::routes::document::IndexUpdateResponse;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
let reader = db.main_read_txn()?;
|
let reader = db.main_read_txn()?;
|
||||||
@ -21,7 +21,7 @@ pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
let data: BTreeSet<String> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
let data: BTreeSet<String> = ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -43,7 +43,7 @@ pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
|
@ -6,12 +6,12 @@ use tide::{Request, Response};
|
|||||||
|
|
||||||
use crate::error::{ResponseError, SResult};
|
use crate::error::{ResponseError, SResult};
|
||||||
use crate::helpers::tide::RequestExt;
|
use crate::helpers::tide::RequestExt;
|
||||||
use crate::models::token::ACL::*;
|
use crate::helpers::tide::ACL::*;
|
||||||
use crate::routes::document::IndexUpdateResponse;
|
use crate::routes::document::IndexUpdateResponse;
|
||||||
use crate::Data;
|
use crate::Data;
|
||||||
|
|
||||||
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsRead)?;
|
ctx.is_allowed(Private)?;
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
let db = &ctx.state().db;
|
let db = &ctx.state().db;
|
||||||
@ -37,7 +37,7 @@ pub async fn get(ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let data: BTreeMap<String, Vec<String>> =
|
let data: BTreeMap<String, Vec<String>> =
|
||||||
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
ctx.body_json().await.map_err(ResponseError::bad_request)?;
|
||||||
@ -61,7 +61,7 @@ pub async fn update(mut ctx: Request<Data>) -> SResult<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
pub async fn delete(ctx: Request<Data>) -> SResult<Response> {
|
||||||
ctx.is_allowed(SettingsWrite)?;
|
ctx.is_allowed(Private)?;
|
||||||
|
|
||||||
let index = ctx.index()?;
|
let index = ctx.index()?;
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ pub fn setup_server() -> Result<TestBackend<Service<Data>>, Box<dyn Error>> {
|
|||||||
let opt = Opt {
|
let opt = Opt {
|
||||||
db_path: tmp_dir.path().to_str().unwrap().to_string(),
|
db_path: tmp_dir.path().to_str().unwrap().to_string(),
|
||||||
http_addr: "127.0.0.1:7700".to_owned(),
|
http_addr: "127.0.0.1:7700".to_owned(),
|
||||||
api_key: None,
|
master_key: None,
|
||||||
|
env: "development".to_owned(),
|
||||||
no_analytics: true,
|
no_analytics: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user