Skip to content

Commit 28a2654

Browse files
committed
Add PAT (Personal Access Token) auth support
- Add set_pat() convenience method on Configuration to set a PAT that is used in place of an application key (DD-APPLICATION-KEY header) - Add DD_PAT env var support, taking precedence over DD_APP_KEY when set - Update both configuration.rs and configuration.j2 template in sync - Add unit tests for PAT configuration behavior Ref: CRED-2150
1 parent f2e7ab9 commit 28a2654

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

.generator/src/generator/templates/configuration.j2

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ impl Configuration {
106106
self.auth_keys.insert(operation_str.to_string(), api_key);
107107
}
108108

109+
/// Set a Personal Access Token (PAT) for authentication.
110+
/// The PAT is used in place of an application key and is sent
111+
/// via the DD-APPLICATION-KEY header.
112+
pub fn set_pat(&mut self, pat: String) {
113+
self.auth_keys.insert(
114+
"appKeyAuth".to_string(),
115+
APIKey {
116+
key: pat,
117+
prefix: "".to_owned(),
118+
},
119+
);
120+
}
121+
109122
pub fn set_proxy_url(&mut self, proxy_url: Option<String>) {
110123
self.proxy_url = proxy_url;
111124
}
@@ -149,6 +162,19 @@ impl Default for Configuration {
149162
{%- endfor %}
150163
{%- endif %}
151164

165+
// DD_PAT takes precedence over DD_APP_KEY when set
166+
if let Ok(pat) = env::var("DD_PAT") {
167+
if !pat.is_empty() {
168+
auth_keys.insert(
169+
"appKeyAuth".to_owned(),
170+
APIKey {
171+
key: pat,
172+
prefix: "".to_owned(),
173+
},
174+
);
175+
}
176+
}
177+
152178
Self {
153179
user_agent: DEFAULT_USER_AGENT.clone(),
154180
unstable_operations,

src/datadog/configuration.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ impl Configuration {
109109
self.auth_keys.insert(operation_str.to_string(), api_key);
110110
}
111111

112+
/// Set a Personal Access Token (PAT) for authentication.
113+
/// The PAT is used in place of an application key and is sent
114+
/// via the DD-APPLICATION-KEY header.
115+
pub fn set_pat(&mut self, pat: String) {
116+
self.auth_keys.insert(
117+
"appKeyAuth".to_string(),
118+
APIKey {
119+
key: pat,
120+
prefix: "".to_owned(),
121+
},
122+
);
123+
}
124+
112125
pub fn set_proxy_url(&mut self, proxy_url: Option<String>) {
113126
self.proxy_url = proxy_url;
114127
}
@@ -363,6 +376,19 @@ impl Default for Configuration {
363376
},
364377
);
365378

379+
// DD_PAT takes precedence over DD_APP_KEY when set
380+
if let Ok(pat) = env::var("DD_PAT") {
381+
if !pat.is_empty() {
382+
auth_keys.insert(
383+
"appKeyAuth".to_owned(),
384+
APIKey {
385+
key: pat,
386+
prefix: "".to_owned(),
387+
},
388+
);
389+
}
390+
}
391+
366392
Self {
367393
user_agent: DEFAULT_USER_AGENT.clone(),
368394
unstable_operations,
@@ -1128,3 +1154,113 @@ lazy_static! {
11281154
])
11291155
};
11301156
}
1157+
1158+
#[cfg(test)]
1159+
mod tests {
1160+
use super::*;
1161+
use std::sync::Mutex;
1162+
1163+
// Mutex to prevent env var tests from interfering with each other
1164+
static ENV_MUTEX: Mutex<()> = Mutex::new(());
1165+
1166+
#[test]
1167+
fn test_set_pat_overrides_app_key() {
1168+
let mut config = Configuration::new();
1169+
config.set_pat("my-pat-token".to_string());
1170+
1171+
let app_key = config.auth_keys.get("appKeyAuth").unwrap();
1172+
assert_eq!(app_key.key, "my-pat-token");
1173+
}
1174+
1175+
#[test]
1176+
fn test_set_pat_after_construction() {
1177+
let mut config = Configuration::new();
1178+
// Set an app key first
1179+
config.set_auth_key(
1180+
"appKeyAuth",
1181+
APIKey {
1182+
key: "original-app-key".to_string(),
1183+
prefix: "".to_string(),
1184+
},
1185+
);
1186+
// Now override with PAT
1187+
config.set_pat("my-pat-token".to_string());
1188+
1189+
let app_key = config.auth_keys.get("appKeyAuth").unwrap();
1190+
assert_eq!(app_key.key, "my-pat-token");
1191+
}
1192+
1193+
#[test]
1194+
fn test_dd_pat_env_var() {
1195+
let _lock = ENV_MUTEX.lock().unwrap();
1196+
// Save and clear existing values
1197+
let old_pat = env::var("DD_PAT").ok();
1198+
let old_app_key = env::var("DD_APP_KEY").ok();
1199+
1200+
env::set_var("DD_PAT", "env-pat-token");
1201+
env::remove_var("DD_APP_KEY");
1202+
1203+
let config = Configuration::default();
1204+
let app_key = config.auth_keys.get("appKeyAuth").unwrap();
1205+
assert_eq!(app_key.key, "env-pat-token");
1206+
1207+
// Restore env
1208+
match old_pat {
1209+
Some(v) => env::set_var("DD_PAT", v),
1210+
None => env::remove_var("DD_PAT"),
1211+
}
1212+
match old_app_key {
1213+
Some(v) => env::set_var("DD_APP_KEY", v),
1214+
None => env::remove_var("DD_APP_KEY"),
1215+
}
1216+
}
1217+
1218+
#[test]
1219+
fn test_dd_pat_precedence_over_dd_app_key() {
1220+
let _lock = ENV_MUTEX.lock().unwrap();
1221+
// Save existing values
1222+
let old_pat = env::var("DD_PAT").ok();
1223+
let old_app_key = env::var("DD_APP_KEY").ok();
1224+
1225+
env::set_var("DD_PAT", "pat-wins");
1226+
env::set_var("DD_APP_KEY", "app-key-loses");
1227+
1228+
let config = Configuration::default();
1229+
let app_key = config.auth_keys.get("appKeyAuth").unwrap();
1230+
assert_eq!(app_key.key, "pat-wins");
1231+
1232+
// Restore env
1233+
match old_pat {
1234+
Some(v) => env::set_var("DD_PAT", v),
1235+
None => env::remove_var("DD_PAT"),
1236+
}
1237+
match old_app_key {
1238+
Some(v) => env::set_var("DD_APP_KEY", v),
1239+
None => env::remove_var("DD_APP_KEY"),
1240+
}
1241+
}
1242+
1243+
#[test]
1244+
fn test_empty_dd_pat_does_not_override() {
1245+
let _lock = ENV_MUTEX.lock().unwrap();
1246+
let old_pat = env::var("DD_PAT").ok();
1247+
let old_app_key = env::var("DD_APP_KEY").ok();
1248+
1249+
env::set_var("DD_PAT", "");
1250+
env::set_var("DD_APP_KEY", "my-app-key");
1251+
1252+
let config = Configuration::default();
1253+
let app_key = config.auth_keys.get("appKeyAuth").unwrap();
1254+
assert_eq!(app_key.key, "my-app-key");
1255+
1256+
// Restore env
1257+
match old_pat {
1258+
Some(v) => env::set_var("DD_PAT", v),
1259+
None => env::remove_var("DD_PAT"),
1260+
}
1261+
match old_app_key {
1262+
Some(v) => env::set_var("DD_APP_KEY", v),
1263+
None => env::remove_var("DD_APP_KEY"),
1264+
}
1265+
}
1266+
}

0 commit comments

Comments
 (0)