identity_verification/verification_method/
builder.rs1use identity_core::common::Object;
5
6use crate::error::Result;
7use crate::verification_method::MethodData;
8use crate::verification_method::MethodType;
9use crate::verification_method::VerificationMethod;
10use identity_did::CoreDID;
11use identity_did::DIDUrl;
12
13#[derive(Clone, Debug, Default)]
15pub struct MethodBuilder {
16 pub(crate) id: Option<DIDUrl>,
17 pub(crate) controller: Option<CoreDID>,
18 pub(crate) type_: Option<MethodType>,
19 pub(crate) data: Option<MethodData>,
20 pub(crate) properties: Object,
21}
22
23impl MethodBuilder {
24 pub fn new(properties: Object) -> Self {
26 Self {
27 id: None,
28 controller: None,
29 type_: None,
30 data: None,
31 properties,
32 }
33 }
34
35 #[must_use]
37 pub fn id(mut self, value: DIDUrl) -> Self {
38 self.id = Some(value);
39 self
40 }
41
42 #[must_use]
44 pub fn controller(mut self, value: CoreDID) -> Self {
45 self.controller = Some(value);
46 self
47 }
48
49 #[must_use]
51 pub fn type_(mut self, value: MethodType) -> Self {
52 self.type_ = Some(value);
53 self
54 }
55
56 #[must_use]
58 pub fn data(mut self, value: MethodData) -> Self {
59 self.data = Some(value);
60 self
61 }
62
63 pub fn build(self) -> Result<VerificationMethod> {
65 VerificationMethod::from_builder(self)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use identity_core::convert::FromJson;
72 use identity_did::DID;
73 use identity_jose::jwk::Jwk;
74
75 use crate::Error;
76
77 use super::*;
78
79 #[test]
80 fn test_method_builder_success() {
81 for method_data_fn in [MethodData::new_base58, MethodData::new_multibase] {
82 let result: Result<VerificationMethod> = MethodBuilder::default()
83 .id("did:example:123#key".parse().unwrap())
84 .controller("did:example:123".parse().unwrap())
85 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
86 .data(method_data_fn(""))
87 .build();
88 assert!(result.is_ok());
89 }
90 }
91
92 #[test]
93 fn test_missing_id_fragment() {
94 let result: Result<VerificationMethod> = MethodBuilder::default()
95 .id("did:example:123".parse().unwrap())
96 .controller("did:example:123".parse().unwrap())
97 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
98 .data(MethodData::PublicKeyMultibase("".into()))
99 .build();
100 assert!(matches!(result.unwrap_err(), Error::InvalidMethod(_)));
101 }
102
103 #[test]
104 fn test_missing_id() {
105 let result: Result<VerificationMethod> = MethodBuilder::default()
106 .controller("did:example:123".parse().unwrap())
107 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
108 .data(MethodData::PublicKeyMultibase("".into()))
109 .build();
110 assert!(matches!(result.unwrap_err(), Error::InvalidMethod(_)));
111 }
112
113 #[test]
114 fn test_missing_type() {
115 let result: Result<VerificationMethod> = MethodBuilder::default()
116 .id("did:example:123#key".parse().unwrap())
117 .controller("did:example:123".parse().unwrap())
118 .data(MethodData::PublicKeyMultibase("".into()))
119 .build();
120 assert!(matches!(result.unwrap_err(), Error::InvalidMethod(_)));
121 }
122
123 #[test]
124 fn test_missing_data() {
125 let result: Result<VerificationMethod> = MethodBuilder::default()
126 .id("did:example:123#key".parse().unwrap())
127 .controller("did:example:123".parse().unwrap())
128 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
129 .build();
130 assert!(matches!(result.unwrap_err(), Error::InvalidMethod(_)));
131 }
132
133 #[test]
134 fn test_missing_controller() {
135 let result: Result<VerificationMethod> = MethodBuilder::default()
136 .id("did:example:123#key".parse().unwrap())
137 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
138 .data(MethodData::PublicKeyMultibase("".into()))
139 .build();
140 assert!(matches!(result.unwrap_err(), Error::InvalidMethod(_)));
141 }
142
143 #[test]
144 fn test_jwk_contains_private_key_material() {
145 let jwk: Jwk = Jwk::from_json(
146 r#"
147 {
148 "kty": "OKP",
149 "crv": "Ed25519",
150 "d": "nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
151 "x": "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
152 }
153 "#,
154 )
155 .unwrap();
156
157 let did: CoreDID = "did:example:123".parse().unwrap();
158 let result: Result<VerificationMethod> = MethodBuilder::default()
159 .id(did.clone().join("#key-0").unwrap())
160 .controller(did.clone())
161 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
162 .data(MethodData::PublicKeyJwk(jwk.clone()))
163 .build();
164 assert!(matches!(result.unwrap_err(), Error::PrivateKeyMaterialExposed));
165
166 let err: Error = VerificationMethod::new_from_jwk(did, jwk, Some("#frag")).unwrap_err();
167 assert!(matches!(err, Error::PrivateKeyMaterialExposed));
168 }
169}