174 lines
6.7 KiB
Diff
174 lines
6.7 KiB
Diff
|
diff --git a/syncserver-settings/src/lib.rs b/syncserver-settings/src/lib.rs
|
||
|
index 6732ffc..1c9ef83 100644
|
||
|
--- a/syncserver-settings/src/lib.rs
|
||
|
+++ b/syncserver-settings/src/lib.rs
|
||
|
@@ -18,6 +18,7 @@ static PREFIX: &str = "sync";
|
||
|
pub struct Settings {
|
||
|
pub port: u16,
|
||
|
pub host: String,
|
||
|
+ pub public_url: Option<String>,
|
||
|
/// Keep-alive header value (seconds)
|
||
|
pub actix_keep_alive: Option<u32>,
|
||
|
/// The master secret, from which are derived
|
||
|
@@ -182,6 +183,7 @@ impl Default for Settings {
|
||
|
Settings {
|
||
|
port: 8000,
|
||
|
host: "127.0.0.1".to_string(),
|
||
|
+ public_url: None,
|
||
|
actix_keep_alive: None,
|
||
|
master_secret: Secrets::default(),
|
||
|
statsd_host: Some("localhost".to_owned()),
|
||
|
diff --git a/syncserver/src/server/mod.rs b/syncserver/src/server/mod.rs
|
||
|
index f1e0a18..d686693 100644
|
||
|
--- a/syncserver/src/server/mod.rs
|
||
|
+++ b/syncserver/src/server/mod.rs
|
||
|
@@ -80,7 +80,7 @@ pub struct Server;
|
||
|
|
||
|
#[macro_export]
|
||
|
macro_rules! build_app {
|
||
|
- ($syncstorage_state: expr, $tokenserver_state: expr, $secrets: expr, $limits: expr, $cors: expr, $metrics: expr) => {
|
||
|
+ ($public_url: expr, $syncstorage_state: expr, $tokenserver_state: expr, $secrets: expr, $limits: expr, $cors: expr, $metrics: expr) => {
|
||
|
App::new()
|
||
|
.configure(|cfg| {
|
||
|
cfg.app_data(Data::new($syncstorage_state));
|
||
|
@@ -90,6 +90,7 @@ macro_rules! build_app {
|
||
|
cfg.app_data(Data::new(state));
|
||
|
}
|
||
|
})
|
||
|
+ .app_data(Data::new($public_url))
|
||
|
.app_data(Data::new($secrets))
|
||
|
// Middleware is applied LIFO
|
||
|
// These will wrap all outbound responses with matching status codes.
|
||
|
@@ -336,6 +337,7 @@ impl Server {
|
||
|
};
|
||
|
|
||
|
build_app!(
|
||
|
+ settings.public_url.clone(),
|
||
|
syncstorage_state,
|
||
|
tokenserver_state.clone(),
|
||
|
Arc::clone(&secrets),
|
||
|
diff --git a/syncserver/src/server/test.rs b/syncserver/src/server/test.rs
|
||
|
index 8690526..7efbe98 100644
|
||
|
--- a/syncserver/src/server/test.rs
|
||
|
+++ b/syncserver/src/server/test.rs
|
||
|
@@ -127,6 +127,7 @@ macro_rules! init_app {
|
||
|
let state = get_test_state(&$settings).await;
|
||
|
let metrics = state.metrics.clone();
|
||
|
test::init_service(build_app!(
|
||
|
+ $settings.public_url.clone(),
|
||
|
state,
|
||
|
None::<tokenserver::ServerState>,
|
||
|
Arc::clone(&SECRETS),
|
||
|
@@ -248,6 +249,7 @@ where
|
||
|
let state = get_test_state(&settings).await;
|
||
|
let metrics = state.metrics.clone();
|
||
|
let app = test::init_service(build_app!(
|
||
|
+ settings.public_url.clone(),
|
||
|
state,
|
||
|
None::<tokenserver::ServerState>,
|
||
|
Arc::clone(&SECRETS),
|
||
|
@@ -292,6 +294,7 @@ async fn test_endpoint_with_body(
|
||
|
let state = get_test_state(&settings).await;
|
||
|
let metrics = state.metrics.clone();
|
||
|
let app = test::init_service(build_app!(
|
||
|
+ settings.public_url.clone(),
|
||
|
state,
|
||
|
None::<tokenserver::ServerState>,
|
||
|
Arc::clone(&SECRETS),
|
||
|
diff --git a/syncserver/src/web/auth.rs b/syncserver/src/web/auth.rs
|
||
|
index 9153d38..ca1d123 100644
|
||
|
--- a/syncserver/src/web/auth.rs
|
||
|
+++ b/syncserver/src/web/auth.rs
|
||
|
@@ -170,6 +170,7 @@ impl HawkPayload {
|
||
|
pub fn extrude(
|
||
|
header: &str,
|
||
|
method: &str,
|
||
|
+ public_url: &Option<String>,
|
||
|
secrets: &Secrets,
|
||
|
ci: &ConnectionInfo,
|
||
|
uri: &Uri,
|
||
|
@@ -190,6 +191,15 @@ impl HawkPayload {
|
||
|
} else {
|
||
|
80
|
||
|
};
|
||
|
+
|
||
|
+ let prefix = match &public_url {
|
||
|
+ None => "".to_owned(),
|
||
|
+ Some(url) => match url.parse::<Uri>() {
|
||
|
+ Err(_) => "".to_owned(),
|
||
|
+ Ok(uri) => uri.path().to_owned()
|
||
|
+ }
|
||
|
+ };
|
||
|
+
|
||
|
let path = uri.path_and_query().ok_or(HawkErrorKind::MissingPath)?;
|
||
|
let expiry = if path.path().ends_with("/info/collections") {
|
||
|
0
|
||
|
@@ -197,7 +207,7 @@ impl HawkPayload {
|
||
|
Utc::now().timestamp() as u64
|
||
|
};
|
||
|
|
||
|
- HawkPayload::new(header, method, path.as_str(), host, port, secrets, expiry)
|
||
|
+ HawkPayload::new(header, method, (prefix + path.as_str()).as_str(), host, port, secrets, expiry)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/syncserver/src/web/extractors.rs b/syncserver/src/web/extractors.rs
|
||
|
index 4bd617b..b9aee1c 100644
|
||
|
--- a/syncserver/src/web/extractors.rs
|
||
|
+++ b/syncserver/src/web/extractors.rs
|
||
|
@@ -1056,6 +1056,7 @@ impl HawkIdentifier {
|
||
|
method: &str,
|
||
|
uri: &Uri,
|
||
|
ci: &ConnectionInfo,
|
||
|
+ public_url: &Option<String>,
|
||
|
secrets: &Secrets,
|
||
|
) -> Result<Self, Error>
|
||
|
where
|
||
|
@@ -1072,6 +1073,7 @@ impl HawkIdentifier {
|
||
|
.to_str()
|
||
|
.map_err(|e| -> ApiError { HawkErrorKind::Header(e).into() })?;
|
||
|
let identifier = Self::generate(
|
||
|
+ public_url,
|
||
|
secrets,
|
||
|
method,
|
||
|
auth_header,
|
||
|
@@ -1084,6 +1086,7 @@ impl HawkIdentifier {
|
||
|
}
|
||
|
|
||
|
pub fn generate(
|
||
|
+ public_url: &Option<String>,
|
||
|
secrets: &Secrets,
|
||
|
method: &str,
|
||
|
header: &str,
|
||
|
@@ -1091,7 +1094,7 @@ impl HawkIdentifier {
|
||
|
uri: &Uri,
|
||
|
exts: &mut Extensions,
|
||
|
) -> Result<Self, Error> {
|
||
|
- let payload = HawkPayload::extrude(header, method, secrets, connection_info, uri)?;
|
||
|
+ let payload = HawkPayload::extrude(header, method, &public_url, secrets, connection_info, uri)?;
|
||
|
let puid = Self::uid_from_path(uri)?;
|
||
|
if payload.user_id != puid {
|
||
|
warn!("⚠️ Hawk UID not in URI: {:?} {:?}", payload.user_id, uri);
|
||
|
@@ -1145,6 +1148,12 @@ impl FromRequest for HawkIdentifier {
|
||
|
// NOTE: `connection_info()` will get a mutable reference lock on `extensions()`
|
||
|
let connection_info = req.connection_info().clone();
|
||
|
let method = req.method().clone();
|
||
|
+
|
||
|
+ let public_url: &Option<String> = match &req.app_data::<Data<Option<String>>>() {
|
||
|
+ Some(data) => data,
|
||
|
+ None => &None
|
||
|
+ };
|
||
|
+
|
||
|
// Tried collapsing this to a `.or_else` and hit problems with the return resolving
|
||
|
// to an appropriate error state. Can't use `?` since the function does not return a result.
|
||
|
let secrets = match req.app_data::<Data<Arc<Secrets>>>() {
|
||
|
@@ -1155,7 +1164,7 @@ impl FromRequest for HawkIdentifier {
|
||
|
}
|
||
|
};
|
||
|
|
||
|
- let result = Self::extrude(&req, method.as_str(), uri, &connection_info, secrets);
|
||
|
+ let result = Self::extrude(&req, method.as_str(), uri, &connection_info, &public_url, secrets);
|
||
|
|
||
|
if let Ok(ref hawk_id) = result {
|
||
|
// Store the origin of the token as an extra to be included when emitting a Sentry error
|