fix(explorer,explorer-api): mixnode location (#2763)

* chore(explorer-api): remove useless route (/terms)

* feat(explorer-api-geoip): add coordinates lat&lon

* fix(explorer): mixnode location

* fix: typo

* fix: clippy
This commit is contained in:
Pierre Dommerc
2023-01-05 15:53:15 +01:00
committed by GitHub
parent 5b15ed6f15
commit fdbe3a1f6a
11 changed files with 22 additions and 43 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ GEOIPUPDATE_LICENSE_KEY=xxx
# List of space-separated database edition IDs. Edition IDs may
# consist of letters, digits, and dashes. For example, GeoIP2-City
# would download the GeoIP2 City database (GeoIP2-City).
GEOIPUPDATE_EDITION_IDS=GeoLite2-Country
GEOIPUPDATE_EDITION_IDS=GeoLite2-City
# The number of hours between geoipupdate runs. If this is not set
# or is set to 0, geoipupdate will run once and exit.
GEOIPUPDATE_FREQUENCY=72
+1 -1
View File
@@ -1,2 +1,2 @@
# The path to the geoip database file
GEOIP_DB_PATH=./geo_ip/GeoLite2-Country.mmdb
GEOIP_DB_PATH=./geo_ip/GeoLite2-City.mmdb
+1 -1
View File
@@ -40,7 +40,7 @@ It should be previously installed thanks to `geoipupdate` service.
For example:
```shell
GEOIP_DB_PATH=./geo_ip/GeoLite2-Country.mmdb cargo run
GEOIP_DB_PATH=./geo_ip/GeoLite2-City.mmdb cargo run
```
Note: explorer-api binary reads the provided `.env` file.
-26
View File
@@ -1,26 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::geo_ip::location::Location;
use crate::state::ExplorerApiStateContext;
use rocket::response::status;
use rocket::serde::json::Json;
use rocket::{Route, State};
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
pub fn nym_terms_make_default_routes(settings: &OpenApiSettings) -> (Vec<Route>, OpenApi) {
openapi_get_routes_spec![settings: terms]
}
#[openapi(tag = "terms")]
#[get("/")]
pub(crate) async fn terms(
_state: &State<ExplorerApiStateContext>,
location: Location,
) -> Result<Json<String>, status::Forbidden<String>> {
if location.iso_alpha2 == "US" {
return Err(status::Forbidden(Some("US government sucks".to_string())));
}
Ok(Json("Nym Terms & Conditions: Welcome".to_string()))
}
-1
View File
@@ -1 +0,0 @@
pub(crate) mod http;
+11 -6
View File
@@ -3,14 +3,14 @@
use isocountry::CountryCode;
use log::warn;
use maxminddb::{geoip2::Country, MaxMindDBError, Reader};
use maxminddb::{geoip2::City, MaxMindDBError, Reader};
use std::{
net::{IpAddr, ToSocketAddrs},
str::FromStr,
sync::Arc,
};
const DEFAULT_DATABASE_PATH: &str = "./geo_ip/GeoLite2-Country.mmdb";
const DEFAULT_DATABASE_PATH: &str = "./geo_ip/GeoLite2-City.mmdb";
const FAKE_PORT: u16 = 1234;
#[derive(Debug)]
@@ -38,6 +38,8 @@ pub(crate) struct Location {
pub(crate) iso_alpha3: String,
/// English country short name (ISO 3166-1)
pub(crate) name: String,
pub(crate) latitude: Option<f64>,
pub(crate) longitude: Option<f64>,
}
impl GeoIp {
@@ -86,7 +88,7 @@ impl GeoIp {
error!("No registered GeoIP database");
GeoIpError::InternalError
})?
.lookup::<Country>(ip);
.lookup::<City>(ip);
match &result {
Ok(v) => Ok(Some(
Location::try_from(v).map_err(|_| GeoIpError::InternalError)?,
@@ -99,11 +101,11 @@ impl GeoIp {
}
}
impl<'a> TryFrom<&Country<'a>> for Location {
impl<'a> TryFrom<&City<'a>> for Location {
type Error = String;
fn try_from(country: &Country) -> Result<Self, Self::Error> {
let data = country.country.as_ref().ok_or_else(|| {
fn try_from(city: &City) -> Result<Self, Self::Error> {
let data = city.country.as_ref().ok_or_else(|| {
warn!("No Country data found");
"No Country data found"
})?;
@@ -119,10 +121,13 @@ impl<'a> TryFrom<&Country<'a>> for Location {
warn!("{}", &message);
message
})?;
Ok(Location {
iso_alpha2,
iso_alpha3: String::from(iso_codes.alpha3()),
name: String::from(iso_codes.name()),
latitude: city.location.as_ref().and_then(|l| l.latitude),
longitude: city.location.as_ref().and_then(|l| l.longitude),
})
}
}
-2
View File
@@ -5,7 +5,6 @@ use rocket::{Build, Request, Rocket};
use rocket_cors::{AllowedHeaders, AllowedOrigins};
use rocket_okapi::swagger_ui::make_swagger_ui;
use crate::buy_terms::http::nym_terms_make_default_routes;
use crate::country_statistics::http::country_statistics_make_default_routes;
use crate::gateways::http::gateways_make_default_routes;
use crate::http::swagger::get_docs;
@@ -57,7 +56,6 @@ fn configure_rocket(state: ExplorerApiStateContext) -> Rocket<Build> {
"/overview" => overview_make_default_routes(&openapi_settings),
"/ping" => ping_make_default_routes(&openapi_settings),
"/validators" => validators_make_default_routes(&openapi_settings),
"/terms" => nym_terms_make_default_routes(&openapi_settings),
};
building_rocket
-1
View File
@@ -10,7 +10,6 @@ use logging::setup_logging;
use network_defaults::setup_env;
use task::TaskManager;
mod buy_terms;
pub(crate) mod cache;
mod client;
pub(crate) mod commands;
+4
View File
@@ -36,6 +36,8 @@ pub(crate) struct Location {
pub(crate) two_letter_iso_country_code: String,
pub(crate) three_letter_iso_country_code: String,
pub(crate) country_name: String,
pub(crate) latitude: Option<f64>,
pub(crate) longitude: Option<f64>,
}
impl Location {
@@ -44,6 +46,8 @@ impl Location {
country_name: location.name,
two_letter_iso_country_code: location.iso_alpha2,
three_letter_iso_country_code: location.iso_alpha3,
latitude: location.latitude,
longitude: location.longitude,
}
}
}
+2 -2
View File
@@ -164,10 +164,10 @@ const PageMixnodeDetailWithState: React.FC = () => {
{mixNode && (
<ContentCard title="Location">
{mixNode?.error && <ComponentError text="There was a problem retrieving this mixnode location" />}
{mixNode.data && mixNode?.data?.location && (
{mixNode?.data?.location?.latitude && mixNode?.data?.location?.longitude && (
<WorldMap
loading={mixNode.isLoading}
userLocation={[mixNode?.data?.location?.lng, mixNode?.data?.location?.lat]}
userLocation={[mixNode.data.location.longitude, mixNode.data.location.latitude]}
/>
)}
</ContentCard>
+2 -2
View File
@@ -77,8 +77,8 @@ export interface MixNodeResponseItem {
status: MixnodeStatus;
location: {
country_name: string;
lat: number;
lng: number;
latitude?: number;
longitude?: number;
three_letter_iso_country_code: string;
two_letter_iso_country_code: string;
};