Skip to content

Commit 820e63b

Browse files
byronwolfmanthomasqueirozbpront
authored
feat(sources): add access to URL path in custom VRL auth (#23165)
* feat(sources) add access to URL path in custom VRL auth * update website docs for VRL custom auth * format components.cue (tabs vs spaces) * Add changelog entry * Address changelog linter --------- Co-authored-by: Thomas <thomas.schneider@datadoghq.com> Co-authored-by: Pavlos Rontidis <pavlos.rontidis@gmail.com>
1 parent d9dc37c commit 820e63b

File tree

5 files changed

+51
-13
lines changed

5 files changed

+51
-13
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Enabled URL path access in VRL scripts of custom auth strategy for server components.
2+
3+
authors: byronwolfman

src/common/http/server_auth.rs

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ impl HttpServerAuthMatcher {
198198
&self,
199199
address: Option<&SocketAddr>,
200200
headers: &HeaderMap<HeaderValue>,
201+
path: &str,
201202
) -> Result<(), ErrorMessage> {
202203
match self {
203204
HttpServerAuthMatcher::AuthHeader(expected, err_message) => {
@@ -218,7 +219,7 @@ impl HttpServerAuthMatcher {
218219
}
219220
}
220221
HttpServerAuthMatcher::Vrl { program } => {
221-
self.handle_vrl_auth(address, headers, program)
222+
self.handle_vrl_auth(address, headers, path, program)
222223
}
223224
}
224225
}
@@ -227,6 +228,7 @@ impl HttpServerAuthMatcher {
227228
&self,
228229
address: Option<&SocketAddr>,
229230
headers: &HeaderMap<HeaderValue>,
231+
path: &str,
230232
program: &Program,
231233
) -> Result<(), ErrorMessage> {
232234
let mut target = VrlTarget::new(
@@ -250,6 +252,7 @@ impl HttpServerAuthMatcher {
250252
"address".into(),
251253
address.map_or(Value::Null, |a| Value::from(a.ip().to_string())),
252254
),
255+
("path".into(), Value::from(path.to_owned())),
253256
]),
254257
Default::default(),
255258
)),
@@ -439,7 +442,7 @@ mod tests {
439442

440443
let matcher = basic_auth.build(&Default::default()).unwrap();
441444

442-
let result = matcher.handle_auth(Some(&next_addr()), &HeaderMap::new());
445+
let result = matcher.handle_auth(Some(&next_addr()), &HeaderMap::new(), "/");
443446

444447
assert!(result.is_err());
445448
let error = result.unwrap_err();
@@ -458,7 +461,7 @@ mod tests {
458461

459462
let mut headers = HeaderMap::new();
460463
headers.insert(AUTHORIZATION, HeaderValue::from_static("Basic wrong"));
461-
let result = matcher.handle_auth(Some(&next_addr()), &headers);
464+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/");
462465

463466
assert!(result.is_err());
464467
let error = result.unwrap_err();
@@ -482,7 +485,7 @@ mod tests {
482485
AUTHORIZATION,
483486
Authorization::basic(&username, &password).0.encode(),
484487
);
485-
let result = matcher.handle_auth(Some(&next_addr()), &headers);
488+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/");
486489

487490
assert!(result.is_ok());
488491
}
@@ -497,7 +500,7 @@ mod tests {
497500

498501
let mut headers = HeaderMap::new();
499502
headers.insert(AUTHORIZATION, HeaderValue::from_static("test"));
500-
let result = matcher.handle_auth(Some(&next_addr()), &headers);
503+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/");
501504

502505
assert!(result.is_ok());
503506
}
@@ -513,7 +516,7 @@ mod tests {
513516
let matcher = custom_auth.build(&Default::default()).unwrap();
514517

515518
let headers = HeaderMap::new();
516-
let result = matcher.handle_auth(Some(&next_addr()), &headers);
519+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/");
517520

518521
assert!(result.is_ok());
519522
}
@@ -529,7 +532,35 @@ mod tests {
529532
let matcher = custom_auth.build(&Default::default()).unwrap();
530533

531534
let headers = HeaderMap::new();
532-
let result = matcher.handle_auth(None, &headers);
535+
let result = matcher.handle_auth(None, &headers, "/");
536+
537+
assert!(result.is_err());
538+
}
539+
540+
#[test]
541+
fn custom_auth_matcher_should_be_able_to_check_path() {
542+
let custom_auth = HttpServerAuthConfig::Custom {
543+
source: r#".path == "/ok""#.to_string(),
544+
};
545+
546+
let matcher = custom_auth.build(&Default::default()).unwrap();
547+
548+
let headers = HeaderMap::new();
549+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/ok");
550+
551+
assert!(result.is_ok());
552+
}
553+
554+
#[test]
555+
fn custom_auth_matcher_should_return_401_with_wrong_path() {
556+
let custom_auth = HttpServerAuthConfig::Custom {
557+
source: r#".path == "/ok""#.to_string(),
558+
};
559+
560+
let matcher = custom_auth.build(&Default::default()).unwrap();
561+
562+
let headers = HeaderMap::new();
563+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/bad");
533564

534565
assert!(result.is_err());
535566
}
@@ -544,7 +575,7 @@ mod tests {
544575

545576
let mut headers = HeaderMap::new();
546577
headers.insert(AUTHORIZATION, HeaderValue::from_static("wrong value"));
547-
let result = matcher.handle_auth(Some(&next_addr()), &headers);
578+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/");
548579

549580
assert!(result.is_err());
550581
let error = result.unwrap_err();
@@ -562,7 +593,7 @@ mod tests {
562593

563594
let mut headers = HeaderMap::new();
564595
headers.insert(AUTHORIZATION, HeaderValue::from_static("test"));
565-
let result = matcher.handle_auth(Some(&next_addr()), &headers);
596+
let result = matcher.handle_auth(Some(&next_addr()), &headers, "/");
566597

567598
assert!(result.is_err());
568599
let error = result.unwrap_err();

src/sinks/websocket_server/sink.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl WebSocketListenerSink {
214214
));
215215
return Ok(response);
216216
};
217-
match auth.handle_auth(Some(&addr), req.headers()) {
217+
match auth.handle_auth(Some(&addr), req.headers(), req.uri().path()) {
218218
Ok(_) => {
219219
extra_tags.append(&mut Self::extract_extra_tags(
220220
&extra_tags_config,

src/sources/util/http/prelude.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ pub trait HttpSource: Clone + Send + Sync + 'static {
133133
let events = auth_matcher
134134
.as_ref()
135135
.map_or(Ok(()), |a| {
136-
a.handle_auth(addr.as_ref().map(|a| a.0).as_ref(), &headers)
136+
a.handle_auth(
137+
addr.as_ref().map(|a| a.0).as_ref(),
138+
&headers,
139+
path.as_str(),
140+
)
137141
})
138142
.and_then(|()| self.decode(encoding_header.as_deref(), body))
139143
.and_then(|body| {

website/cue/reference/components.cue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,8 +1290,8 @@ components: {
12901290
authorization code using VRL. Here is an example that looks up the token in an
12911291
enrichment table backed by a CSV file.
12921292
1293-
Currently custom VRL auth has access to `headers` and `address` (IP address of the
1294-
client).
1293+
Currently custom VRL auth has access to `headers`, `path`, and `address` (IP
1294+
address of the client).
12951295
12961296
```yaml
12971297
\(kind)s:

0 commit comments

Comments
 (0)