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