diff --git a/src/api.rs b/src/api.rs index 4feb786..3f3db77 100644 --- a/src/api.rs +++ b/src/api.rs @@ -9,14 +9,20 @@ use crate::keys::Key; const BASE_URL: &str = "https://api.azirevpn.com"; #[derive(Serialize, Deserialize, Debug)] -pub(crate) struct CheckResult { +pub(crate) struct CheckResponse { + pub status: String, + pub data: CheckData, +} + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct CheckData { pub connected: bool, pub ip: String, // XXX pub location: Option, } #[derive(Serialize, Deserialize, Debug)] -pub(crate) struct Locations { +pub(crate) struct LocationsResponse { pub status: String, pub locations: Vec, } @@ -41,46 +47,47 @@ impl Location { } #[derive(Serialize, Deserialize, Debug)] -pub(crate) struct Addresses { +pub(crate) struct AddressResponse { pub status: String, - pub ipv4: WireguardConfigIpv4, - pub ipv6: WireguardConfigIpv6, + pub data: AddressData, +} + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct AddressData { + pub ipv4_address: Ipv4Addr, + pub ipv4_netmask: u8, + pub ipv6_address: Ipv6Addr, + pub ipv6_netmask: u8, pub dns: Vec, } - #[derive(Serialize, Deserialize, Debug)] -pub(crate) struct WireguardConfigIpv4 { - pub address: Ipv4Addr, - pub netmask: u8, -} -#[derive(Serialize, Deserialize, Debug)] -pub(crate) struct WireguardConfigIpv6 { - pub address: Ipv6Addr, - pub netmask: u8, +pub(crate) struct AddIpRequest<'a> { + pub key: &'a str, } -pub(crate) fn check() -> anyhow::Result { - let url = format!("{}/v1/check", BASE_URL); - let response: CheckResult = ureq::get(&url).call()?.into_json()?; +pub(crate) fn check() -> anyhow::Result { + let url = format!("{}/v3/check", BASE_URL); + let response: CheckResponse = ureq::get(&url).call()?.into_json()?; debug!("response = {:?}", &response); - Ok(response) + Ok(response.data) } -pub(crate) fn get_locations() -> anyhow::Result { - let url = format!("{}/v2/locations", BASE_URL); - let response: Locations = ureq::get(&url).call()?.into_json()?; +pub(crate) fn get_locations() -> anyhow::Result> { + let url = format!("{}/v3/locations", BASE_URL); + let response: LocationsResponse = ureq::get(&url).call()?.into_json()?; debug!("response = {:?}", &response); - Ok(response) + Ok(response.locations) } -pub(crate) fn add_ip(username: &str, token: &str, public_key: &Key) -> anyhow::Result { - let url = format!("{}/v2/ip/add", BASE_URL); - let response: Addresses = ureq::post(&url) - .send_form(&[ - ("username", username), - ("token", token), - ("key", &public_key.to_base64()), - ])? +pub(crate) fn add_ip(token: &str, public_key: &Key) -> anyhow::Result { + let url = format!("{}/v3/ips", BASE_URL); + let authorization = format!("Bearer {token}"); + let request = AddIpRequest { + key: &public_key.to_base64(), + }; + let response: AddressResponse = ureq::post(&url) + .set("Authorization", &authorization) + .send_json(&request)? .into_json()?; debug!("response = {:?}", &response); - Ok(response) + Ok(response.data) } diff --git a/src/config.rs b/src/config.rs index 4689adf..50ee469 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,10 +43,6 @@ impl MachineConfig { Ok(()) } - pub(crate) fn username(&self) -> anyhow::Result { - Ok(std::fs::read_to_string(self.username_path())?) - } - pub(crate) fn token(&self) -> anyhow::Result { Ok(std::fs::read_to_string(self.token_path())?) } @@ -60,11 +56,6 @@ impl MachineConfig { Key::try_from_base64(key_data.trim_end()) } - pub(crate) fn save_username(&self, username: &str) -> anyhow::Result<()> { - std::fs::write(self.username_path(), username)?; - Ok(()) - } - pub(crate) fn save_token(&self, token: &str) -> anyhow::Result<()> { std::fs::write(self.token_path(), token)?; Ok(()) @@ -80,10 +71,6 @@ impl MachineConfig { &self.path } - fn username_path(&self) -> PathBuf { - self.path().join("username") - } - fn token_path(&self) -> PathBuf { self.path().join("token") } diff --git a/src/main.rs b/src/main.rs index 20b39da..4aa9e1d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,6 @@ struct Opts { #[derive(Parser, Debug)] struct LoginOpts { - username: String, token: String, } @@ -79,7 +78,6 @@ fn main() -> Result<(), anyhow::Error> { fn login(opts: &Opts, login_opts: &LoginOpts) -> Result<(), anyhow::Error> { let machine_config = config::MachineConfig::new(opts.machine.as_ref())?; - machine_config.save_username(&login_opts.username)?; machine_config.save_token(&login_opts.token)?; Ok(()) } @@ -109,7 +107,7 @@ fn list_locations(opts: &Opts) -> Result<(), anyhow::Error> { if opts.json { println!("{}", serde_json::to_string(&locations)?); } else { - for (i, location) in locations.locations.iter().enumerate() { + for (i, location) in locations.iter().enumerate() { if i > 0 { println!() }; @@ -128,16 +126,14 @@ fn get_config(opts: &Opts, config_opts: &ConfigOpts) -> Result<(), anyhow::Error let machine_config = MachineConfig::new(opts.machine.as_ref())?; let locations = api::get_locations()?; let location = locations - .locations .iter() .find(|location| location.name == config_opts.location) .ok_or_else(|| anyhow::anyhow!("no such location: {}", config_opts.location))?; debug!("location = {:?}", &location); let keys = get_keys(&machine_config)?; debug!("keys = {:?}", &keys); - let username = machine_config.username()?; let token = machine_config.token()?; - let addresses = api::add_ip(&username, &token, &keys.public_key)?; + let addresses = api::add_ip(&token, &keys.public_key)?; write_config( &mut std::io::stdout().lock(), @@ -152,17 +148,17 @@ fn write_config( output: &mut dyn Write, config_opts: &ConfigOpts, location: &api::Location, - config: &api::Addresses, + config: &api::AddressData, keys: &WireguardKeyPair, ) -> Result<(), anyhow::Error> { writeln!(output, "[Interface]")?; writeln!(output, "PrivateKey = {}", &keys.private_key.to_base64())?; let allowed_addresses = if config_opts.no_ipv6 { - vec![IpAddr::V4(config.ipv4.address)] + vec![IpAddr::V4(config.ipv4_address)] } else { vec![ - IpAddr::V4(config.ipv4.address), - IpAddr::V6(config.ipv6.address), + IpAddr::V4(config.ipv4_address), + IpAddr::V6(config.ipv6_address), ] }; write_list(output, "Address = ", allowed_addresses)?;