AP-5/src/lib.rs

273 lines
12 KiB
Rust

use md5;
use serde;
use worker::{kv::KvStore, *};
#[event(fetch)]
pub async fn main(req: Request, env: Env, _ctx: worker::Context) -> Result<Response> {
// 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
}