use std::convert::Infallible;
use std::net::SocketAddr;
use serde::Deserialize;
use warp::{Filter, Reply};
const APPLICATION_SECRET: &str = "<your-application-secret>";
const PROTECTION_PROFILE_ID: &str = "<your-protection-profile-id>";
#[tokio::main]
async fn main() {
let protected = warp::path("protected")
.and(warp::post())
.and(warp::addr::remote())
.and(warp::body::json::<ProtectedRequestPayload>())
.and_then(handler);
warp::serve(protected)
.run(([0, 0, 0, 0], 8000))
.await;
}
#[derive(Deserialize)]
struct ProtectedRequestPayload {
solution: String,
}
async fn handler(
addr: Option<SocketAddr>,
payload: ProtectedRequestPayload,
) -> Result<impl Reply, Infallible> {
let addr = addr.expect("remote address unavailable");
let is_valid = duckity::validate(
payload.solution,
addr.ip(),
APPLICATION_SECRET,
PROTECTION_PROFILE_ID,
)
.await
.unwrap();
if is_valid {
Ok(warp::reply::with_status(
warp::reply::json(&"This is protected!"),
warp::http::StatusCode::OK,
))
} else {
Ok(warp::reply::with_status(
warp::reply::json(&"The provided solution token was invalid."),
warp::http::StatusCode::BAD_REQUEST,
))
}
}