1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct GatewayTunnel {
8 pub id: Uuid,
9 pub sandbox_id: Option<Uuid>,
10 pub tunnel_type: TunnelType,
11 pub public_url: String,
12 pub local_port: u16,
13 pub state: TunnelState,
14 pub config_json: serde_json::Value,
15 pub error_message: Option<String>,
16 pub created_at: DateTime<Utc>,
17 pub updated_at: DateTime<Utc>,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
21#[serde(rename_all = "snake_case")]
22pub enum TunnelType {
23 Frp,
24 Bore,
25 Cloudflare,
26 Ngrok,
27 Lan,
28 Manual,
29}
30
31impl std::fmt::Display for TunnelType {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 Self::Frp => write!(f, "frp"),
35 Self::Bore => write!(f, "bore"),
36 Self::Cloudflare => write!(f, "cloudflare"),
37 Self::Ngrok => write!(f, "ngrok"),
38 Self::Lan => write!(f, "lan"),
39 Self::Manual => write!(f, "manual"),
40 }
41 }
42}
43
44impl std::str::FromStr for TunnelType {
45 type Err = String;
46 fn from_str(s: &str) -> Result<Self, Self::Err> {
47 match s {
48 "frp" => Ok(Self::Frp),
49 "bore" => Ok(Self::Bore),
50 "cloudflare" => Ok(Self::Cloudflare),
51 "ngrok" => Ok(Self::Ngrok),
52 "lan" => Ok(Self::Lan),
53 "manual" => Ok(Self::Manual),
54 other => Err(format!("unknown tunnel type: {}", other)),
55 }
56 }
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
60#[serde(rename_all = "snake_case")]
61pub enum TunnelState {
62 Active,
63 Stopped,
64 Error,
65}
66
67impl std::fmt::Display for TunnelState {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 match self {
70 Self::Active => write!(f, "active"),
71 Self::Stopped => write!(f, "stopped"),
72 Self::Error => write!(f, "error"),
73 }
74 }
75}
76
77impl std::str::FromStr for TunnelState {
78 type Err = String;
79 fn from_str(s: &str) -> Result<Self, Self::Err> {
80 match s {
81 "active" => Ok(Self::Active),
82 "stopped" => Ok(Self::Stopped),
83 "error" => Ok(Self::Error),
84 other => Err(format!("unknown tunnel state: {}", other)),
85 }
86 }
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct ClientToken {
92 pub id: Uuid,
93 pub name: String,
94 pub token_hash: String,
96 pub scopes: Vec<TokenScope>,
97 pub expires_at: Option<DateTime<Utc>>,
98 pub last_used_at: Option<DateTime<Utc>>,
99 pub created_at: DateTime<Utc>,
100 pub revoked_at: Option<DateTime<Utc>>,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
104#[serde(tag = "type", rename_all = "snake_case")]
105pub enum TokenScope {
106 FullAccess,
107 SandboxAccess { sandbox_id: Uuid },
108 WorkspaceAccess { workspace_id: Uuid },
109 ReadOnly,
110 ChatOnly { sandbox_id: Uuid },
111}
112
113impl TokenScope {
114 pub fn allows_sandbox(&self, sandbox_id: &Uuid) -> bool {
116 match self {
117 Self::FullAccess => true,
118 Self::SandboxAccess { sandbox_id: sid } => sid == sandbox_id,
119 Self::ChatOnly { sandbox_id: sid } => sid == sandbox_id,
120 Self::ReadOnly => true,
121 Self::WorkspaceAccess { .. } => {
122 false
125 }
126 }
127 }
128
129 pub fn allows_write(&self) -> bool {
131 match self {
132 Self::FullAccess => true,
133 Self::SandboxAccess { .. } => true,
134 Self::WorkspaceAccess { .. } => true,
135 Self::ChatOnly { .. } => true,
136 Self::ReadOnly => false,
137 }
138 }
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
143pub struct GatewayStatus {
144 pub enabled: bool,
145 pub active_provider: String,
147 pub lan: LanStatus,
148 pub providers: Vec<TunnelProviderInfo>,
149 pub active_tunnels: usize,
150 pub active_tokens: usize,
151 pub frp: FrpStatus,
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct LanStatus {
157 pub enabled: bool,
158 pub mdns_name: Option<String>,
159 pub local_addresses: Vec<String>,
160 pub advertise_port: u16,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
164pub struct FrpStatus {
165 pub enabled: bool,
166 pub process_running: bool,
167 pub server_addr: Option<String>,
168 pub proxy_count: usize,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct TunnelProviderInfo {
174 pub name: String,
176 pub enabled: bool,
177 pub installed: bool,
178 pub binary_path: Option<String>,
179 pub version: Option<String>,
180 pub process_running: bool,
181 pub tunnel_count: usize,
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize)]
186pub struct ProviderPrepareResult {
187 pub provider: String,
188 pub installed: bool,
189 pub binary_path: String,
190 pub version: Option<String>,
191 pub message: String,
192}