#![allow(deprecated)]
use super::error::ConnectionError;
use super::vpn::{VpnConfig, VpnKind};
use uuid::Uuid;
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct WireGuardConfig {
pub name: String,
pub gateway: String,
pub private_key: String,
pub address: String,
pub peers: Vec<WireGuardPeer>,
pub dns: Option<Vec<String>>,
pub mtu: Option<u32>,
pub uuid: Option<Uuid>,
}
impl WireGuardConfig {
pub fn new(
name: impl Into<String>,
gateway: impl Into<String>,
private_key: impl Into<String>,
address: impl Into<String>,
peers: Vec<WireGuardPeer>,
) -> Self {
Self {
name: name.into(),
gateway: gateway.into(),
private_key: private_key.into(),
address: address.into(),
peers,
dns: None,
mtu: None,
uuid: None,
}
}
#[must_use]
pub fn with_dns(mut self, dns: Vec<String>) -> Self {
self.dns = Some(dns);
self
}
#[must_use]
pub fn with_mtu(mut self, mtu: u32) -> Self {
self.mtu = Some(mtu);
self
}
#[must_use]
pub fn with_uuid(mut self, uuid: Uuid) -> Self {
self.uuid = Some(uuid);
self
}
}
impl super::vpn::sealed::Sealed for WireGuardConfig {}
impl VpnConfig for WireGuardConfig {
fn vpn_kind(&self) -> VpnKind {
VpnKind::WireGuard
}
fn name(&self) -> &str {
&self.name
}
fn dns(&self) -> Option<&[String]> {
self.dns.as_deref()
}
fn mtu(&self) -> Option<u32> {
self.mtu
}
fn uuid(&self) -> Option<Uuid> {
self.uuid
}
}
impl From<WireGuardConfig> for VpnCredentials {
fn from(config: WireGuardConfig) -> Self {
Self {
vpn_type: VpnKind::WireGuard,
name: config.name,
gateway: config.gateway,
private_key: config.private_key,
address: config.address,
peers: config.peers,
dns: config.dns,
mtu: config.mtu,
uuid: config.uuid,
}
}
}
impl From<VpnCredentials> for WireGuardConfig {
fn from(config: VpnCredentials) -> Self {
Self {
name: config.name,
gateway: config.gateway,
private_key: config.private_key,
address: config.address,
peers: config.peers,
dns: config.dns,
mtu: config.mtu,
uuid: config.uuid,
}
}
}
#[deprecated(note = "Use WireGuardConfig instead.")]
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct VpnCredentials {
pub vpn_type: VpnKind,
pub name: String,
pub gateway: String,
pub private_key: String,
pub address: String,
pub peers: Vec<WireGuardPeer>,
pub dns: Option<Vec<String>>,
pub mtu: Option<u32>,
pub uuid: Option<Uuid>,
}
impl VpnCredentials {
pub fn new(
vpn_type: VpnKind,
name: impl Into<String>,
gateway: impl Into<String>,
private_key: impl Into<String>,
address: impl Into<String>,
peers: Vec<WireGuardPeer>,
) -> Self {
Self {
vpn_type,
name: name.into(),
gateway: gateway.into(),
private_key: private_key.into(),
address: address.into(),
peers,
dns: None,
mtu: None,
uuid: None,
}
}
#[must_use]
pub fn builder() -> VpnCredentialsBuilder {
VpnCredentialsBuilder::default()
}
#[must_use]
pub fn with_dns(mut self, dns: Vec<String>) -> Self {
self.dns = Some(dns);
self
}
#[must_use]
pub fn with_mtu(mut self, mtu: u32) -> Self {
self.mtu = Some(mtu);
self
}
#[must_use]
pub fn with_uuid(mut self, uuid: Uuid) -> Self {
self.uuid = Some(uuid);
self
}
}
impl super::vpn::sealed::Sealed for VpnCredentials {}
impl VpnConfig for VpnCredentials {
fn vpn_kind(&self) -> VpnKind {
self.vpn_type
}
fn name(&self) -> &str {
&self.name
}
fn dns(&self) -> Option<&[String]> {
self.dns.as_deref()
}
fn mtu(&self) -> Option<u32> {
self.mtu
}
fn uuid(&self) -> Option<Uuid> {
self.uuid
}
}
#[non_exhaustive]
#[derive(Debug, Default)]
pub struct VpnCredentialsBuilder {
vpn_type: Option<VpnKind>,
name: Option<String>,
gateway: Option<String>,
private_key: Option<String>,
address: Option<String>,
peers: Vec<WireGuardPeer>,
dns: Option<Vec<String>>,
mtu: Option<u32>,
uuid: Option<Uuid>,
}
impl VpnCredentialsBuilder {
#[must_use]
pub fn wireguard(mut self) -> Self {
self.vpn_type = Some(VpnKind::WireGuard);
self
}
#[must_use]
pub fn vpn_kind(mut self, vpn_kind: VpnKind) -> Self {
self.vpn_type = Some(vpn_kind);
self
}
#[must_use]
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
#[must_use]
pub fn gateway(mut self, gateway: impl Into<String>) -> Self {
self.gateway = Some(gateway.into());
self
}
#[must_use]
pub fn private_key(mut self, private_key: impl Into<String>) -> Self {
self.private_key = Some(private_key.into());
self
}
#[must_use]
pub fn address(mut self, address: impl Into<String>) -> Self {
self.address = Some(address.into());
self
}
#[must_use]
pub fn add_peer(mut self, peer: WireGuardPeer) -> Self {
self.peers.push(peer);
self
}
#[must_use]
pub fn peers(mut self, peers: Vec<WireGuardPeer>) -> Self {
self.peers = peers;
self
}
#[must_use]
pub fn with_dns(mut self, dns: Vec<String>) -> Self {
self.dns = Some(dns);
self
}
#[must_use]
pub fn with_mtu(mut self, mtu: u32) -> Self {
self.mtu = Some(mtu);
self
}
#[must_use]
pub fn with_uuid(mut self, uuid: Uuid) -> Self {
self.uuid = Some(uuid);
self
}
#[must_use = "the built credentials must be passed to the VPN connect API"]
pub fn build(self) -> Result<VpnCredentials, ConnectionError> {
let vpn_type = self.vpn_type.ok_or_else(|| {
ConnectionError::IncompleteBuilder("VPN type is required (use .wireguard())".into())
})?;
let name = self.name.ok_or_else(|| {
ConnectionError::IncompleteBuilder("connection name is required (use .name())".into())
})?;
let gateway = self.gateway.ok_or_else(|| {
ConnectionError::IncompleteBuilder("gateway is required (use .gateway())".into())
})?;
let private_key = self.private_key.ok_or_else(|| {
ConnectionError::IncompleteBuilder(
"private key is required (use .private_key())".into(),
)
})?;
let address = self.address.ok_or_else(|| {
ConnectionError::IncompleteBuilder("address is required (use .address())".into())
})?;
if self.peers.is_empty() {
return Err(ConnectionError::InvalidPeers(
"at least one peer is required (use .add_peer())".into(),
));
}
Ok(VpnCredentials {
vpn_type,
name,
gateway,
private_key,
address,
peers: self.peers,
dns: self.dns,
mtu: self.mtu,
uuid: self.uuid,
})
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct WireGuardPeer {
pub public_key: String,
pub gateway: String,
pub allowed_ips: Vec<String>,
pub preshared_key: Option<String>,
pub persistent_keepalive: Option<u32>,
}
impl WireGuardPeer {
pub fn new(
public_key: impl Into<String>,
gateway: impl Into<String>,
allowed_ips: Vec<String>,
) -> Self {
Self {
public_key: public_key.into(),
gateway: gateway.into(),
allowed_ips,
preshared_key: None,
persistent_keepalive: None,
}
}
#[must_use]
pub fn with_preshared_key(mut self, psk: impl Into<String>) -> Self {
self.preshared_key = Some(psk.into());
self
}
#[must_use]
pub fn with_persistent_keepalive(mut self, interval: u32) -> Self {
self.persistent_keepalive = Some(interval);
self
}
}