Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: api gateway and session token for securing cluster #292

Merged
merged 13 commits into from
May 28, 2024
1,631 changes: 1,433 additions & 198 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ members = [
"packages/media_core",
"packages/media_runner",
"packages/transport_webrtc",
"packages/media_secure",
"packages/media_gateway",
]

[workspace.dependencies]
sans-io-runtime = { git = "https://github.com/giangndm/sans-io-runtime.git", rev = "e7ef60e0eef35c532c8544c472514ae831a8908f" }
atm0s-sdn = { git = "https://github.com/giangndm/8xFF-decentralized-sdn.git", rev = "9200a1615def0ddffce8338b34afd24421f24269" }
sans-io-runtime = { git = "https://github.com/giangndm/sans-io-runtime.git", rev = "c781cef12b2a435b5e31a6ede69d301a23719452" }
atm0s-sdn = { git = "https://github.com/giangndm/8xFF-decentralized-sdn.git", rev = "e3456db45912bdd461755088a5dde5e004b0f17a" }
tracing-subscriber = { version = "0.3", features = ["env-filter", "std"] }
convert-enum = "0.1"
num_enum = "0.7"
Expand Down
22 changes: 20 additions & 2 deletions bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ poem-openapi = { version = "5.0", features = ["swagger-ui"] }
tokio = { version = "1.37", features = ["full"] }
sans-io-runtime = { workspace = true }
atm0s-sdn = { workspace = true }
media-server-protocol = { path = "../packages/protocol" }
media-server-runner = { path = "../packages/media_runner" }
media-server-protocol = { path = "../packages/protocol", features = ["quinn-rpc"] }
media-server-secure = { path = "../packages/media_secure" }
media-server-runner = { path = "../packages/media_runner", optional = true }
media-server-gateway = { path = "../packages/media_gateway", optional = true }
local-ip-address = "0.6"
serde = { version = "1.0", features = ["derive"] }
quinn = { version = "0.11", optional = true }
rustls = { version = "0.23", optional = true }
convert-enum = { workspace = true }
num_enum = { workspace = true }
derive_more = { workspace = true }
rcgen = { version = "0.13", optional = true }
maxminddb = "0.24.0"

[features]
default = ["gateway", "media", "connector", "cert_utils"]
gateway = ["media-server-gateway", "quinn_vnet"]
media = ["media-server-runner", "quinn_vnet"]
connector = ["quinn_vnet"]
cert_utils = ["rcgen", "rustls"]
quinn_vnet = ["rustls", "quinn"]
Binary file added bin/certs/cluster.cert
Binary file not shown.
Binary file added bin/certs/cluster.key
Binary file not shown.
11 changes: 11 additions & 0 deletions bin/gate_z0_n1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUST_LOG=atm0s_sdn_network::features::socket=debug,info \
RUST_BACKTRACE=1 \
cargo run -- \
--http-port 3000 \
--node-id 0 \
--sdn-port 10000 \
--sdn-zone 0 \
gateway \
--lat 10 \
--lon 20 \
--geo-db "../maxminddb-data/GeoLite2-City.mmdb"
12 changes: 12 additions & 0 deletions bin/gate_z256_n1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
RUST_LOG=atm0s_sdn_network::features::socket=debug,info \
RUST_BACKTRACE=1 \
cargo run -- \
--http-port 4000 \
--node-id 256 \
--sdn-zone 256 \
--sdn-port 11000 \
--seeds 0@/ip4/127.0.0.1/udp/10000 \
gateway \
--lat 20 \
--lon 30 \
--geo-db "../maxminddb-data/GeoLite2-City.mmdb"
11 changes: 11 additions & 0 deletions bin/media_z0_n1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUST_LOG=atm0s_sdn_network::features::socket=debug,info \
RUST_BACKTRACE=1 \
cargo run -- \
--http-port 3001 \
--node-id 1 \
--sdn-port 10001 \
--sdn-zone 0 \
--seeds 0@/ip4/127.0.0.1/udp/10000 \
media \
--allow-private-ip \
--enable-token-api
11 changes: 11 additions & 0 deletions bin/media_z0_n2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUST_LOG=info \
RUST_BACKTRACE=1 \
cargo run -- \
--http-port 3002 \
--node-id 2 \
--sdn-port 10002 \
--sdn-zone 0 \
--seeds 0@/ip4/127.0.0.1/udp/10000 \
media \
--allow-private-ip \
--enable-token-api
11 changes: 11 additions & 0 deletions bin/media_z256_n1.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUST_LOG=atm0s_sdn_network::features::socket=debug,info \
RUST_BACKTRACE=1 \
cargo run -- \
--http-port 4001 \
--node-id 257 \
--sdn-port 11001 \
--sdn-zone 256 \
--seeds 256@/ip4/127.0.0.1/udp/11000 \
media \
--allow-private-ip \
--enable-token-api
11 changes: 11 additions & 0 deletions bin/media_z256_n2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RUST_LOG=info \
RUST_BACKTRACE=1 \
cargo run -- \
--http-port 4002 \
--node-id 258 \
--sdn-port 11002 \
--sdn-zone 256 \
--seeds 256@/ip4/127.0.0.1/udp/11000 \
media \
--allow-private-ip \
--enable-token-api
1 change: 0 additions & 1 deletion bin/node1.sh

This file was deleted.

1 change: 0 additions & 1 deletion bin/node2.sh

This file was deleted.

6 changes: 6 additions & 0 deletions bin/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[derive(num_enum::TryFromPrimitive, num_enum::IntoPrimitive, derive_more::Display)]

Check warning on line 1 in bin/src/errors.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/errors.rs#L1

Added line #L1 was not covered by tests
#[repr(u32)]
pub enum MediaServerError {
GatewayRpcError = 0x00020001,
InvalidConnId = 0x00020002,
}
77 changes: 53 additions & 24 deletions bin/src/http.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
use std::net::SocketAddr;
use std::sync::Arc;

use media_server_protocol::endpoint::ClusterConnId;
use media_server_protocol::transport::{RpcReq, RpcRes};
use media_server_secure::{MediaEdgeSecure, MediaGatewaySecure};
use poem::endpoint::StaticFilesEndpoint;
use poem::{listener::TcpListener, middleware::Cors, EndpointExt, Route, Server};
use poem_openapi::types::{ToJSON, Type};
use poem_openapi::OpenApiService;
use poem_openapi::{types::ParseFromJSON, Object};
use tokio::sync::mpsc::Sender;

mod api_connector;
mod api_media;
mod api_token;
mod utils;

#[derive(Debug, Default, Object)]
pub struct Response<T: ParseFromJSON + ToJSON + Type + Send + Sync> {
pub status: bool,
Expand All @@ -34,36 +41,58 @@
}
}

mod api_connector;
mod api_media;
mod utils;

pub async fn run_gateway_http_server(sender: Sender<Rpc<RpcReq<ClusterConnId>, RpcRes<ClusterConnId>>>) -> Result<(), Box<dyn std::error::Error>> {
let api_service: OpenApiService<_, ()> = OpenApiService::new(api_media::MediaApis, "Media Gateway APIs", env!("CARGO_PKG_VERSION")).server("/");
let ui = api_service.swagger_ui();
let spec = api_service.spec();
pub async fn run_gateway_http_server<ES: 'static + MediaEdgeSecure + Send + Sync, GS: 'static + MediaGatewaySecure + Send + Sync>(
port: u16,
sender: Sender<Rpc<RpcReq<ClusterConnId>, RpcRes<ClusterConnId>>>,
edge_secure: Arc<ES>,
gateway_secure: Arc<GS>,
) -> Result<(), Box<dyn std::error::Error>> {
let token_service: OpenApiService<_, ()> = OpenApiService::new(api_token::TokenApis::<GS>::new(), "App APIs", env!("CARGO_PKG_VERSION")).server("/token/");
let token_ui = token_service.swagger_ui();
let token_spec = token_service.spec();
let media_service: OpenApiService<_, ()> = OpenApiService::new(api_media::MediaApis::<ES>::new(), "Media Gateway APIs", env!("CARGO_PKG_VERSION")).server("/media/");
let media_ui = media_service.swagger_ui();
let media_spec = media_service.spec();

Check warning on line 55 in bin/src/http.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/http.rs#L44-L55

Added lines #L44 - L55 were not covered by tests
let route = Route::new()
.nest("/", api_service)
.nest("/ui", ui)
.at("/spec", poem::endpoint::make_sync(move |_| spec.clone()))
.with(Cors::new())
.data(api_media::MediaServerCtx { sender });
.nest("/samples", StaticFilesEndpoint::new("./public").index_file("index.html"))
.nest("/token/", token_service.data(api_token::TokenServerCtx { secure: gateway_secure }))
.nest("/token/ui", token_ui)
.at("/token/spec", poem::endpoint::make_sync(move |_| token_spec.clone()))
.nest("/", media_service.data(api_media::MediaServerCtx { sender, secure: edge_secure }))
.nest("/ui", media_ui)
.at("/spec", poem::endpoint::make_sync(move |_| media_spec.clone()))
.with(Cors::new());

Check warning on line 64 in bin/src/http.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/http.rs#L57-L64

Added lines #L57 - L64 were not covered by tests

Server::new(TcpListener::bind("0.0.0.0:3000")).run(route).await?;
Server::new(TcpListener::bind(SocketAddr::new([0, 0, 0, 0].into(), port))).run(route).await?;

Check warning on line 66 in bin/src/http.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/http.rs#L66

Added line #L66 was not covered by tests
Ok(())
}

pub async fn run_media_http_server(port: u16, sender: Sender<Rpc<RpcReq<ClusterConnId>, RpcRes<ClusterConnId>>>) -> Result<(), Box<dyn std::error::Error>> {
let api_service: OpenApiService<_, ()> = OpenApiService::new(api_media::MediaApis, "Media Server APIs", env!("CARGO_PKG_VERSION")).server("/");
let ui = api_service.swagger_ui();
let spec = api_service.spec();
let route = Route::new()
.nest("/", api_service)
pub async fn run_media_http_server<ES: 'static + MediaEdgeSecure + Send + Sync, GS: 'static + MediaGatewaySecure + Send + Sync>(
port: u16,
sender: Sender<Rpc<RpcReq<ClusterConnId>, RpcRes<ClusterConnId>>>,
edge_secure: Arc<ES>,
gateway_secure: Option<Arc<GS>>,
) -> Result<(), Box<dyn std::error::Error>> {
let mut route = Route::new();

Check warning on line 76 in bin/src/http.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/http.rs#L70-L76

Added lines #L70 - L76 were not covered by tests

if let Some(gateway_secure) = gateway_secure {
let token_service: OpenApiService<_, ()> = OpenApiService::new(api_token::TokenApis::<GS>::new(), "App APIs", env!("CARGO_PKG_VERSION")).server("/token/");
let token_ui = token_service.swagger_ui();
let token_spec = token_service.spec();
route = route
.nest("/token/", token_service.data(api_token::TokenServerCtx { secure: gateway_secure }))
.nest("/token/ui", token_ui)
.at("/token/spec", poem::endpoint::make_sync(move |_| token_spec.clone()));
}
let media_service: OpenApiService<_, ()> = OpenApiService::new(api_media::MediaApis::<ES>::new(), "Media Gateway APIs", env!("CARGO_PKG_VERSION")).server("/media/");
let media_ui = media_service.swagger_ui();
let media_spec = media_service.spec();
let route = route

Check warning on line 90 in bin/src/http.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/http.rs#L78-L90

Added lines #L78 - L90 were not covered by tests
.nest("/samples", StaticFilesEndpoint::new("./public").index_file("index.html"))
.nest("/ui", ui)
.at("/spec", poem::endpoint::make_sync(move |_| spec.clone()))
.with(Cors::new())
.data(api_media::MediaServerCtx { sender });
.nest("/", media_service.data(api_media::MediaServerCtx { sender, secure: edge_secure }))
.nest("/ui", media_ui)
.at("/spec", poem::endpoint::make_sync(move |_| media_spec.clone()))
.with(Cors::new());

Check warning on line 95 in bin/src/http.rs

View check run for this annotation

Codecov / codecov/patch

bin/src/http.rs#L92-L95

Added lines #L92 - L95 were not covered by tests

Server::new(TcpListener::bind(SocketAddr::new([0, 0, 0, 0].into(), port))).run(route).await?;
Ok(())
Expand Down
Loading
Loading