Ver Fonte

完善区域移除时对应用户对下级设备的mqtt权限变更行为

zii há 3 semanas atrás
pai
commit
44c958ac7d
2 ficheiros alterados com 93 adições e 11 exclusões
  1. 3 3
      src/api/ability.rs
  2. 90 8
      src/api/area.rs

+ 3 - 3
src/api/ability.rs

@@ -214,7 +214,7 @@ pub async fn drop_device(
         return Json(JsonBack{errcode: 3000, errmsg: Some("数据库异常: 获取设备sn失败".to_string())});
     };
     let mut sqls=Vec::new();
-    let mqids = if let Ok(mqids) = state.db_lite.query_rows(
+    let params = if let Ok(mqids) = state.db_lite.query_rows(
         "select u.mqid from map_user_device m left join user u on u.id=m.did where m.did=?", 
         [d.device], 
         |r|{sqls.push("?");r.get::<usize,String>(0)}).await{mqids}else{return Json(JsonBack{errcode:3000,errmsg:Some("数据库异常: 获取用户mqtt-clientid失败".to_string())})};
@@ -228,7 +228,7 @@ pub async fn drop_device(
             match s.db_mq_map.execute(
                 format!("delete from sub where clientid in ({}) and topic in (?,?)",sqls.join(",")).as_str(), 
                 rusqlite::params_from_iter({
-                    let mut m = mqids.clone();
+                    let mut m = params.clone();
                     m.push(format!("/wf/Iot/client/{}",sn));
                     m.push(format!("{}/state",sn));
                     m})).await{
@@ -238,7 +238,7 @@ pub async fn drop_device(
             match s.db_mq_map.execute(
                 format!("delete from pub where clientid in ({}) and topic in (?,?)",sqls.join(",")).as_str(), 
                 rusqlite::params_from_iter({
-                    let mut m = mqids.clone();
+                    let mut m = params.clone();
                     m.push(format!("/wf/Iot/device/{}",sn));
                     m.push(format!("{}/cmd",sn));
                     m})).await{

+ 90 - 8
src/api/area.rs

@@ -1,6 +1,6 @@
 use axum::{Json, extract::State};
 
-use crate::{AppState, api::{JsonBack, check_token, errcode0, token_fail}, datasource::{Datasource, SqliteParams}};
+use crate::{AppState, api::{JsonBack, check_token, errcode0, token_fail}, datasource::{Datasource, SqliteParams}, log, LogLevel::*};
 
 #[derive(serde::Deserialize)]
 pub struct ANew{
@@ -62,7 +62,7 @@ pub struct EditIdName{
     token: String,
     id: u64,
     name: Option<String>,
-    uid: Option<i64>,
+    uid: Option<u64>,
 }
 
 pub async fn a_edit(
@@ -101,14 +101,15 @@ pub async fn a_remove(
     State(state): State<AppState>,
     Json(a): axum::extract::Json<EditIdName>
 ) -> Json<JsonBack> {
-    let (uid,_) = match check_token(&state, a.token).await {
+    let (uid , mut mqid) = match check_token(&state, a.token).await {
         Ok(id) => {id},
         Err(_) => {
             return token_fail();
         }
     };
-    if let Some(uid) = a.uid{
-        match state.db_lite.execute("delete from map_user_area where aid=? and uid=?", (a.id,uid)).await{
+    if let Some(target_uid) = a.uid{
+        // 移除用户-区域关系 按用户
+        match state.db_lite.execute("delete from map_user_area where aid=? and uid=?", (a.id,target_uid)).await{
             Ok(n) => {
                 if n == 0{
                     return Json(JsonBack{errcode: 3000, errmsg: Some(format!("区域关系不存在"))});
@@ -118,7 +119,15 @@ pub async fn a_remove(
                 return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除区域关系失败: {e}"))});
             }
         }
+        // 覆盖mqid为目标用户的mqid
+        match state.db_lite.query("select mqid from user where id=?", [target_uid], |r|{r.get::<usize,String>(0)}).await{
+            Ok(s) => {mqid = s},
+            Err(e) => {
+                return Json(JsonBack{errcode: 3000, errmsg: Some(format!("获取用户mqtt失败: {e}"))});
+            }
+        }
     } else {
+        // 用户删除自己的下属区域
         match state.db_lite.execute("delete from map_user_area where (aid=? or aid in(select id from area where sup=?)) and uid=?", (a.id,a.id,uid)).await{
             Ok(_) => {},
             Err(e) => {
@@ -132,6 +141,43 @@ pub async fn a_remove(
             }
         }
     }
+    // 移除用户对被移除区域的mqtt权限
+    match state.mq_detail{
+        Some(s) => {
+            let mut sqls = vec![];
+            let sns = if let Ok(s) = state.db_lite.query_rows("select sn from device where area=?", [a.id], |r|{r.get::<usize,String>(0)}).await{
+                sqls.append(&mut vec!["?","?"]);
+                s
+            }else{
+                return Json(JsonBack{errcode: 3000, errmsg: Some(format!("获取设备sn失败"))});
+            };
+            match s.db_mq_map.execute(
+                format!("delete from sub where clientid=? and topic in ({})",sqls.join(",")).as_str(), 
+                rusqlite::params_from_iter({
+                    let mut m = vec![mqid.clone()];
+                    for sn in &sns{
+                        m.push(format!("/wf/Iot/device/{}",sn));
+                        m.push(format!("{}/cmd",sn));
+                    }
+                    m})).await{
+                Ok(n) => {log(Warning, format!("delete sub: {}",n))},
+                Err(e) => {log(Warning, format!("error: {e}"))}
+            };
+            match s.db_mq_map.execute(
+                format!("delete from pub where clientid=? and topic in ({})",sqls.join(",")).as_str(), 
+                rusqlite::params_from_iter({
+                    let mut m = vec![mqid];
+                    for sn in &sns{
+                        m.push(format!("/wf/Iot/device/{}",sn));
+                        m.push(format!("{}/cmd",sn));
+                    }
+                    m})).await{
+                Ok(n) => {log(Warning, format!("delete pub: {}",n))},
+                Err(e) => {log(Warning, format!("error: {e}"))}
+            };
+        }
+        None => {}
+    }
     errcode0()
 }
 
@@ -139,7 +185,7 @@ pub async fn a_del(
     State(state): State<AppState>,
     Json(a): axum::extract::Json<EditIdName>
 ) -> Json<JsonBack> {
-    let (uid,_) = match check_token(&state, a.token).await {
+    let (uid, mqid) = match check_token(&state, a.token).await {
         Ok(id) => {id},
         Err(_) => {
             return token_fail();
@@ -174,6 +220,42 @@ pub async fn a_del(
         [a.id,uid]).await {
         return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除设备失败: {e}"))});
     }
-
+    
+    match state.mq_detail{
+        Some(s) => {
+            let mut sqls = vec![];
+            let sns = if let Ok(s) = state.db_lite.query_rows("select sn from device where area=?", [a.id], |r|{r.get::<usize,String>(0)}).await{
+                sqls.append(&mut vec!["?","?"]);
+                s
+            }else{
+                return Json(JsonBack{errcode: 3000, errmsg: Some(format!("获取设备sn失败"))});
+            };
+            match s.db_mq_map.execute(
+                format!("delete from sub where clientid=? and topic in ({})",sqls.join(",")).as_str(), 
+                rusqlite::params_from_iter({
+                    let mut m = vec![mqid.clone()];
+                    for sn in &sns{
+                        m.push(format!("/wf/Iot/device/{}",sn));
+                        m.push(format!("{}/cmd",sn));
+                    }
+                    m})).await{
+                Ok(n) => {log(Warning, format!("delete sub: {}",n))},
+                Err(e) => {log(Warning, format!("error: {e}"))}
+            };
+            match s.db_mq_map.execute(
+                format!("delete from pub where clientid=? and topic in ({})",sqls.join(",")).as_str(), 
+                rusqlite::params_from_iter({
+                    let mut m = vec![mqid];
+                    for sn in &sns{
+                        m.push(format!("/wf/Iot/device/{}",sn));
+                        m.push(format!("{}/cmd",sn));
+                    }
+                    m})).await{
+                Ok(n) => {log(Warning, format!("delete pub: {}",n))},
+                Err(e) => {log(Warning, format!("error: {e}"))}
+            };
+        }
+        None => {}
+    }
     errcode0()
-}
+}