Skip to content

Commit 0352b84

Browse files
authored
Support %-encoded characters in DID method id (#1303)
1 parent e68538f commit 0352b84

File tree

6 files changed

+31
-24
lines changed

6 files changed

+31
-24
lines changed

identity_did/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ repository.workspace = true
1111
description = "Agnostic implementation of the Decentralized Identifiers (DID) standard."
1212

1313
[dependencies]
14-
did_url = { version = "0.1", default-features = false, features = ["std", "serde"] }
14+
did_url_parser = { version = "0.2.0", features = ["std", "serde"] }
1515
form_urlencoded = { version = "1.2.0", default-features = false, features = ["alloc"] }
1616
identity_core = { version = "=1.1.1", path = "../identity_core" }
1717
serde.workspace = true

identity_did/src/did.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::fmt::Formatter;
88
use core::str::FromStr;
99
use std::hash::Hash;
1010

11-
use did_url::DID as BaseDIDUrl;
11+
use did_url_parser::DID as BaseDIDUrl;
1212

1313
use identity_core::common::KeyComparable;
1414

@@ -111,14 +111,7 @@ impl CoreDID {
111111
///
112112
/// Returns `Err` if the input is not a valid [`DID`].
113113
pub fn parse(input: impl AsRef<str>) -> Result<Self, Error> {
114-
let base_did_url: BaseDIDUrl = BaseDIDUrl::parse(input).map_err(Error::from)?;
115-
Self::try_from_base_did(base_did_url)
116-
}
117-
118-
/// Try convert a [`BaseDIDUrl`] into a [`CoreDID`].
119-
fn try_from_base_did(base_did_url: BaseDIDUrl) -> Result<Self, Error> {
120-
Self::check_validity(&base_did_url)?;
121-
Ok(Self(base_did_url))
114+
BaseDIDUrl::parse(input).map(Self).map_err(Error::from)
122115
}
123116

124117
/// Set the method name of the [`DID`].
@@ -145,9 +138,23 @@ impl CoreDID {
145138

146139
/// Validates whether a string is a valid [`DID`] method-id.
147140
pub fn valid_method_id(value: &str) -> Result<(), Error> {
148-
if !value.chars().all(is_char_method_id) {
149-
return Err(Error::InvalidMethodId);
141+
// if !value.chars().all(is_char_method_id) {
142+
// return Err(Error::InvalidMethodId);
143+
// }
144+
let mut chars = value.chars();
145+
while let Some(c) = chars.next() {
146+
match c {
147+
'%' => {
148+
let digits = chars.clone().take(2).collect::<String>();
149+
u8::from_str_radix(&digits, 16).map_err(|_| Error::InvalidMethodId)?;
150+
chars.next();
151+
chars.next();
152+
}
153+
c if is_char_method_id(c) => (),
154+
_ => return Err(Error::InvalidMethodId),
155+
}
150156
}
157+
151158
Ok(())
152159
}
153160

@@ -185,7 +192,7 @@ impl TryFrom<BaseDIDUrl> for CoreDID {
185192
type Error = Error;
186193

187194
fn try_from(base_did_url: BaseDIDUrl) -> Result<Self, Self::Error> {
188-
Self::try_from_base_did(base_did_url)
195+
Ok(Self(base_did_url))
189196
}
190197
}
191198

identity_did/src/did_url.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::cmp::Ordering;
1010
use std::hash::Hash;
1111
use std::hash::Hasher;
1212

13-
use did_url::DID as BaseDIDUrl;
13+
use did_url_parser::DID as BaseDIDUrl;
1414

1515
use identity_core::common::KeyComparable;
1616
use identity_core::common::Url;

identity_did/src/error.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ pub enum Error {
2323
Other(&'static str),
2424
}
2525

26-
impl From<did_url::Error> for Error {
27-
fn from(error: did_url::Error) -> Self {
26+
impl From<did_url_parser::Error> for Error {
27+
fn from(error: did_url_parser::Error) -> Self {
2828
match error {
29-
did_url::Error::InvalidFragment => Self::InvalidFragment,
30-
did_url::Error::InvalidMethodId => Self::InvalidMethodId,
31-
did_url::Error::InvalidMethodName => Self::InvalidMethodName,
32-
did_url::Error::InvalidPath => Self::InvalidPath,
33-
did_url::Error::InvalidQuery => Self::InvalidQuery,
34-
did_url::Error::InvalidScheme => Self::InvalidScheme,
29+
did_url_parser::Error::InvalidFragment => Self::InvalidFragment,
30+
did_url_parser::Error::InvalidMethodId => Self::InvalidMethodId,
31+
did_url_parser::Error::InvalidMethodName => Self::InvalidMethodName,
32+
did_url_parser::Error::InvalidPath => Self::InvalidPath,
33+
did_url_parser::Error::InvalidQuery => Self::InvalidQuery,
34+
did_url_parser::Error::InvalidScheme => Self::InvalidScheme,
3535
error => Self::Other(error.as_str()),
3636
}
3737
}

identity_did/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mod error;
2323

2424
pub use crate::did_url::DIDUrl;
2525
pub use crate::did_url::RelativeDIDUrl;
26-
pub use ::did_url::DID as BaseDIDUrl;
26+
pub use ::did_url_parser::DID as BaseDIDUrl;
2727
pub use did::CoreDID;
2828
pub use did::DID;
2929
pub use error::Error;

identity_document/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ rust-version.workspace = true
1212
description = "Method-agnostic implementation of the Decentralized Identifiers (DID) standard."
1313

1414
[dependencies]
15-
did_url = { version = "0.1", default-features = false, features = ["std", "serde"] }
15+
did_url_parser = { version = "0.2.0", features = ["std", "serde"] }
1616
identity_core = { version = "=1.1.1", path = "../identity_core" }
1717
identity_did = { version = "=1.1.1", path = "../identity_did" }
1818
identity_verification = { version = "=1.1.1", path = "../identity_verification", default-features = false }

0 commit comments

Comments
 (0)