| 719 | } |
| 720 | |
| 721 | pub async fn list( |
| 722 | limit: i64, |
| 723 | offset: i64, |
| 724 | filters: &Filters, |
| 725 | order_by: OrderBy, |
| 726 | order_by_desc: bool, |
| 727 | ) -> Result<Vec<DeviceListItem>, Error> { |
| 728 | let mut q = device::dsl::device |
| 729 | .inner_join(device_profile::table) |
| 730 | .inner_join(application::table) |
| 731 | .left_join(multicast_group_device::table) |
| 732 | .select(( |
| 733 | device::dev_eui, |
| 734 | device::name, |
| 735 | device::description, |
| 736 | device_profile::id, |
| 737 | device_profile::name, |
| 738 | device::created_at, |
| 739 | device::updated_at, |
| 740 | device::last_seen_at, |
| 741 | device::margin, |
| 742 | device::external_power_source, |
| 743 | device::battery_level, |
| 744 | device::tags, |
| 745 | )) |
| 746 | .distinct() |
| 747 | .into_boxed(); |
| 748 | |
| 749 | // Filter by user permissions |
| 750 | if let Some(user_id) = &filters.user_id { |
| 751 | q = q.filter(dsl::exists( |
| 752 | user::table |
| 753 | .filter( |
| 754 | user::id |
| 755 | .eq(fields::Uuid::from(user_id)) |
| 756 | .and(user::is_active.eq(true)), |
| 757 | ) |
| 758 | .filter( |
| 759 | user::is_admin.eq(true).or(dsl::exists( |
| 760 | tenant_user::table |
| 761 | .filter( |
| 762 | tenant_user::user_id |
| 763 | .eq(user::id) |
| 764 | .and(tenant_user::tenant_id.eq(application::tenant_id)), |
| 765 | ) |
| 766 | .filter( |
| 767 | tenant_user::is_admin |
| 768 | .eq(true) |
| 769 | .or(tenant_user::is_device_admin.eq(true)) |
| 770 | .or(dsl::exists( |
| 771 | tenant_user_application::table.filter( |
| 772 | tenant_user_application::user_id.eq(user::id).and( |
| 773 | tenant_user_application::application_id |
| 774 | .eq(application::id), |
| 775 | ), |
| 776 | ), |
| 777 | )), |
| 778 | ), |