2
2
super :: { CacaoError , Version } ,
3
3
crate :: auth:: did:: { extract_did_data, DID_METHOD_KEY } ,
4
4
serde:: { Deserialize , Serialize } ,
5
+ url:: Url ,
5
6
} ;
6
7
7
8
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize , Hash ) ]
@@ -24,6 +25,7 @@ impl Payload {
24
25
const ISS_POSITION_OF_ADDRESS : usize = 4 ;
25
26
const ISS_POSITION_OF_NAMESPACE : usize = 2 ;
26
27
const ISS_POSITION_OF_REFERENCE : usize = 3 ;
28
+ pub const WALLETCONNECT_IDENTITY_KEY : & ' static str = "walletconnect_identity_key" ;
27
29
28
30
/// TODO: write valdation
29
31
pub fn validate ( & self ) -> Result < ( ) , CacaoError > {
@@ -77,21 +79,141 @@ impl Payload {
77
79
. or_else ( |_| self . identity_key_from_resources ( ) )
78
80
}
79
81
82
+ fn extract_did_key ( did_key : & str ) -> Result < String , CacaoError > {
83
+ extract_did_data ( did_key, DID_METHOD_KEY )
84
+ . map_err ( |_| CacaoError :: PayloadIdentityKey )
85
+ . map ( |data| data. to_owned ( ) )
86
+ }
87
+
80
88
fn identity_key_from_resources ( & self ) -> Result < String , CacaoError > {
81
89
let resources = self
82
90
. resources
83
91
. as_ref ( )
84
92
. ok_or ( CacaoError :: PayloadResources ) ?;
85
93
let did_key = resources. first ( ) . ok_or ( CacaoError :: PayloadIdentityKey ) ?;
86
94
87
- extract_did_data ( did_key, DID_METHOD_KEY )
88
- . map ( |data| data. to_string ( ) )
89
- . map_err ( |_| CacaoError :: PayloadIdentityKey )
95
+ Self :: extract_did_key ( did_key)
90
96
}
91
97
92
98
fn identity_key_from_audience ( & self ) -> Result < String , CacaoError > {
93
- extract_did_data ( & self . aud , DID_METHOD_KEY )
94
- . map ( |data| data. to_string ( ) )
99
+ self . identity_key_from_audience_url ( )
100
+ . or_else ( |_| self . identity_key_from_audience_did_key ( ) )
101
+ }
102
+
103
+ fn identity_key_from_audience_did_key ( & self ) -> Result < String , CacaoError > {
104
+ Self :: extract_did_key ( & self . aud )
105
+ }
106
+
107
+ fn identity_key_from_audience_url ( & self ) -> Result < String , CacaoError > {
108
+ self . aud
109
+ . parse :: < Url > ( )
95
110
. map_err ( |_| CacaoError :: PayloadIdentityKey )
111
+ . and_then ( |url| {
112
+ url. query_pairs ( )
113
+ . find ( |( key, _) | key == Self :: WALLETCONNECT_IDENTITY_KEY )
114
+ . ok_or ( CacaoError :: PayloadIdentityKey )
115
+ . and_then ( |( _, value) | Self :: extract_did_key ( & value) )
116
+ } )
117
+ }
118
+ }
119
+
120
+ #[ cfg( test) ]
121
+ mod tests {
122
+ use super :: * ;
123
+
124
+ #[ test]
125
+ fn identity_key_from_resources ( ) {
126
+ assert_eq ! (
127
+ Payload {
128
+ domain: "example.com" . to_owned( ) ,
129
+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
130
+ statement: None ,
131
+ aud: "" . to_owned( ) ,
132
+ version: Version :: V1 ,
133
+ nonce: "" . to_owned( ) ,
134
+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
135
+ exp: None ,
136
+ nbf: None ,
137
+ request_id: None ,
138
+ resources: Some ( vec![
139
+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
140
+ ] ) ,
141
+ }
142
+ . identity_key( )
143
+ . unwrap( ) ,
144
+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
145
+ ) ;
146
+ }
147
+
148
+ #[ test]
149
+ fn identity_key_from_aud ( ) {
150
+ assert_eq ! (
151
+ Payload {
152
+ domain: "example.com" . to_owned( ) ,
153
+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
154
+ statement: None ,
155
+ aud: "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
156
+ version: Version :: V1 ,
157
+ nonce: "" . to_owned( ) ,
158
+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
159
+ exp: None ,
160
+ nbf: None ,
161
+ request_id: None ,
162
+ resources: Some ( vec![
163
+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht8" . to_owned( ) ,
164
+ ] ) ,
165
+ }
166
+ . identity_key( )
167
+ . unwrap( ) ,
168
+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
169
+ ) ;
170
+ }
171
+
172
+ #[ test]
173
+ fn identity_key_from_aud_url ( ) {
174
+ assert_eq ! (
175
+ Payload {
176
+ domain: "example.com" . to_owned( ) ,
177
+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
178
+ statement: None ,
179
+ aud: "https://example.com?walletconnect_identity_key=did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
180
+ version: Version :: V1 ,
181
+ nonce: "" . to_owned( ) ,
182
+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
183
+ exp: None ,
184
+ nbf: None ,
185
+ request_id: None ,
186
+ resources: Some ( vec![
187
+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht8" . to_owned( ) ,
188
+ ] ) ,
189
+ }
190
+ . identity_key( )
191
+ . unwrap( ) ,
192
+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
193
+ ) ;
194
+ }
195
+
196
+ #[ test]
197
+ fn identity_key_from_aud_url_encoded ( ) {
198
+ assert_eq ! (
199
+ Payload {
200
+ domain: "example.com" . to_owned( ) ,
201
+ iss: "did:pkh:eip155:1:0xdFe7d0E324ed017a74aE311E9236E6CaDB24176b" . to_owned( ) ,
202
+ statement: None ,
203
+ aud: "https://example.com?walletconnect_identity_key=did%3Akey%3Az6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7" . to_owned( ) ,
204
+ version: Version :: V1 ,
205
+ nonce: "" . to_owned( ) ,
206
+ iat: "2023-09-07T11:04:23+02:00" . to_owned( ) ,
207
+ exp: None ,
208
+ nbf: None ,
209
+ request_id: None ,
210
+ resources: Some ( vec![
211
+ "did:key:z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht8" . to_owned( ) ,
212
+ ] ) ,
213
+ }
214
+ . identity_key( )
215
+ . unwrap( ) ,
216
+ "z6MkvjNoiz9AXGH1igzrtB54US5hE9bZPQm1ryKGkCLwWht7"
217
+ ) ;
96
218
}
97
219
}
0 commit comments