Skip to content

Commit c9c29c3

Browse files
committed
runtimes/core: support running multiple gateways
1 parent f4448a1 commit c9c29c3

File tree

10 files changed

+416
-258
lines changed

10 files changed

+416
-258
lines changed

runtimes/core/src/api/call.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ impl ServiceRegistry {
9696
})
9797
}
9898

99+
pub fn service_names(&self) -> Vec<&EncoreName> {
100+
self.base_urls.keys().collect()
101+
}
102+
99103
pub fn service_base_url<Q>(&self, service_name: &Q) -> Option<&String>
100104
where
101105
EncoreName: Borrow<Q>,

runtimes/core/src/api/cors/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,16 @@ pub struct MetaHeaders {
197197
}
198198

199199
impl MetaHeaders {
200-
pub fn from_schema(endpoints: &EndpointMap, auth: Option<&auth::Authenticator>) -> Self {
200+
pub fn from_schema(
201+
gateway_name: &str,
202+
endpoints: &EndpointMap,
203+
auth: Option<&auth::Authenticator>,
204+
) -> Self {
201205
let mut allow_headers = HashSet::new();
202206
let mut expose_headers = HashSet::new();
203207

204208
for ep in endpoints.values() {
205-
if !ep.exposed {
209+
if !ep.exposed.contains(gateway_name) {
206210
continue;
207211
}
208212
for h in ep.request.iter().flat_map(|req| req.header.iter()) {

runtimes/core/src/api/endpoint.rs

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::collections::{HashMap, HashSet};
22
use std::future::Future;
33
use std::pin::Pin;
44
use std::sync::{Arc, Mutex};
@@ -24,11 +24,12 @@ use crate::encore::parser::meta::v1::{self as meta, selector};
2424
use crate::log::LogFromRust;
2525
use crate::model::StreamDirection;
2626
use crate::names::EndpointName;
27-
use crate::trace;
2827
use crate::{model, Hosted};
28+
use crate::{trace, EncoreName};
2929

3030
use super::pvalue::{PValue, PValues};
3131
use super::reqauth::caller::Caller;
32+
use super::reqauth::platform::ValidationData;
3233

3334
#[derive(Debug)]
3435
pub struct SuccessResponse {
@@ -162,8 +163,8 @@ pub struct Endpoint {
162163
/// Whether this is a raw endpoint.
163164
pub raw: bool,
164165

165-
/// Whether the service is exposed publicly.
166-
pub exposed: bool,
166+
/// Which gateways this endpoint is exposed through.
167+
pub exposed: HashSet<EncoreName>,
167168

168169
/// Whether the service requires authentication data.
169170
pub requires_auth: bool,
@@ -331,8 +332,8 @@ pub fn endpoints_from_meta(
331332
}
332333
let resp_schema = ep.response_schema.build(&registry)?;
333334

334-
// We only support a single gateway right now.
335-
let exposed = ep.ep.expose.contains_key("api-gateway");
335+
let exposed = ep.ep.expose.keys().map(|gw_name| gw_name.into()).collect();
336+
336337
let raw =
337338
rpc::Protocol::try_from(ep.ep.proto).is_ok_and(|proto| proto == rpc::Protocol::Raw);
338339

@@ -444,11 +445,7 @@ impl EndpointHandler {
444445
.into_parts();
445446

446447
// Authenticate the request from the platform, if applicable.
447-
#[allow(clippy::manual_unwrap_or_default)]
448-
let platform_seal_of_approval = match self.authenticate_platform(&parts) {
449-
Ok(seal) => seal,
450-
Err(_err) => None,
451-
};
448+
let platform_seal_of_approval = self.authenticate_platform(&parts).ok();
452449

453450
let meta = CallMeta::parse_with_caller(
454451
&self.shared.inbound_svc_auth,
@@ -546,8 +543,13 @@ impl EndpointHandler {
546543

547544
let internal_caller = request.internal_caller.clone();
548545

546+
// check if this endpoint is exposed by the calling gateway
547+
let exposed = internal_caller.as_ref().is_some_and(|caller| {
548+
matches!(caller, Caller::Gateway { gateway } if self.endpoint.exposed.contains(gateway))
549+
});
550+
549551
// If the endpoint isn't exposed, return a 404.
550-
if !self.endpoint.exposed && !request.allows_private_endpoint_call() {
552+
if !exposed && !request.allows_private_endpoint_call() {
551553
return Error {
552554
code: ErrCode::NotFound,
553555
message: "endpoint not found".into(),
@@ -662,32 +664,9 @@ impl EndpointHandler {
662664
fn authenticate_platform(
663665
&self,
664666
req: &axum::http::request::Parts,
665-
) -> Result<Option<platform::SealOfApproval>, platform::ValidationError> {
666-
let Some(x_encore_auth_header) = req.headers.get("x-encore-auth") else {
667-
return Ok(None);
668-
};
669-
let x_encore_auth_header = x_encore_auth_header
670-
.to_str()
671-
.map_err(|_| platform::ValidationError::InvalidMac)?;
672-
673-
let Some(date_header) = req.headers.get("Date") else {
674-
return Err(platform::ValidationError::InvalidDateHeader);
675-
};
676-
let date_header = date_header
677-
.to_str()
678-
.map_err(|_| platform::ValidationError::InvalidDateHeader)?;
679-
680-
let request_path = req.uri.path();
681-
let req = platform::ValidationData {
682-
request_path,
683-
date_header,
684-
x_encore_auth_header,
685-
};
686-
687-
self.shared
688-
.platform_auth
689-
.validate_platform_request(&req)
690-
.map(Some)
667+
) -> Result<platform::SealOfApproval, platform::ValidationError> {
668+
let data = ValidationData::from_req(req)?;
669+
self.shared.platform_auth.validate_platform_request(&data)
691670
}
692671
}
693672

0 commit comments

Comments
 (0)