gardesk/garwarp / 47ba17e

Browse files

derive caller from dbus header

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
47ba17eab2ddabedd3fe5ee5d69ee39088a6ed3a
Parents
a3b9db6
Tree
8091f4f

1 changed file

StatusFile+-
M garwarp/src/dbus.rs 94 13
garwarp/src/dbus.rsmodified
@@ -3,10 +3,12 @@ use std::collections::HashMap;
3
 use zbus::{
3
 use zbus::{
4
     blocking::Connection,
4
     blocking::Connection,
5
     interface,
5
     interface,
6
+    message::Header,
6
     zvariant::{OwnedObjectPath, OwnedValue},
7
     zvariant::{OwnedObjectPath, OwnedValue},
7
 };
8
 };
8
 
9
 
9
-use crate::error::PortalResponseCode;
10
+use crate::error::{PortalError, map_portal_error};
11
+use crate::portal::derive_request_id_from_handle;
10
 
12
 
11
 pub const BACKEND_DBUS_NAME: &str = "org.freedesktop.impl.portal.desktop.garwarp";
13
 pub const BACKEND_DBUS_NAME: &str = "org.freedesktop.impl.portal.desktop.garwarp";
12
 pub const BACKEND_OBJECT_PATH: &str = "/org/freedesktop/portal/desktop";
14
 pub const BACKEND_OBJECT_PATH: &str = "/org/freedesktop/portal/desktop";
@@ -14,7 +16,24 @@ const INTERFACE_VERSION: u32 = 1;
14
 type PortalMethodReply = (u32, HashMap<String, OwnedValue>);
16
 type PortalMethodReply = (u32, HashMap<String, OwnedValue>);
15
 
17
 
16
 fn failed_response() -> PortalMethodReply {
18
 fn failed_response() -> PortalMethodReply {
17
-    (PortalResponseCode::Failed as u32, HashMap::new())
19
+    failure_response(&PortalError::InternalFailure)
20
+}
21
+
22
+fn failure_response(error: &PortalError) -> PortalMethodReply {
23
+    let mapping = map_portal_error(error);
24
+    (mapping.code as u32, HashMap::new())
25
+}
26
+
27
+fn request_id_for_call(
28
+    request_handle: &OwnedObjectPath,
29
+    header: Header<'_>,
30
+) -> Result<String, PortalError> {
31
+    let sender = header
32
+        .sender()
33
+        .map(|sender| sender.as_str())
34
+        .ok_or(PortalError::UnauthorizedClient)?;
35
+
36
+    derive_request_id_from_handle(sender, request_handle.as_str())
18
 }
37
 }
19
 
38
 
20
 pub struct SessionNameGuard {
39
 pub struct SessionNameGuard {
@@ -44,21 +63,29 @@ struct ScreenshotPortal;
44
 impl ScreenshotPortal {
63
 impl ScreenshotPortal {
45
     fn screenshot(
64
     fn screenshot(
46
         &self,
65
         &self,
47
-        _handle: OwnedObjectPath,
66
+        handle: OwnedObjectPath,
48
         _app_id: &str,
67
         _app_id: &str,
49
         _parent_window: &str,
68
         _parent_window: &str,
50
         _options: HashMap<String, OwnedValue>,
69
         _options: HashMap<String, OwnedValue>,
70
+        #[zbus(header)] header: Header<'_>,
51
     ) -> PortalMethodReply {
71
     ) -> PortalMethodReply {
72
+        if let Err(error) = request_id_for_call(&handle, header) {
73
+            return failure_response(&error);
74
+        }
52
         failed_response()
75
         failed_response()
53
     }
76
     }
54
 
77
 
55
     fn pick_color(
78
     fn pick_color(
56
         &self,
79
         &self,
57
-        _handle: OwnedObjectPath,
80
+        handle: OwnedObjectPath,
58
         _app_id: &str,
81
         _app_id: &str,
59
         _parent_window: &str,
82
         _parent_window: &str,
60
         _options: HashMap<String, OwnedValue>,
83
         _options: HashMap<String, OwnedValue>,
84
+        #[zbus(header)] header: Header<'_>,
61
     ) -> PortalMethodReply {
85
     ) -> PortalMethodReply {
86
+        if let Err(error) = request_id_for_call(&handle, header) {
87
+            return failure_response(&error);
88
+        }
62
         failed_response()
89
         failed_response()
63
     }
90
     }
64
 
91
 
@@ -75,34 +102,46 @@ struct FileChooserPortal;
75
 impl FileChooserPortal {
102
 impl FileChooserPortal {
76
     fn open_file(
103
     fn open_file(
77
         &self,
104
         &self,
78
-        _handle: OwnedObjectPath,
105
+        handle: OwnedObjectPath,
79
         _app_id: &str,
106
         _app_id: &str,
80
         _parent_window: &str,
107
         _parent_window: &str,
81
         _title: &str,
108
         _title: &str,
82
         _options: HashMap<String, OwnedValue>,
109
         _options: HashMap<String, OwnedValue>,
110
+        #[zbus(header)] header: Header<'_>,
83
     ) -> PortalMethodReply {
111
     ) -> PortalMethodReply {
112
+        if let Err(error) = request_id_for_call(&handle, header) {
113
+            return failure_response(&error);
114
+        }
84
         failed_response()
115
         failed_response()
85
     }
116
     }
86
 
117
 
87
     fn save_file(
118
     fn save_file(
88
         &self,
119
         &self,
89
-        _handle: OwnedObjectPath,
120
+        handle: OwnedObjectPath,
90
         _app_id: &str,
121
         _app_id: &str,
91
         _parent_window: &str,
122
         _parent_window: &str,
92
         _title: &str,
123
         _title: &str,
93
         _options: HashMap<String, OwnedValue>,
124
         _options: HashMap<String, OwnedValue>,
125
+        #[zbus(header)] header: Header<'_>,
94
     ) -> PortalMethodReply {
126
     ) -> PortalMethodReply {
127
+        if let Err(error) = request_id_for_call(&handle, header) {
128
+            return failure_response(&error);
129
+        }
95
         failed_response()
130
         failed_response()
96
     }
131
     }
97
 
132
 
98
     fn save_files(
133
     fn save_files(
99
         &self,
134
         &self,
100
-        _handle: OwnedObjectPath,
135
+        handle: OwnedObjectPath,
101
         _app_id: &str,
136
         _app_id: &str,
102
         _parent_window: &str,
137
         _parent_window: &str,
103
         _title: &str,
138
         _title: &str,
104
         _options: HashMap<String, OwnedValue>,
139
         _options: HashMap<String, OwnedValue>,
140
+        #[zbus(header)] header: Header<'_>,
105
     ) -> PortalMethodReply {
141
     ) -> PortalMethodReply {
142
+        if let Err(error) = request_id_for_call(&handle, header) {
143
+            return failure_response(&error);
144
+        }
106
         failed_response()
145
         failed_response()
107
     }
146
     }
108
 
147
 
@@ -119,16 +158,29 @@ struct AppChooserPortal;
119
 impl AppChooserPortal {
158
 impl AppChooserPortal {
120
     fn choose_application(
159
     fn choose_application(
121
         &self,
160
         &self,
122
-        _handle: OwnedObjectPath,
161
+        handle: OwnedObjectPath,
123
         _app_id: &str,
162
         _app_id: &str,
124
         _parent_window: &str,
163
         _parent_window: &str,
125
         _choices: Vec<String>,
164
         _choices: Vec<String>,
126
         _options: HashMap<String, OwnedValue>,
165
         _options: HashMap<String, OwnedValue>,
166
+        #[zbus(header)] header: Header<'_>,
127
     ) -> PortalMethodReply {
167
     ) -> PortalMethodReply {
168
+        if let Err(error) = request_id_for_call(&handle, header) {
169
+            return failure_response(&error);
170
+        }
128
         failed_response()
171
         failed_response()
129
     }
172
     }
130
 
173
 
131
-    fn update_choices(&self, _handle: OwnedObjectPath, _choices: Vec<String>) {}
174
+    fn update_choices(
175
+        &self,
176
+        handle: OwnedObjectPath,
177
+        _choices: Vec<String>,
178
+        #[zbus(header)] header: Header<'_>,
179
+    ) -> zbus::fdo::Result<()> {
180
+        request_id_for_call(&handle, header)
181
+            .map(|_| ())
182
+            .map_err(|error| zbus::fdo::Error::Failed(map_portal_error(&error).reason.to_string()))
183
+    }
132
 
184
 
133
     #[zbus(property)]
185
     #[zbus(property)]
134
     fn version(&self) -> u32 {
186
     fn version(&self) -> u32 {
@@ -145,7 +197,10 @@ mod tests {
145
         ScreenshotPortal,
197
         ScreenshotPortal,
146
     };
198
     };
147
     use crate::error::PortalResponseCode;
199
     use crate::error::PortalResponseCode;
148
-    use zbus::zvariant::{OwnedObjectPath, OwnedValue};
200
+    use zbus::{
201
+        message::{Header, Message},
202
+        zvariant::{OwnedObjectPath, OwnedValue},
203
+    };
149
 
204
 
150
     #[test]
205
     #[test]
151
     fn backend_object_path_is_portal_desktop_path() {
206
     fn backend_object_path_is_portal_desktop_path() {
@@ -167,12 +222,18 @@ mod tests {
167
             "org.test.App",
222
             "org.test.App",
168
             "x11:0x2a",
223
             "x11:0x2a",
169
             options.clone(),
224
             options.clone(),
225
+            test_call_header(),
170
         );
226
         );
171
         assert_eq!(response, PortalResponseCode::Failed as u32);
227
         assert_eq!(response, PortalResponseCode::Failed as u32);
172
         assert!(results.is_empty());
228
         assert!(results.is_empty());
173
 
229
 
174
-        let (response, results) =
230
+        let (response, results) = ScreenshotPortal.pick_color(
175
-            ScreenshotPortal.pick_color(request_handle_path(), "org.test.App", "", options);
231
+            request_handle_path(),
232
+            "org.test.App",
233
+            "",
234
+            options,
235
+            test_call_header(),
236
+        );
176
         assert_eq!(response, PortalResponseCode::Failed as u32);
237
         assert_eq!(response, PortalResponseCode::Failed as u32);
177
         assert!(results.is_empty());
238
         assert!(results.is_empty());
178
     }
239
     }
@@ -186,6 +247,7 @@ mod tests {
186
             "",
247
             "",
187
             "Open",
248
             "Open",
188
             options.clone(),
249
             options.clone(),
250
+            test_call_header(),
189
         );
251
         );
190
         assert_eq!(response, PortalResponseCode::Failed as u32);
252
         assert_eq!(response, PortalResponseCode::Failed as u32);
191
         assert!(results.is_empty());
253
         assert!(results.is_empty());
@@ -196,6 +258,7 @@ mod tests {
196
             "",
258
             "",
197
             "Save",
259
             "Save",
198
             options.clone(),
260
             options.clone(),
261
+            test_call_header(),
199
         );
262
         );
200
         assert_eq!(response, PortalResponseCode::Failed as u32);
263
         assert_eq!(response, PortalResponseCode::Failed as u32);
201
         assert!(results.is_empty());
264
         assert!(results.is_empty());
@@ -206,6 +269,7 @@ mod tests {
206
             "",
269
             "",
207
             "Save",
270
             "Save",
208
             options,
271
             options,
272
+            test_call_header(),
209
         );
273
         );
210
         assert_eq!(response, PortalResponseCode::Failed as u32);
274
         assert_eq!(response, PortalResponseCode::Failed as u32);
211
         assert!(results.is_empty());
275
         assert!(results.is_empty());
@@ -221,15 +285,32 @@ mod tests {
221
             "",
285
             "",
222
             choices.clone(),
286
             choices.clone(),
223
             options,
287
             options,
288
+            test_call_header(),
224
         );
289
         );
225
         assert_eq!(response, PortalResponseCode::Failed as u32);
290
         assert_eq!(response, PortalResponseCode::Failed as u32);
226
         assert!(results.is_empty());
291
         assert!(results.is_empty());
227
 
292
 
228
-        AppChooserPortal.update_choices(request_handle_path(), choices);
293
+        let error = AppChooserPortal
294
+            .update_choices(request_handle_path(), choices, test_call_header())
295
+            .expect_err("update choices should reject missing sender metadata");
296
+        match error {
297
+            zbus::fdo::Error::Failed(reason) => assert_eq!(reason, "unauthorized_client"),
298
+            other => panic!("unexpected update choices error: {other:?}"),
299
+        }
229
     }
300
     }
230
 
301
 
231
     fn request_handle_path() -> OwnedObjectPath {
302
     fn request_handle_path() -> OwnedObjectPath {
232
         OwnedObjectPath::try_from("/org/freedesktop/portal/desktop/request/1_42/token_1")
303
         OwnedObjectPath::try_from("/org/freedesktop/portal/desktop/request/1_42/token_1")
233
             .expect("valid request object path")
304
             .expect("valid request object path")
234
     }
305
     }
306
+
307
+    fn test_call_header() -> Header<'static> {
308
+        let call = Message::method_call(BACKEND_OBJECT_PATH, "TestCall")
309
+            .expect("test call builder")
310
+            .interface("org.freedesktop.impl.portal.Screenshot")
311
+            .expect("test interface")
312
+            .build(&())
313
+            .expect("test message");
314
+        Box::leak(Box::new(call)).header()
315
+    }
235
 }
316
 }