Skip to content

Commit f6226cc

Browse files
committed
feat(http): implement the forward id logic
1 parent 5d13fc4 commit f6226cc

File tree

3 files changed

+49
-19
lines changed

3 files changed

+49
-19
lines changed

htsget-config/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -430,13 +430,13 @@ The authorization server should respond with a rule set that htsget-rs can use t
430430

431431
The following additional options can be configured under the `auth` table to enable this:
432432

433-
| Option | Description | Type | Default |
434-
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|----------|
435-
| `authorization_url` | The URL which will be called to authorize the user. A GET request will be issued to the url. Alternatively, this can be a file path to authorize users based on static config. | URL | Not set. |
436-
| `forward_headers` | For each header specified, forward any headers from the client to the authorization server. Headers are forwarded with the `Htsget-Context-` as a prefix. | Array of header names | Not set. |
437-
| `forward_endpoint_type` | Forwards the type of endpoint that the request used in a header called `Htsget-Context-Endpoint-Type`. The value of this header will either be `reads` or `variants`, depending on whether the user requested the reads or variants endpoint. | Boolean | `false` |
438-
| `forward_id` | Forwards the id of the request in a header called `Htsget-Context-Id`. The value of this header will be request path without the `/reads` or `/variants` component. For example, if a request path is `/reads/<id>`, this header will have the same value as `<id>`. | Boolean | `false` |
439-
| `passthrough_auth` | Forward the authorization header to the authorization server directly without renaming it to a `Htsget-Context-` custom header. If this is true, then the `Authorization` header is required with the request. | Boolean | `false` |
433+
| Option | Description | Type | Default |
434+
|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|----------|
435+
| `authorization_url` | The URL which will be called to authorize the user. A GET request will be issued to the url. Alternatively, this can be a file path to authorize users based on static config. | URL | Not set. |
436+
| `forward_headers` | For each header specified, forward any headers from the client to the authorization server. Headers are forwarded with the `Htsget-Context-` as a prefix. | Array of header names | Not set. |
437+
| `forward_endpoint_type` | Forwards the type of endpoint that the request used in a header called `Htsget-Context-Endpoint-Type`. The value of this header will either be `reads` or `variants`, depending on whether the user requested the reads or variants endpoint. | Boolean | `false` |
438+
| `forward_id` | Forwards the id of the request in a header called `Htsget-Context-Id`. The value of this header will be request path without the `/reads/` or `/variants/` component. For example, if a request path is `/reads/<id>`, this header will have the same value as `<id>`. | Boolean | `false` |
439+
| `passthrough_auth` | Forward the authorization header to the authorization server directly without renaming it to a `Htsget-Context-` custom header. If this is true, then the `Authorization` header is required with the request. | Boolean | `false` |
440440

441441
When using the `authorization_url`, the [authentication](#jwt-authentication) config must also be set as htsget-rs will
442442
forward the JWT token to the authorization server so that it can make decisions about the user's authorization. If the

htsget-config/src/config/advanced/auth/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ impl AuthConfigBuilder {
213213
self
214214
}
215215

216-
/// Set whether to forward the id
216+
/// Set whether to forward the id.
217217
pub fn forward_id(mut self, forward_id: bool) -> Self {
218218
self.forward_id = forward_id;
219219
self

htsget-http/src/middleware/auth.rs

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ impl Debug for Auth {
7272
}
7373

7474
const FORWARD_HEADER_PREFIX: &str = "Htsget-Context-";
75-
const ENDPOINT_TYPE_NAME: &str = "Endpoint-Type";
75+
const ENDPOINT_TYPE_HEADER_NAME: &str = "Endpoint-Type";
76+
const ID_HEADER_NAME: &str = "Id";
7677

7778
impl Auth {
7879
/// Get the config for this auth layer instance.
@@ -136,6 +137,7 @@ impl Auth {
136137
request_headers: &HeaderMap,
137138
request_extensions: Option<Value>,
138139
request_endpoint: &Endpoint,
140+
id: &str,
139141
) -> HtsGetResult<HeaderMap> {
140142
let mut forwarded_headers = if self.config.passthrough_auth() {
141143
let auth_header = request_headers
@@ -195,13 +197,23 @@ impl Auth {
195197
}
196198

197199
if self.config.forward_endpoint_type() {
198-
let header_name =
199-
HeaderName::from_str(&format!("{}{}", FORWARD_HEADER_PREFIX, ENDPOINT_TYPE_NAME))?;
200+
let header_name = HeaderName::from_str(&format!(
201+
"{}{}",
202+
FORWARD_HEADER_PREFIX, ENDPOINT_TYPE_HEADER_NAME
203+
))?;
200204
let value = HeaderValue::from_str(&request_endpoint.to_string())?;
201205

202206
forwarded_headers.insert(header_name, value);
203207
}
204208

209+
if self.config.forward_id() {
210+
let header_name =
211+
HeaderName::from_str(&format!("{}{}", FORWARD_HEADER_PREFIX, ID_HEADER_NAME))?;
212+
let value = HeaderValue::from_str(id)?;
213+
214+
forwarded_headers.insert(header_name, value);
215+
}
216+
205217
Ok(forwarded_headers)
206218
}
207219

@@ -213,11 +225,12 @@ impl Auth {
213225
headers: &HeaderMap,
214226
request_extensions: Option<Value>,
215227
request_endpoint: &Endpoint,
228+
id: &str,
216229
) -> HtsGetResult<Option<AuthorizationRestrictions>> {
217230
match self.config.authorization_url() {
218231
Some(UrlOrStatic::Url(uri)) => {
219232
let forwarded_headers =
220-
self.forwarded_headers(headers, request_extensions, request_endpoint)?;
233+
self.forwarded_headers(headers, request_extensions, request_endpoint, id)?;
221234

222235
self
223236
.fetch_from_url(&uri.to_string(), forwarded_headers)
@@ -421,7 +434,7 @@ impl Auth {
421434
endpoint: &Endpoint,
422435
) -> HtsGetResult<Option<AuthorizationRestrictions>> {
423436
let restrictions = self
424-
.query_authorization_service(headers, request_extensions, endpoint)
437+
.query_authorization_service(headers, request_extensions, endpoint, path)
425438
.await?;
426439

427440
if let Some(restrictions) = restrictions {
@@ -613,7 +626,7 @@ mod tests {
613626
("Custom2".parse().unwrap(), "Value".parse().unwrap()),
614627
]);
615628
let forwarded_headers = result
616-
.forwarded_headers(&request_headers, None, &Endpoint::Reads)
629+
.forwarded_headers(&request_headers, None, &Endpoint::Reads, "id")
617630
.unwrap();
618631
assert_eq!(
619632
forwarded_headers,
@@ -638,7 +651,7 @@ mod tests {
638651
let result = AuthBuilder::default().with_config(config).build().unwrap();
639652

640653
let forwarded_headers = result
641-
.forwarded_headers(&request_headers, None, &Endpoint::Reads)
654+
.forwarded_headers(&request_headers, None, &Endpoint::Reads, "id")
642655
.unwrap();
643656
assert_eq!(
644657
forwarded_headers,
@@ -668,7 +681,7 @@ mod tests {
668681
let result = AuthBuilder::default().with_config(config).build().unwrap();
669682

670683
let forwarded_headers = result
671-
.forwarded_headers(&request_headers, None, &Endpoint::Reads)
684+
.forwarded_headers(&request_headers, None, &Endpoint::Reads, "id")
672685
.unwrap();
673686
assert_eq!(
674687
forwarded_headers,
@@ -695,6 +708,7 @@ mod tests {
695708
"Key": "Value"
696709
})),
697710
&Endpoint::Reads,
711+
"id",
698712
)
699713
.unwrap();
700714
assert_eq!(
@@ -705,21 +719,37 @@ mod tests {
705719
),])
706720
);
707721

708-
let config = builder.forward_endpoint_type(true).build().unwrap();
722+
let config = builder.clone().forward_endpoint_type(true).build().unwrap();
709723
let result = AuthBuilder::default().with_config(config).build().unwrap();
710724

711725
let forwarded_headers = result
712-
.forwarded_headers(&request_headers, None, &Endpoint::Variants)
726+
.forwarded_headers(&request_headers, None, &Endpoint::Variants, "id")
713727
.unwrap();
714728
assert_eq!(
715729
forwarded_headers,
716730
HeaderMap::from_iter([(
717-
format!("{}{}", FORWARD_HEADER_PREFIX, ENDPOINT_TYPE_NAME)
731+
format!("{}{}", FORWARD_HEADER_PREFIX, ENDPOINT_TYPE_HEADER_NAME)
718732
.parse()
719733
.unwrap(),
720734
"variants".parse().unwrap()
721735
),])
722736
);
737+
738+
let config = builder.forward_id(true).build().unwrap();
739+
let result = AuthBuilder::default().with_config(config).build().unwrap();
740+
741+
let forwarded_headers = result
742+
.forwarded_headers(&request_headers, None, &Endpoint::Variants, "id")
743+
.unwrap();
744+
assert_eq!(
745+
forwarded_headers,
746+
HeaderMap::from_iter([(
747+
format!("{}{}", FORWARD_HEADER_PREFIX, ID_HEADER_NAME)
748+
.parse()
749+
.unwrap(),
750+
"id".parse().unwrap()
751+
),])
752+
);
723753
}
724754

725755
#[test]

0 commit comments

Comments
 (0)