Skip to content

Commit c677510

Browse files
authored
Canonicalize URL path segments in ResourceExt (#2369)
* Canonicalize URL path segments in Resourceext Fixes #2177 * Add "canonicalizes" to KV dictionary
1 parent 9644db3 commit c677510

File tree

5 files changed

+41
-24
lines changed

5 files changed

+41
-24
lines changed

sdk/keyvault/.dict.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
canonicalizes
12
cbcpad
23
ciphertext
34
ckmaeskeywrap

sdk/keyvault/azure_security_keyvault_keys/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
### Bugs Fixed
1010

11+
- `ResourceExt` canonicalizes URL path segments ([#2177](https://github.com/Azure/azure-sdk-for-rust/issues/2177))
12+
1113
### Other Changes
1214

1315
## 0.1.0 (2025-02-18)

sdk/keyvault/azure_security_keyvault_keys/src/resource.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ fn deconstruct(url: &Url) -> Result<ResourceId> {
9494
let vault_url = format!("{}://{}", url.scheme(), url.authority(),);
9595
let mut segments = url
9696
.path_segments()
97-
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "invalid url"))?;
97+
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "invalid url"))?
98+
.filter(|s| !s.is_empty());
9899
segments
99100
.next()
100-
.and_then(none_if_empty)
101101
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "missing collection"))
102102
.and_then(|col| {
103103
if col != "keys" {
@@ -110,10 +110,9 @@ fn deconstruct(url: &Url) -> Result<ResourceId> {
110110
})?;
111111
let name = segments
112112
.next()
113-
.and_then(none_if_empty)
114113
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "missing name"))
115114
.map(String::from)?;
116-
let version = segments.next().and_then(none_if_empty).map(String::from);
115+
let version = segments.next().map(String::from);
117116

118117
Ok(ResourceId {
119118
source_id: url.as_str().into(),
@@ -123,14 +122,6 @@ fn deconstruct(url: &Url) -> Result<ResourceId> {
123122
})
124123
}
125124

126-
fn none_if_empty(s: &str) -> Option<&str> {
127-
if s.is_empty() {
128-
return None;
129-
}
130-
131-
Some(s)
132-
}
133-
134125
mod private {
135126
use crate::models::{DeletedKeyBundle, DeletedKeyItem, KeyBundle, KeyItem};
136127

@@ -284,4 +275,19 @@ mod tests {
284275
}
285276
);
286277
}
278+
279+
#[test]
280+
fn canonicalizes() {
281+
assert_eq!(
282+
"https://vault.azure.net//keys/name/version"
283+
.parse::<ResourceId>()
284+
.unwrap(),
285+
ResourceId {
286+
source_id: "https://vault.azure.net//keys/name/version".to_string(),
287+
vault_url: "https://vault.azure.net".into(),
288+
name: "name".into(),
289+
version: Some("version".into()),
290+
}
291+
);
292+
}
287293
}

sdk/keyvault/azure_security_keyvault_secrets/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
### Bugs Fixed
1010

11+
- `ResourceExt` canonicalizes URL path segments ([#2177](https://github.com/Azure/azure-sdk-for-rust/issues/2177))
12+
1113
### Other Changes
1214

1315
## 0.1.0 (2025-02-18)

sdk/keyvault/azure_security_keyvault_secrets/src/resource.rs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ fn deconstruct(url: &Url) -> Result<ResourceId> {
9292
let vault_url = format!("{}://{}", url.scheme(), url.authority(),);
9393
let mut segments = url
9494
.path_segments()
95-
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "invalid url"))?;
95+
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "invalid url"))?
96+
.filter(|s| !s.is_empty());
9697
segments
9798
.next()
98-
.and_then(none_if_empty)
9999
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "missing collection"))
100100
.and_then(|col| {
101101
if col != "secrets" {
@@ -108,10 +108,9 @@ fn deconstruct(url: &Url) -> Result<ResourceId> {
108108
})?;
109109
let name = segments
110110
.next()
111-
.and_then(none_if_empty)
112111
.ok_or_else(|| azure_core::Error::message(ErrorKind::DataConversion, "missing name"))
113112
.map(String::from)?;
114-
let version = segments.next().and_then(none_if_empty).map(String::from);
113+
let version = segments.next().map(String::from);
115114

116115
Ok(ResourceId {
117116
source_id: url.as_str().into(),
@@ -121,14 +120,6 @@ fn deconstruct(url: &Url) -> Result<ResourceId> {
121120
})
122121
}
123122

124-
fn none_if_empty(s: &str) -> Option<&str> {
125-
if s.is_empty() {
126-
return None;
127-
}
128-
129-
Some(s)
130-
}
131-
132123
mod private {
133124
use crate::models::{DeletedSecretBundle, DeletedSecretItem, SecretBundle, SecretItem};
134125

@@ -281,4 +272,19 @@ mod tests {
281272
}
282273
);
283274
}
275+
276+
#[test]
277+
fn canonicalizes() {
278+
assert_eq!(
279+
"https://vault.azure.net//secrets/name/version"
280+
.parse::<ResourceId>()
281+
.unwrap(),
282+
ResourceId {
283+
source_id: "https://vault.azure.net//secrets/name/version".to_string(),
284+
vault_url: "https://vault.azure.net".into(),
285+
name: "name".into(),
286+
version: Some("version".into()),
287+
}
288+
);
289+
}
284290
}

0 commit comments

Comments
 (0)