clientAclController.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. import { Request, Response } from 'express';
  2. import { ClientAclModel } from '../models/clientAcl';
  3. import { toString } from '../utils/helpers';
  4. export class ClientAclController {
  5. // 获取所有客户端授权规则
  6. static async getAllClientAcl(req: Request, res: Response): Promise<void> {
  7. try {
  8. const page = Number(req.query.page) || 1;
  9. const limit = Number(req.query.limit) || 20;
  10. const offset = (page - 1) * limit;
  11. const clientAcls = await ClientAclModel.getAll(limit, offset);
  12. const total = await ClientAclModel.getCount();
  13. res.status(200).json({
  14. success: true,
  15. data: clientAcls,
  16. pagination: {
  17. page,
  18. limit,
  19. total,
  20. pages: Math.ceil(total / limit)
  21. }
  22. });
  23. } catch (error) {
  24. console.error('获取客户端授权规则列表失败:', error);
  25. res.status(500).json({
  26. success: false,
  27. message: '获取客户端授权规则列表失败',
  28. error: error instanceof Error ? error.message : '未知错误'
  29. });
  30. }
  31. }
  32. // 根据ID获取客户端授权规则
  33. static async getClientAclById(req: Request, res: Response): Promise<void> {
  34. try {
  35. const { id } = req.params;
  36. if (!id || isNaN(Number(id))) {
  37. res.status(400).json({
  38. success: false,
  39. message: '无效的ID'
  40. });
  41. return;
  42. }
  43. const clientAcl = await ClientAclModel.getById(Number(id));
  44. if (!clientAcl) {
  45. res.status(404).json({
  46. success: false,
  47. message: '客户端授权规则不存在'
  48. });
  49. return;
  50. }
  51. res.status(200).json({
  52. success: true,
  53. data: clientAcl
  54. });
  55. } catch (error) {
  56. console.error('获取客户端授权规则失败:', error);
  57. res.status(500).json({
  58. success: false,
  59. message: '获取客户端授权规则失败',
  60. error: error instanceof Error ? error.message : '未知错误'
  61. });
  62. }
  63. }
  64. // 根据用户名获取授权规则
  65. static async getClientAclByUsername(req: Request, res: Response): Promise<void> {
  66. try {
  67. const { username } = req.params;
  68. const usernameStr = toString(username);
  69. if (!usernameStr) {
  70. res.status(400).json({
  71. success: false,
  72. message: '用户名不能为空'
  73. });
  74. return;
  75. }
  76. const clientAcls = await ClientAclModel.getByUsername(usernameStr);
  77. res.status(200).json({
  78. success: true,
  79. data: clientAcls
  80. });
  81. } catch (error) {
  82. console.error('根据用户名获取授权规则失败:', error);
  83. res.status(500).json({
  84. success: false,
  85. message: '根据用户名获取授权规则失败',
  86. error: error instanceof Error ? error.message : '未知错误'
  87. });
  88. }
  89. }
  90. // 根据主题获取授权规则
  91. static async getClientAclByTopic(req: Request, res: Response): Promise<void> {
  92. try {
  93. const { topic } = req.params;
  94. const topicStr = toString(topic);
  95. if (!topicStr) {
  96. res.status(400).json({
  97. success: false,
  98. message: '主题不能为空'
  99. });
  100. return;
  101. }
  102. const clientAcls = await ClientAclModel.getByTopic(topicStr);
  103. res.status(200).json({
  104. success: true,
  105. data: clientAcls
  106. });
  107. } catch (error) {
  108. console.error('根据主题获取授权规则失败:', error);
  109. res.status(500).json({
  110. success: false,
  111. message: '根据主题获取授权规则失败',
  112. error: error instanceof Error ? error.message : '未知错误'
  113. });
  114. }
  115. }
  116. // 创建客户端授权规则
  117. static async createClientAcl(req: Request, res: Response): Promise<void> {
  118. try {
  119. const { clientid, username, topic, action, permission, priority, description } = req.body;
  120. if (!username || !topic || !action || !permission) {
  121. res.status(400).json({
  122. success: false,
  123. message: '用户名、主题、操作和权限不能为空'
  124. });
  125. return;
  126. }
  127. // 验证action和permission的值
  128. if (!['publish', 'subscribe', 'pubsub'].includes(action)) {
  129. res.status(400).json({
  130. success: false,
  131. message: '操作必须是publish、subscribe或pubsub之一'
  132. });
  133. return;
  134. }
  135. if (!['allow', 'deny'].includes(permission)) {
  136. res.status(400).json({
  137. success: false,
  138. message: '权限必须是allow或deny之一'
  139. });
  140. return;
  141. }
  142. // 创建客户端授权规则
  143. const newClientAcl = await ClientAclModel.create({
  144. clientid: clientid || null,
  145. username,
  146. topic,
  147. action,
  148. permission,
  149. priority: priority || 0,
  150. description: description || null
  151. });
  152. res.status(201).json({
  153. success: true,
  154. data: newClientAcl,
  155. message: '客户端授权规则创建成功'
  156. });
  157. } catch (error) {
  158. console.error('创建客户端授权规则失败:', error);
  159. res.status(500).json({
  160. success: false,
  161. message: '创建客户端授权规则失败',
  162. error: error instanceof Error ? error.message : '未知错误'
  163. });
  164. }
  165. }
  166. // 更新客户端授权规则
  167. static async updateClientAcl(req: Request, res: Response): Promise<void> {
  168. try {
  169. const { id } = req.params;
  170. const { username, topic, action, permission, priority, description } = req.body;
  171. if (!id || isNaN(Number(id))) {
  172. res.status(400).json({
  173. success: false,
  174. message: '无效的ID'
  175. });
  176. return;
  177. }
  178. // 检查客户端授权规则是否存在
  179. const existingClientAcl = await ClientAclModel.getById(Number(id));
  180. if (!existingClientAcl) {
  181. res.status(404).json({
  182. success: false,
  183. message: '客户端授权规则不存在'
  184. });
  185. return;
  186. }
  187. // 验证action和permission的值
  188. if (action && !['publish', 'subscribe', 'pubsub'].includes(action)) {
  189. res.status(400).json({
  190. success: false,
  191. message: '操作必须是publish、subscribe或pubsub之一'
  192. });
  193. return;
  194. }
  195. if (permission && !['allow', 'deny'].includes(permission)) {
  196. res.status(400).json({
  197. success: false,
  198. message: '权限必须是allow或deny之一'
  199. });
  200. return;
  201. }
  202. // 更新客户端授权规则
  203. const updatedClientAcl = await ClientAclModel.update(Number(id), {
  204. username,
  205. topic,
  206. action,
  207. permission,
  208. priority,
  209. description
  210. });
  211. res.status(200).json({
  212. success: true,
  213. data: updatedClientAcl,
  214. message: '客户端授权规则更新成功'
  215. });
  216. } catch (error) {
  217. console.error('更新客户端授权规则失败:', error);
  218. res.status(500).json({
  219. success: false,
  220. message: '更新客户端授权规则失败',
  221. error: error instanceof Error ? error.message : '未知错误'
  222. });
  223. }
  224. }
  225. // 删除客户端授权规则
  226. static async deleteClientAcl(req: Request, res: Response): Promise<void> {
  227. try {
  228. const { id } = req.params;
  229. if (!id || isNaN(Number(id))) {
  230. res.status(400).json({
  231. success: false,
  232. message: '无效的ID'
  233. });
  234. return;
  235. }
  236. // 检查客户端授权规则是否存在
  237. const existingClientAcl = await ClientAclModel.getById(Number(id));
  238. if (!existingClientAcl) {
  239. res.status(404).json({
  240. success: false,
  241. message: '客户端授权规则不存在'
  242. });
  243. return;
  244. }
  245. // 删除客户端授权规则
  246. await ClientAclModel.delete(Number(id));
  247. res.status(200).json({
  248. success: true,
  249. message: '客户端授权规则删除成功'
  250. });
  251. } catch (error) {
  252. console.error('删除客户端授权规则失败:', error);
  253. res.status(500).json({
  254. success: false,
  255. message: '删除客户端授权规则失败',
  256. error: error instanceof Error ? error.message : '未知错误'
  257. });
  258. }
  259. }
  260. // 批量删除客户端授权规则
  261. static async deleteMultipleClientAcl(req: Request, res: Response): Promise<void> {
  262. try {
  263. const { ids } = req.body;
  264. if (!ids || !Array.isArray(ids) || ids.length === 0) {
  265. res.status(400).json({
  266. success: false,
  267. message: '请提供有效的ID列表'
  268. });
  269. return;
  270. }
  271. // 验证所有ID是否为数字
  272. const validIds = ids.filter(id => !isNaN(Number(id)));
  273. if (validIds.length !== ids.length) {
  274. res.status(400).json({
  275. success: false,
  276. message: 'ID列表包含无效的ID'
  277. });
  278. return;
  279. }
  280. // 批量删除客户端授权规则
  281. await ClientAclModel.deleteMultiple(validIds.map(id => Number(id)));
  282. res.status(200).json({
  283. success: true,
  284. message: `成功删除${validIds.length}条客户端授权规则`
  285. });
  286. } catch (error) {
  287. console.error('批量删除客户端授权规则失败:', error);
  288. res.status(500).json({
  289. success: false,
  290. message: '批量删除客户端授权规则失败',
  291. error: error instanceof Error ? error.message : '未知错误'
  292. });
  293. }
  294. }
  295. // 根据用户名和操作类型获取授权规则
  296. static async getClientAclByUsernameAndAction(req: Request, res: Response): Promise<void> {
  297. try {
  298. const { username, action } = req.params;
  299. const usernameStr = toString(username);
  300. const actionStr = toString(action);
  301. if (!usernameStr || !actionStr) {
  302. res.status(400).json({
  303. success: false,
  304. message: '用户名和操作类型不能为空'
  305. });
  306. return;
  307. }
  308. if (!['publish', 'subscribe', 'pubsub'].includes(actionStr)) {
  309. res.status(400).json({
  310. success: false,
  311. message: '操作必须是publish、subscribe或pubsub之一'
  312. });
  313. return;
  314. }
  315. const clientAcls = await ClientAclModel.getByUsernameAndAction(usernameStr, actionStr);
  316. res.status(200).json({
  317. success: true,
  318. data: clientAcls
  319. });
  320. } catch (error) {
  321. console.error('根据用户名和操作类型获取授权规则失败:', error);
  322. res.status(500).json({
  323. success: false,
  324. message: '根据用户名和操作类型获取授权规则失败',
  325. error: error instanceof Error ? error.message : '未知错误'
  326. });
  327. }
  328. }
  329. // 检查用户是否有权限访问特定主题
  330. static async checkUserPermission(req: Request, res: Response): Promise<void> {
  331. try {
  332. const { username, topic, action } = req.body;
  333. if (!username || !topic || !action) {
  334. res.status(400).json({
  335. success: false,
  336. message: '用户名、主题和操作类型不能为空'
  337. });
  338. return;
  339. }
  340. // 验证action的值
  341. if (!['publish', 'subscribe'].includes(action)) {
  342. res.status(400).json({
  343. success: false,
  344. message: '操作必须是publish或subscribe之一'
  345. });
  346. return;
  347. }
  348. // 检查用户权限
  349. const hasPermission = await ClientAclModel.checkPermission(username, topic, action);
  350. res.status(200).json({
  351. success: true,
  352. data: {
  353. username,
  354. topic,
  355. action,
  356. hasPermission
  357. },
  358. message: `用户${hasPermission ? '有' : '没有'}权限${action === 'publish' ? '发布到' : '订阅'}主题${topic}`
  359. });
  360. } catch (error) {
  361. console.error('检查用户权限失败:', error);
  362. res.status(500).json({
  363. success: false,
  364. message: '检查用户权限失败',
  365. error: error instanceof Error ? error.message : '未知错误'
  366. });
  367. }
  368. }
  369. // 获取客户端授权统计信息
  370. static async getClientAclStats(req: Request, res: Response): Promise<void> {
  371. try {
  372. const stats = await ClientAclModel.getPermissionStats();
  373. res.status(200).json({
  374. success: true,
  375. data: stats,
  376. message: '获取客户端授权统计信息成功'
  377. });
  378. } catch (error) {
  379. console.error('获取客户端授权统计信息失败:', error);
  380. res.status(500).json({
  381. success: false,
  382. message: '获取客户端授权统计信息失败',
  383. error: error instanceof Error ? error.message : '未知错误'
  384. });
  385. }
  386. }
  387. }