# It is not intended for manual editing.
version = 3
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff"
+[[package]]
+name = "crc32fast"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
"instant",
]
+[[package]]
+name = "flate2"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
+dependencies = [
+ "cfg-if",
+ "crc32fast",
+ "libc",
+ "miniz_oxide",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
+[[package]]
+name = "miniz_oxide"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
+dependencies = [
+ "adler",
+ "autocfg",
+]
+
[[package]]
name = "mio"
version = "0.7.13"
"unicode-xid",
]
+[[package]]
+name = "procfs"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd"
+dependencies = [
+ "bitflags",
+ "byteorder",
+ "flate2",
+ "hex",
+ "lazy_static",
+ "libc",
+]
+
[[package]]
name = "prometheus"
version = "0.12.0"
"cfg-if",
"fnv",
"lazy_static",
+ "libc",
"memchr",
"parking_lot",
+ "procfs",
"protobuf",
"thiserror",
]
def raze_fetch_remote_crates():
"""This function defines a collection of repos and should be called in a WORKSPACE file"""
+ maybe(
+ http_archive,
+ name = "raze__adler__1_0_2",
+ url = "https://crates.io/api/v1/crates/adler/1.0.2/download",
+ type = "tar.gz",
+ sha256 = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe",
+ strip_prefix = "adler-1.0.2",
+ build_file = Label("//cargo/remote:BUILD.adler-1.0.2.bazel"),
+ )
+
maybe(
http_archive,
name = "raze__aho_corasick__0_7_18",
build_file = Label("//cargo/remote:BUILD.crc16-0.4.0.bazel"),
)
+ maybe(
+ http_archive,
+ name = "raze__crc32fast__1_2_1",
+ url = "https://crates.io/api/v1/crates/crc32fast/1.2.1/download",
+ type = "tar.gz",
+ sha256 = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a",
+ strip_prefix = "crc32fast-1.2.1",
+ build_file = Label("//cargo/remote:BUILD.crc32fast-1.2.1.bazel"),
+ )
+
maybe(
http_archive,
name = "raze__crossbeam_channel__0_5_1",
build_file = Label("//cargo/remote:BUILD.fastrand-1.5.0.bazel"),
)
+ maybe(
+ http_archive,
+ name = "raze__flate2__1_0_22",
+ url = "https://crates.io/api/v1/crates/flate2/1.0.22/download",
+ type = "tar.gz",
+ sha256 = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f",
+ strip_prefix = "flate2-1.0.22",
+ build_file = Label("//cargo/remote:BUILD.flate2-1.0.22.bazel"),
+ )
+
maybe(
http_archive,
name = "raze__fnv__1_0_7",
build_file = Label("//cargo/remote:BUILD.memchr-2.4.1.bazel"),
)
+ maybe(
+ http_archive,
+ name = "raze__miniz_oxide__0_4_4",
+ url = "https://crates.io/api/v1/crates/miniz_oxide/0.4.4/download",
+ type = "tar.gz",
+ sha256 = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b",
+ strip_prefix = "miniz_oxide-0.4.4",
+ build_file = Label("//cargo/remote:BUILD.miniz_oxide-0.4.4.bazel"),
+ )
+
maybe(
http_archive,
name = "raze__mio__0_7_13",
build_file = Label("//cargo/remote:BUILD.proc-macro2-1.0.29.bazel"),
)
+ maybe(
+ http_archive,
+ name = "raze__procfs__0_9_1",
+ url = "https://crates.io/api/v1/crates/procfs/0.9.1/download",
+ type = "tar.gz",
+ sha256 = "ab8809e0c18450a2db0f236d2a44ec0b4c1412d0eb936233579f0990faa5d5cd",
+ strip_prefix = "procfs-0.9.1",
+ build_file = Label("//cargo/remote:BUILD.procfs-0.9.1.bazel"),
+ )
+
maybe(
http_archive,
name = "raze__prometheus__0_12_0",
--- /dev/null
+"""
+@generated
+cargo-raze crate build file.
+
+DO NOT EDIT! Replaced on runs of cargo-raze
+"""
+
+# buildifier: disable=load
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+# buildifier: disable=load
+load(
+ "@rules_rust//rust:rust.bzl",
+ "rust_binary",
+ "rust_library",
+ "rust_test",
+)
+
+package(default_visibility = [
+ # Public for visibility by "@raze__crate__version//" targets.
+ #
+ # Prefer access through "//cargo", which limits external
+ # visibility to explicit Cargo.toml dependencies.
+ "//visibility:public",
+])
+
+licenses([
+ "notice", # MIT from expression "0BSD OR (MIT OR Apache-2.0)"
+])
+
+# Generated Targets
+
+# Unsupported target "bench" with type "bench" omitted
+
+rust_library(
+ name = "adler",
+ srcs = glob(["**/*.rs"]),
+ crate_features = [
+ ],
+ crate_root = "src/lib.rs",
+ crate_type = "lib",
+ data = [],
+ edition = "2015",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "1.0.2",
+ # buildifier: leave-alone
+ deps = [
+ ],
+)
--- /dev/null
+"""
+@generated
+cargo-raze crate build file.
+
+DO NOT EDIT! Replaced on runs of cargo-raze
+"""
+
+# buildifier: disable=load
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+# buildifier: disable=load
+load(
+ "@rules_rust//rust:rust.bzl",
+ "rust_binary",
+ "rust_library",
+ "rust_test",
+)
+
+package(default_visibility = [
+ # Public for visibility by "@raze__crate__version//" targets.
+ #
+ # Prefer access through "//cargo", which limits external
+ # visibility to explicit Cargo.toml dependencies.
+ "//visibility:public",
+])
+
+licenses([
+ "notice", # MIT from expression "MIT OR Apache-2.0"
+])
+
+# Generated Targets
+# buildifier: disable=out-of-order-load
+# buildifier: disable=load-on-top
+load(
+ "@rules_rust//cargo:cargo_build_script.bzl",
+ "cargo_build_script",
+)
+
+cargo_build_script(
+ name = "crc32fast_build_script",
+ srcs = glob(["**/*.rs"]),
+ build_script_env = {
+ },
+ crate_features = [
+ "default",
+ "std",
+ ],
+ crate_root = "build.rs",
+ data = glob(["**"]),
+ edition = "2015",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "1.2.1",
+ visibility = ["//visibility:private"],
+ deps = [
+ ],
+)
+
+# Unsupported target "bench" with type "bench" omitted
+
+rust_library(
+ name = "crc32fast",
+ srcs = glob(["**/*.rs"]),
+ crate_features = [
+ "default",
+ "std",
+ ],
+ crate_root = "src/lib.rs",
+ crate_type = "lib",
+ data = [],
+ edition = "2015",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "1.2.1",
+ # buildifier: leave-alone
+ deps = [
+ ":crc32fast_build_script",
+ "@raze__cfg_if__1_0_0//:cfg_if",
+ ],
+)
--- /dev/null
+"""
+@generated
+cargo-raze crate build file.
+
+DO NOT EDIT! Replaced on runs of cargo-raze
+"""
+
+# buildifier: disable=load
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+# buildifier: disable=load
+load(
+ "@rules_rust//rust:rust.bzl",
+ "rust_binary",
+ "rust_library",
+ "rust_test",
+)
+
+package(default_visibility = [
+ # Public for visibility by "@raze__crate__version//" targets.
+ #
+ # Prefer access through "//cargo", which limits external
+ # visibility to explicit Cargo.toml dependencies.
+ "//visibility:public",
+])
+
+licenses([
+ "notice", # MIT from expression "MIT OR Apache-2.0"
+])
+
+# Generated Targets
+
+# Unsupported target "compress_file" with type "example" omitted
+
+# Unsupported target "deflatedecoder-bufread" with type "example" omitted
+
+# Unsupported target "deflatedecoder-read" with type "example" omitted
+
+# Unsupported target "deflatedecoder-write" with type "example" omitted
+
+# Unsupported target "deflateencoder-bufread" with type "example" omitted
+
+# Unsupported target "deflateencoder-read" with type "example" omitted
+
+# Unsupported target "deflateencoder-write" with type "example" omitted
+
+# Unsupported target "gzbuilder" with type "example" omitted
+
+# Unsupported target "gzdecoder-bufread" with type "example" omitted
+
+# Unsupported target "gzdecoder-read" with type "example" omitted
+
+# Unsupported target "gzdecoder-write" with type "example" omitted
+
+# Unsupported target "gzencoder-bufread" with type "example" omitted
+
+# Unsupported target "gzencoder-read" with type "example" omitted
+
+# Unsupported target "gzencoder-write" with type "example" omitted
+
+# Unsupported target "gzmultidecoder-bufread" with type "example" omitted
+
+# Unsupported target "gzmultidecoder-read" with type "example" omitted
+
+# Unsupported target "zlibdecoder-bufread" with type "example" omitted
+
+# Unsupported target "zlibdecoder-read" with type "example" omitted
+
+# Unsupported target "zlibdecoder-write" with type "example" omitted
+
+# Unsupported target "zlibencoder-bufread" with type "example" omitted
+
+# Unsupported target "zlibencoder-read" with type "example" omitted
+
+# Unsupported target "zlibencoder-write" with type "example" omitted
+
+rust_library(
+ name = "flate2",
+ srcs = glob(["**/*.rs"]),
+ aliases = {
+ },
+ crate_features = [
+ "default",
+ "miniz_oxide",
+ "rust_backend",
+ ],
+ crate_root = "src/lib.rs",
+ crate_type = "lib",
+ data = [],
+ compile_data = glob(["*/**"]),
+ edition = "2018",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "1.0.22",
+ # buildifier: leave-alone
+ deps = [
+ "@raze__cfg_if__1_0_0//:cfg_if",
+ "@raze__crc32fast__1_2_1//:crc32fast",
+ "@raze__libc__0_2_101//:libc",
+ "@raze__miniz_oxide__0_4_4//:miniz_oxide",
+ ] + selects.with_or({
+ # cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))
+ (
+ "@rules_rust//rust/platform:wasm32-unknown-unknown",
+ "@rules_rust//rust/platform:wasm32-wasi",
+ ): [
+ ],
+ "//conditions:default": [],
+ }),
+)
+
+# Unsupported target "async-reader" with type "test" omitted
+
+# Unsupported target "early-flush" with type "test" omitted
+
+# Unsupported target "empty-read" with type "test" omitted
+
+# Unsupported target "gunzip" with type "test" omitted
+
+# Unsupported target "tokio" with type "test" omitted
+
+# Unsupported target "zero-write" with type "test" omitted
--- /dev/null
+"""
+@generated
+cargo-raze crate build file.
+
+DO NOT EDIT! Replaced on runs of cargo-raze
+"""
+
+# buildifier: disable=load
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+# buildifier: disable=load
+load(
+ "@rules_rust//rust:rust.bzl",
+ "rust_binary",
+ "rust_library",
+ "rust_test",
+)
+
+package(default_visibility = [
+ # Public for visibility by "@raze__crate__version//" targets.
+ #
+ # Prefer access through "//cargo", which limits external
+ # visibility to explicit Cargo.toml dependencies.
+ "//visibility:public",
+])
+
+licenses([
+ "notice", # MIT from expression "MIT OR (Zlib OR Apache-2.0)"
+])
+
+# Generated Targets
+# buildifier: disable=out-of-order-load
+# buildifier: disable=load-on-top
+load(
+ "@rules_rust//cargo:cargo_build_script.bzl",
+ "cargo_build_script",
+)
+
+cargo_build_script(
+ name = "miniz_oxide_build_script",
+ srcs = glob(["**/*.rs"]),
+ build_script_env = {
+ },
+ crate_features = [
+ ],
+ crate_root = "build.rs",
+ data = glob(["**"]),
+ edition = "2018",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "0.4.4",
+ visibility = ["//visibility:private"],
+ deps = [
+ "@raze__autocfg__1_0_1//:autocfg",
+ ],
+)
+
+rust_library(
+ name = "miniz_oxide",
+ srcs = glob(["**/*.rs"]),
+ crate_features = [
+ ],
+ crate_root = "src/lib.rs",
+ crate_type = "lib",
+ data = [],
+ edition = "2018",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "0.4.4",
+ # buildifier: leave-alone
+ deps = [
+ ":miniz_oxide_build_script",
+ "@raze__adler__1_0_2//:adler",
+ ],
+)
--- /dev/null
+"""
+@generated
+cargo-raze crate build file.
+
+DO NOT EDIT! Replaced on runs of cargo-raze
+"""
+
+# buildifier: disable=load
+load("@bazel_skylib//lib:selects.bzl", "selects")
+
+# buildifier: disable=load
+load(
+ "@rules_rust//rust:rust.bzl",
+ "rust_binary",
+ "rust_library",
+ "rust_test",
+)
+
+package(default_visibility = [
+ # Public for visibility by "@raze__crate__version//" targets.
+ #
+ # Prefer access through "//cargo", which limits external
+ # visibility to explicit Cargo.toml dependencies.
+ "//visibility:public",
+])
+
+licenses([
+ "notice", # MIT from expression "MIT OR Apache-2.0"
+])
+
+# Generated Targets
+
+# Unsupported target "diskstat" with type "example" omitted
+
+# Unsupported target "dump" with type "example" omitted
+
+# Unsupported target "interface_stats" with type "example" omitted
+
+# Unsupported target "lslocks" with type "example" omitted
+
+# Unsupported target "lsmod" with type "example" omitted
+
+# Unsupported target "mountinfo" with type "example" omitted
+
+# Unsupported target "netstat" with type "example" omitted
+
+# Unsupported target "pressure" with type "example" omitted
+
+# Unsupported target "process_hierarchy" with type "example" omitted
+
+# Unsupported target "ps" with type "example" omitted
+
+# Unsupported target "self_memory" with type "example" omitted
+
+rust_library(
+ name = "procfs",
+ srcs = glob(["**/*.rs"]),
+ crate_features = [
+ ],
+ crate_root = "src/lib.rs",
+ crate_type = "lib",
+ data = [],
+ edition = "2018",
+ rustc_flags = [
+ "--cap-lints=allow",
+ ],
+ tags = [
+ "cargo-raze",
+ "manual",
+ ],
+ version = "0.9.1",
+ # buildifier: leave-alone
+ deps = [
+ "@raze__bitflags__1_3_2//:bitflags",
+ "@raze__byteorder__1_4_3//:byteorder",
+ "@raze__flate2__1_0_22//:flate2",
+ "@raze__hex__0_4_3//:hex",
+ "@raze__lazy_static__1_4_0//:lazy_static",
+ "@raze__libc__0_2_101//:libc",
+ ],
+)
},
crate_features = [
"default",
+ "libc",
+ "process",
+ "procfs",
"protobuf",
],
crate_root = "build.rs",
},
crate_features = [
"default",
+ "libc",
+ "process",
+ "procfs",
"protobuf",
],
crate_root = "src/lib.rs",
"@raze__cfg_if__1_0_0//:cfg_if",
"@raze__fnv__1_0_7//:fnv",
"@raze__lazy_static__1_4_0//:lazy_static",
+ "@raze__libc__0_2_101//:libc",
"@raze__memchr__2_4_1//:memchr",
"@raze__parking_lot__0_11_2//:parking_lot",
"@raze__protobuf__2_25_1//:protobuf",
"@rules_rust//rust/platform:s390x-unknown-linux-gnu",
"@rules_rust//rust/platform:x86_64-unknown-linux-gnu",
): [
+ "@raze__procfs__0_9_1//:procfs",
],
"//conditions:default": [],
}),
config = "0.11"
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
-prometheus = "0.12.0"
+prometheus = { version = "0.12.0", features = ["process"] }
nats = "0.15.2"
testcontainers = "0.12.0"
{
"monitoring": {
- "enabled": false
+ "enabled": true,
+ "address": "0.0.0.0",
+ "port": 5001
},
"nats": {
"host": "localhost"
},
+ "redis": {
+ "url": "redis://localhost"
+ },
"rest": {
"server": {
"port": 8000,
"token": "<your token>"
}
},
- "redis": {
- "url": "redis://localhost"
+ "webhook": {
+ "server": {
+ "port": 8080,
+ "address": "0.0.0.0"
+ },
+ "discord": {
+ "public_key": "",
+ "client_id": 123
+ }
}
}
\ No newline at end of file
use crate::{config::Config, ratelimit::Ratelimiter};
-use common::log::debug;
-use futures_util::future::TryFutureExt;
+use common::{log::debug, prometheus::{Counter, HistogramVec, labels, opts, register_counter, register_histogram_vec}};
use hyper::{
client::HttpConnector, header::HeaderValue, http::uri::Parts, service::Service, Body, Client,
HeaderMap, Request, Response, Uri,
};
use hyper_tls::HttpsConnector;
+use tokio::sync::Mutex;
use std::{future::Future, pin::Pin, sync::Arc, task::Poll};
+lazy_static::lazy_static! {
+ static ref HTTP_COUNTER: Counter = register_counter!(opts!(
+ "nova_rest_http_requests_total",
+ "Number of HTTP requests made.",
+ labels! {"handler" => "all",}
+ ))
+ .unwrap();
+
+ static ref HTTP_REQ_HISTOGRAM: HistogramVec = register_histogram_vec!(
+ "nova_rest_http_request_duration_seconds",
+ "The HTTP request latencies in seconds.",
+ &["handler"]
+ )
+ .unwrap();
+
+ static ref HTTP_COUNTER_STATUS: Counter = register_counter!(opts!(
+ "nova_rest_http_requests_status",
+ "Number of HTTP requests made by status",
+ labels! {"" => ""}
+ ))
+ .unwrap();
+}
+
+
#[derive(Clone)]
pub struct ServiceProxy {
client: Client<HttpsConnector<HttpConnector>>,
ratelimiter: Arc<Ratelimiter>,
config: Arc<Config>,
+ fail: Arc<Mutex<i32>>,
}
-impl ServiceProxy {
- async fn proxy_call() {}
-}
impl Service<Request<Body>> for ServiceProxy {
type Response = Response<Body>;
}
fn call(&mut self, mut req: Request<hyper::Body>) -> Self::Future {
+ HTTP_COUNTER.inc();
+
+ let timer = HTTP_REQ_HISTOGRAM.with_label_values(&["all"]).start_timer();
let host = "discord.com";
let mut new_parts = Parts::default();
*req.headers_mut() = headers;
let client = self.client.clone();
let ratelimiter = self.ratelimiter.clone();
+ let fail = self.fail.clone();
return Box::pin(async move {
- match ratelimiter.before_request(&req).await {
+ let resp = match ratelimiter.before_request(&req).await {
Ok(allowed) => match allowed {
crate::ratelimit::RatelimiterResponse::Ratelimited => {
debug!("ratelimited");
_ => {
debug!("forwarding request");
match client.request(req).await {
- Ok(response) => {
+ Ok(mut response) => {
ratelimiter.after_request(&path, &response).await;
+ if response.status() != 200 {
+ *fail.lock().await += 1
+ }
+ response.headers_mut().insert("x-fails", HeaderValue::from_str(&format!("{}", fail.lock().await)).unwrap());
Ok(response)
}
Err(e) => Err(e),
Err(e) => Ok(Response::builder()
.body(format!("server error: {}", e).into())
.unwrap()),
- }
+ };
+ timer.observe_duration();
+ resp
});
}
}
pub fn new(config: Arc<Config>, ratelimiter: Arc<Ratelimiter>) -> Self {
let https = HttpsConnector::new();
let client = Client::builder().build::<_, hyper::Body>(https);
+ let fail = Arc::new(Mutex::new(0));
ServiceProxy {
client,
config,
ratelimiter,
+ fail
}
}
}
+use common::prometheus::{Counter, HistogramVec, labels, opts, register_counter, register_histogram_vec};
use libsodium_sys::crypto_sign_ed25519_verify_detached;
+lazy_static::lazy_static! {
+ static ref SIGNATURE_TIME_HISTOGRAM: HistogramVec = register_histogram_vec!(
+ "nova_webhook_signature_time",
+ "The time taken by the signature verification",
+ &["signature"]
+ ).unwrap();
+
+ static ref SIGNATURE_BODY_COUNTER: Counter = register_counter!(opts!(
+ "nova_webhook_",
+ "",
+ labels! {"handler" => "webhook_main"}
+ )).unwrap();
+}
+
/// Checks the signature of a given data using the hex signature and the public key.
pub fn validate_signature(hex_public_key: &str, data: &Vec<u8>, hex_signature: &str) -> bool {
+ SIGNATURE_BODY_COUNTER.inc();
+ let timer = SIGNATURE_TIME_HISTOGRAM.with_label_values(&["webhook_main"]).start_timer();
+
// First, we need to check if the signature & private key is valid base64.
let signature_result = hex::decode(hex_signature);
let public_key_result = hex::decode(hex_public_key);
+ let mut result = false;
if signature_result.is_ok() && public_key_result.is_ok() {
// Since we now have the signatures in u8 vectors. We will initialize all the
// parameters for the ffi call to sodium.
// we assume all the parameters are correct for the call
unsafe {
// If the signature is valid, sodium will return 0
- return crypto_sign_ed25519_verify_detached(
+ result = crypto_sign_ed25519_verify_detached(
signature_pointer.as_ptr(),
data_pointer,
data_len,
) == 0;
}
}
- false
+
+ timer.observe_duration();
+ result
}