51 lines
1.5 KiB
Rust
51 lines
1.5 KiB
Rust
use axum::http::StatusCode;
|
|
use axum::response::IntoResponse;
|
|
use serde_json::json;
|
|
|
|
use crate::auth::PocketBaseUser;
|
|
use crate::consts::FREE_ZONE_BOUNDS;
|
|
|
|
/// Check whether the user is allowed to query data at the given bounds.
|
|
/// Licensed users and admins bypass the check entirely.
|
|
/// Free/anonymous users get 403 if bounds exceed the free zone.
|
|
#[allow(clippy::result_large_err)]
|
|
pub fn check_license_bounds(
|
|
user: &Option<PocketBaseUser>,
|
|
bounds: (f64, f64, f64, f64),
|
|
) -> Result<(), axum::response::Response> {
|
|
if let Some(u) = user {
|
|
if u.is_admin || u.subscription == "licensed" {
|
|
return Ok(());
|
|
}
|
|
}
|
|
|
|
let (south, west, north, east) = bounds;
|
|
let (fz_south, fz_west, fz_north, fz_east) = FREE_ZONE_BOUNDS;
|
|
|
|
if south >= fz_south && west >= fz_west && north <= fz_north && east <= fz_east {
|
|
return Ok(());
|
|
}
|
|
|
|
let body = json!({
|
|
"error": "license_required",
|
|
"message": "A license is required to view data outside the demo area",
|
|
"free_zone": {
|
|
"south": fz_south,
|
|
"west": fz_west,
|
|
"north": fz_north,
|
|
"east": fz_east,
|
|
}
|
|
});
|
|
|
|
Err((StatusCode::FORBIDDEN, axum::Json(body)).into_response())
|
|
}
|
|
|
|
/// Convenience wrapper that takes a point (lat, lon) instead of bounds.
|
|
#[allow(clippy::result_large_err)]
|
|
pub fn check_license_point(
|
|
user: &Option<PocketBaseUser>,
|
|
lat: f64,
|
|
lon: f64,
|
|
) -> Result<(), axum::response::Response> {
|
|
check_license_bounds(user, (lat, lon, lat, lon))
|
|
}
|