use md5; use serde; use worker::{kv::KvStore, *}; #[event(fetch)] pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result { // Create an instance of the Router, which can use parameters (/user/:name) or wildcard values // (/file/*pathname). Alternatively, use `Router::with_data(D)` and pass in arbitrary data for // routes to access and share using the `ctx.data()` method. let router = Router::new(); #[derive(serde::Serialize, serde::Deserialize)] struct UserInfo { ext: String, passwd: String, comment: String, created_at: String, } async fn check_endpoint_auth(token: &String, kv: KvStore) -> bool { // Check if the token provided by the endpoint is valid. match kv .get("authorized_tokens") .cache_ttl(300) .text() .await .unwrap() { Some(t) => t .split(",") .any(|authorized_token| authorized_token == token), None => false, } } router .get_async("/asterisk/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_asterisk").cache_ttl(300).text().await? { Some(a) => Response::ok(&a), None => Response::error( format!("Could not find asterisk.conf for {}", hostname), 404, ), }; } Response::error("Bad Request", 400) }) .get_async("/asterisk/pjsip/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_asterisk_pjsip").cache_ttl(300).text().await? { Some(base) => { let mut conf = base + ""; // let remote_ip = // match _req.headers().get("CF-Connecting-IP").unwrap_or_default() { // Some(ip) => ip, // None => return Response::error("Could not find remote IP", 500), // }; // conf = conf.replace("##EXTERNAL_IP##", &remote_ip) + "\n"; match kv.get("users").cache_ttl(300).text().await? { Some(users) => { let users = users.split(","); let base_user = match kv.get("base_asterisk_pjsip_user").cache_ttl(300).text().await? { Some(base) => base, None => { return Response::error("Could not find user_base", 500) } }; for u in users { let mut user = base_user.clone(); let info: UserInfo = match kv.get(u).cache_ttl(300).json().await? { Some(info) => info, None => { return Response::error( format!("Could not find user {}", u), 500, ) } }; user = user.replace("##CALL##", u); user = user.replace("##EXT##", &info.ext); user = user.replace( "##MD5_CRED##", &format!( "{:x}", md5::compute(format!("{}:gonk:{}", u, &info.passwd)) ), ); // user = user.replace("##PASSWD##", &info.passwd); conf = conf + &user; } } None => { return Response::error(format!("Could not find gonk users"), 404); } } Response::ok(&conf) } None => { Response::error(format!("Could not find pjsip.conf for {}", hostname), 404) } }; } Response::error("Bad Request", 400) }) .get_async("/asterisk/modules/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_asterisk_modules").cache_ttl(300).text().await? { Some(base) => Response::ok(&base), None => Response::error( format!("Could not find modules.conf for {}", hostname), 404, ), }; } Response::error("Bad Request", 400) }) .get_async("/asterisk/logger/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_asterisk_logger").cache_ttl(300).text().await? { Some(base) => Response::ok(&base), None => { Response::error(format!("Could not find logger.conf for {}", hostname), 404) } }; } Response::error("Bad Request", 400) }) .get_async("/f2b/asterisk/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_f2b_asterisk").cache_ttl(300).text().await? { Some(base) => Response::ok(&base), None => Response::error( format!("Could not find fail2ban asterisk.conf for {}", hostname), 404, ), }; } Response::error("Bad Request", 400) }) .get_async("/f2b/voipbl/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_f2b_voipbl").cache_ttl(300).text().await? { Some(base) => Response::ok(&base), None => Response::error( format!("Could not find fail2ban voipbl.conf for {}", hostname), 404, ), }; } Response::error("Bad Request", 400) }) .get_async( "/asterisk/extensions/:hostname/:token", |_req, ctx| async move { if let Some(token) = ctx.param("token") { if !check_endpoint_auth(token, ctx.kv("GONK_NODES")?).await { return Response::error("Unauthorized", 401); } } if let Some(hostname) = ctx.param("hostname") { let kv = ctx.kv("GONK_NODES")?; return match kv.get("base_asterisk_extensions").cache_ttl(300).text().await? { Some(base) => { let mut conf = base + ""; match kv.get("users").cache_ttl(300).text().await? { Some(users) => { let users = users.split(","); let base_user = match kv.get("base_asterisk_extensions_user").cache_ttl(300).text().await? { Some(base) => base, None => { return Response::error( "Could not find the per user configuration for extensions", 500, ) } }; for u in users { let mut user = base_user.clone(); let info: UserInfo = match kv.get(u).cache_ttl(300).json().await? { Some(info) => info, None => { return Response::error( format!("Could not find user {}", u), 500, ) } }; user = user.replace("##CALL##", u); user = user.replace("##EXT##", &info.ext); conf = conf + &user; } } None => { return Response::error( format!("Could not find gonk users"), 404, ); } } Response::ok(&conf) } None => Response::error( format!("Could not find extensions.conf for {}", hostname), 404, ), }; } Response::error("Bad Request", 400) }, ) .run(req, env) .await }