| 240 | } |
| 241 | |
| 242 | async fn list( |
| 243 | &self, |
| 244 | request: Request<api::ListDevicesRequest>, |
| 245 | ) -> Result<Response<api::ListDevicesResponse>, Status> { |
| 246 | let req = request.get_ref(); |
| 247 | let user_id: Option<Uuid> = |
| 248 | if let Some(AuthID::User(v)) = request.extensions().get::<AuthID>() { |
| 249 | Some(*v) |
| 250 | } else { |
| 251 | None |
| 252 | }; |
| 253 | let app_id = Uuid::from_str(&req.application_id).map_err(|e| e.status())?; |
| 254 | let mg_id: Option<Uuid> = if req.multicast_group_id.is_empty() { |
| 255 | None |
| 256 | } else { |
| 257 | Some(Uuid::from_str(&req.multicast_group_id).map_err(|e| e.status())?) |
| 258 | }; |
| 259 | let dp_id: Option<Uuid> = if req.device_profile_id.is_empty() { |
| 260 | None |
| 261 | } else { |
| 262 | Some(Uuid::from_str(&req.device_profile_id).map_err(|e| e.status())?) |
| 263 | }; |
| 264 | |
| 265 | self.validator |
| 266 | .validate( |
| 267 | request.extensions(), |
| 268 | validator::ValidateDevicesAccess::new(validator::Flag::List, app_id), |
| 269 | ) |
| 270 | .await?; |
| 271 | |
| 272 | if let Some(mg_id) = mg_id { |
| 273 | self.validator |
| 274 | .validate( |
| 275 | request.extensions(), |
| 276 | validator::ValidateMulticastGroupAccess::new(validator::Flag::Read, mg_id), |
| 277 | ) |
| 278 | .await?; |
| 279 | } |
| 280 | |
| 281 | let filters = device::Filters { |
| 282 | user_id, |
| 283 | application_id: Some(app_id), |
| 284 | multicast_group_id: mg_id, |
| 285 | device_profile_id: dp_id, |
| 286 | search: if req.search.is_empty() { |
| 287 | None |
| 288 | } else { |
| 289 | Some(req.search.to_string()) |
| 290 | }, |
| 291 | tags: req.tags.clone(), |
| 292 | }; |
| 293 | |
| 294 | let count = device::get_count(&filters).await.map_err(|e| e.status())?; |
| 295 | let items = device::list( |
| 296 | req.limit as i64, |
| 297 | req.offset as i64, |
| 298 | &filters, |
| 299 | req.order_by().from_proto(), |