setUserPermsLogic_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. package user
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "time"
  7. permModel "perms-system-server/internal/model/perm"
  8. "perms-system-server/internal/response"
  9. "perms-system-server/internal/svc"
  10. "perms-system-server/internal/testutil"
  11. "perms-system-server/internal/testutil/ctxhelper"
  12. "perms-system-server/internal/types"
  13. "github.com/stretchr/testify/assert"
  14. "github.com/stretchr/testify/require"
  15. )
  16. type userPermRow struct {
  17. Id int64 `db:"id"`
  18. UserId int64 `db:"userId"`
  19. PermId int64 `db:"permId"`
  20. Effect string `db:"effect"`
  21. }
  22. func findUserPerms(t *testing.T, ctx context.Context, userId int64) []userPermRow {
  23. t.Helper()
  24. conn := testutil.GetTestSqlConn()
  25. var rows []userPermRow
  26. require.NoError(t, conn.QueryRowsCtx(ctx, &rows,
  27. "SELECT `id`,`userId`,`permId`,`effect` FROM `sys_user_perm` WHERE `userId`=?", userId))
  28. return rows
  29. }
  30. func insertTestPerm(t *testing.T, svcCtx *svc.ServiceContext, productCode string) int64 {
  31. t.Helper()
  32. now := time.Now().Unix()
  33. res, err := svcCtx.SysPermModel.Insert(ctxhelper.SuperAdminCtx(), &permModel.SysPerm{
  34. ProductCode: productCode,
  35. Name: "perm_" + testutil.UniqueId(),
  36. Code: "code_" + testutil.UniqueId(),
  37. Status: 1,
  38. CreateTime: now,
  39. UpdateTime: now,
  40. })
  41. require.NoError(t, err)
  42. id, _ := res.LastInsertId()
  43. return id
  44. }
  45. // TC-0192: 正常ALLOW
  46. func TestSetUserPerms_Allow(t *testing.T) {
  47. ctx := ctxhelper.SuperAdminCtx()
  48. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  49. conn := testutil.GetTestSqlConn()
  50. username := testutil.UniqueId()
  51. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  52. mId := insertTestMember(t, svcCtx, "test_product", userId)
  53. p1 := insertTestPerm(t, svcCtx, "test_product")
  54. p2 := insertTestPerm(t, svcCtx, "test_product")
  55. t.Cleanup(func() {
  56. testutil.CleanTableByField(ctx, conn, "`sys_user_perm`", "userId", userId)
  57. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  58. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  59. testutil.CleanTable(ctx, conn, "`sys_perm`", p1, p2)
  60. })
  61. logic := NewSetUserPermsLogic(ctx, svcCtx)
  62. err := logic.SetUserPerms(&types.SetPermsReq{
  63. UserId: userId,
  64. Perms: []types.UserPermItem{
  65. {PermId: p1, Effect: "ALLOW"},
  66. {PermId: p2, Effect: "ALLOW"},
  67. },
  68. })
  69. require.NoError(t, err)
  70. perms := findUserPerms(t, ctx, userId)
  71. assert.Len(t, perms, 2)
  72. for _, p := range perms {
  73. assert.Equal(t, "ALLOW", p.Effect)
  74. }
  75. }
  76. // TC-0194: DENY权限
  77. func TestSetUserPerms_Deny(t *testing.T) {
  78. ctx := ctxhelper.SuperAdminCtx()
  79. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  80. conn := testutil.GetTestSqlConn()
  81. username := testutil.UniqueId()
  82. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  83. mId := insertTestMember(t, svcCtx, "test_product", userId)
  84. p1 := insertTestPerm(t, svcCtx, "test_product")
  85. t.Cleanup(func() {
  86. testutil.CleanTableByField(ctx, conn, "`sys_user_perm`", "userId", userId)
  87. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  88. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  89. testutil.CleanTable(ctx, conn, "`sys_perm`", p1)
  90. })
  91. logic := NewSetUserPermsLogic(ctx, svcCtx)
  92. err := logic.SetUserPerms(&types.SetPermsReq{
  93. UserId: userId,
  94. Perms: []types.UserPermItem{
  95. {PermId: p1, Effect: "DENY"},
  96. },
  97. })
  98. require.NoError(t, err)
  99. perms := findUserPerms(t, ctx, userId)
  100. require.Len(t, perms, 1)
  101. assert.Equal(t, "DENY", perms[0].Effect)
  102. assert.Equal(t, p1, perms[0].PermId)
  103. }
  104. // TC-0193: 用户不存在
  105. func TestSetUserPerms_UserNotFound(t *testing.T) {
  106. ctx := ctxhelper.SuperAdminCtx()
  107. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  108. logic := NewSetUserPermsLogic(ctx, svcCtx)
  109. err := logic.SetUserPerms(&types.SetPermsReq{
  110. UserId: 999999999,
  111. Perms: []types.UserPermItem{
  112. {PermId: 1, Effect: "ALLOW"},
  113. },
  114. })
  115. require.Error(t, err)
  116. var codeErr *response.CodeError
  117. require.True(t, errors.As(err, &codeErr))
  118. assert.Equal(t, 404, codeErr.Code())
  119. assert.Equal(t, "用户不存在", codeErr.Error())
  120. }
  121. // TC-0195: 清空权限
  122. func TestSetUserPerms_EmptyPerms_ClearsAll(t *testing.T) {
  123. ctx := ctxhelper.SuperAdminCtx()
  124. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  125. conn := testutil.GetTestSqlConn()
  126. username := testutil.UniqueId()
  127. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  128. mId := insertTestMember(t, svcCtx, "test_product", userId)
  129. p1 := insertTestPerm(t, svcCtx, "test_product")
  130. t.Cleanup(func() {
  131. testutil.CleanTableByField(ctx, conn, "`sys_user_perm`", "userId", userId)
  132. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  133. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  134. testutil.CleanTable(ctx, conn, "`sys_perm`", p1)
  135. })
  136. logic := NewSetUserPermsLogic(ctx, svcCtx)
  137. err := logic.SetUserPerms(&types.SetPermsReq{
  138. UserId: userId,
  139. Perms: []types.UserPermItem{
  140. {PermId: p1, Effect: "ALLOW"},
  141. },
  142. })
  143. require.NoError(t, err)
  144. err = logic.SetUserPerms(&types.SetPermsReq{
  145. UserId: userId,
  146. Perms: []types.UserPermItem{},
  147. })
  148. require.NoError(t, err)
  149. perms := findUserPerms(t, ctx, userId)
  150. assert.Empty(t, perms)
  151. }
  152. // TC-0196: 无效Effect值
  153. func TestSetUserPerms_InvalidEffect(t *testing.T) {
  154. ctx := ctxhelper.SuperAdminCtx()
  155. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  156. conn := testutil.GetTestSqlConn()
  157. username := testutil.UniqueId()
  158. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  159. mId := insertTestMember(t, svcCtx, "test_product", userId)
  160. t.Cleanup(func() {
  161. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  162. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  163. })
  164. logic := NewSetUserPermsLogic(ctx, svcCtx)
  165. err := logic.SetUserPerms(&types.SetPermsReq{
  166. UserId: userId,
  167. Perms: []types.UserPermItem{
  168. {PermId: 1, Effect: "INVALID"},
  169. },
  170. })
  171. require.Error(t, err)
  172. var codeErr *response.CodeError
  173. require.True(t, errors.As(err, &codeErr))
  174. assert.Equal(t, 400, codeErr.Code())
  175. assert.Contains(t, codeErr.Error(), "effect值无效")
  176. }
  177. // TC-0197: PermId不存在
  178. func TestSetUserPerms_PermNotExists(t *testing.T) {
  179. ctx := ctxhelper.SuperAdminCtx()
  180. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  181. conn := testutil.GetTestSqlConn()
  182. username := testutil.UniqueId()
  183. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  184. mId := insertTestMember(t, svcCtx, "test_product", userId)
  185. t.Cleanup(func() {
  186. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  187. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  188. })
  189. logic := NewSetUserPermsLogic(ctx, svcCtx)
  190. err := logic.SetUserPerms(&types.SetPermsReq{
  191. UserId: userId,
  192. Perms: []types.UserPermItem{
  193. {PermId: 999999999, Effect: "ALLOW"},
  194. },
  195. })
  196. require.Error(t, err)
  197. var codeErr *response.CodeError
  198. require.True(t, errors.As(err, &codeErr))
  199. assert.Equal(t, 400, codeErr.Code())
  200. assert.Contains(t, codeErr.Error(), "无效的权限ID")
  201. }
  202. // TC-0198: 权限不属于当前产品
  203. func TestSetUserPerms_PermBelongsToOtherProduct(t *testing.T) {
  204. ctx := ctxhelper.SuperAdminCtx()
  205. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  206. conn := testutil.GetTestSqlConn()
  207. username := testutil.UniqueId()
  208. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  209. mId := insertTestMember(t, svcCtx, "test_product", userId)
  210. otherPerm := insertTestPerm(t, svcCtx, "other_product")
  211. t.Cleanup(func() {
  212. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  213. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  214. testutil.CleanTable(ctx, conn, "`sys_perm`", otherPerm)
  215. })
  216. logic := NewSetUserPermsLogic(ctx, svcCtx)
  217. err := logic.SetUserPerms(&types.SetPermsReq{
  218. UserId: userId,
  219. Perms: []types.UserPermItem{
  220. {PermId: otherPerm, Effect: "ALLOW"},
  221. },
  222. })
  223. require.Error(t, err)
  224. var codeErr *response.CodeError
  225. require.True(t, errors.As(err, &codeErr))
  226. assert.Equal(t, 400, codeErr.Code())
  227. assert.Contains(t, codeErr.Error(), "其他产品的权限")
  228. }
  229. // TC-0210: 同一权限ID同时为ALLOW和DENY被拒绝
  230. func TestSetUserPerms_ConflictingEffects(t *testing.T) {
  231. ctx := ctxhelper.SuperAdminCtx()
  232. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  233. conn := testutil.GetTestSqlConn()
  234. username := testutil.UniqueId()
  235. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  236. mId := insertTestMember(t, svcCtx, "test_product", userId)
  237. p1 := insertTestPerm(t, svcCtx, "test_product")
  238. t.Cleanup(func() {
  239. testutil.CleanTableByField(ctx, conn, "`sys_user_perm`", "userId", userId)
  240. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  241. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  242. testutil.CleanTable(ctx, conn, "`sys_perm`", p1)
  243. })
  244. logic := NewSetUserPermsLogic(ctx, svcCtx)
  245. err := logic.SetUserPerms(&types.SetPermsReq{
  246. UserId: userId,
  247. Perms: []types.UserPermItem{
  248. {PermId: p1, Effect: "ALLOW"},
  249. {PermId: p1, Effect: "DENY"},
  250. },
  251. })
  252. require.Error(t, err)
  253. var codeErr *response.CodeError
  254. require.True(t, errors.As(err, &codeErr))
  255. assert.Equal(t, 400, codeErr.Code())
  256. assert.Contains(t, codeErr.Error(), "同一权限ID不能同时为 ALLOW 和 DENY")
  257. }
  258. // TC-0211: 重复的权限ID相同Effect被去重
  259. func TestSetUserPerms_DuplicatePermDedup(t *testing.T) {
  260. ctx := ctxhelper.SuperAdminCtx()
  261. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  262. conn := testutil.GetTestSqlConn()
  263. username := testutil.UniqueId()
  264. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  265. mId := insertTestMember(t, svcCtx, "test_product", userId)
  266. p1 := insertTestPerm(t, svcCtx, "test_product")
  267. t.Cleanup(func() {
  268. testutil.CleanTableByField(ctx, conn, "`sys_user_perm`", "userId", userId)
  269. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  270. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  271. testutil.CleanTable(ctx, conn, "`sys_perm`", p1)
  272. })
  273. logic := NewSetUserPermsLogic(ctx, svcCtx)
  274. err := logic.SetUserPerms(&types.SetPermsReq{
  275. UserId: userId,
  276. Perms: []types.UserPermItem{
  277. {PermId: p1, Effect: "ALLOW"},
  278. {PermId: p1, Effect: "ALLOW"},
  279. },
  280. })
  281. require.NoError(t, err)
  282. perms := findUserPerms(t, ctx, userId)
  283. assert.Len(t, perms, 1, "重复的权限ID应被去重,只插入一条")
  284. assert.Equal(t, "ALLOW", perms[0].Effect)
  285. }
  286. // TC-0212: 已禁用的权限不能被设置
  287. func TestSetUserPerms_DisabledPermRejected(t *testing.T) {
  288. ctx := ctxhelper.SuperAdminCtx()
  289. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  290. conn := testutil.GetTestSqlConn()
  291. username := testutil.UniqueId()
  292. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  293. mId := insertTestMember(t, svcCtx, "test_product", userId)
  294. now := time.Now().Unix()
  295. res, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
  296. ProductCode: "test_product",
  297. Name: "disabled_perm_" + testutil.UniqueId(),
  298. Code: "disabled_" + testutil.UniqueId(),
  299. Status: 2,
  300. CreateTime: now,
  301. UpdateTime: now,
  302. })
  303. require.NoError(t, err)
  304. disabledPermId, _ := res.LastInsertId()
  305. t.Cleanup(func() {
  306. testutil.CleanTableByField(ctx, conn, "`sys_user_perm`", "userId", userId)
  307. testutil.CleanTable(ctx, conn, "`sys_product_member`", mId)
  308. testutil.CleanTable(ctx, conn, "`sys_user`", userId)
  309. testutil.CleanTable(ctx, conn, "`sys_perm`", disabledPermId)
  310. })
  311. logic := NewSetUserPermsLogic(ctx, svcCtx)
  312. err = logic.SetUserPerms(&types.SetPermsReq{
  313. UserId: userId,
  314. Perms: []types.UserPermItem{
  315. {PermId: disabledPermId, Effect: "ALLOW"},
  316. },
  317. })
  318. require.Error(t, err)
  319. var codeErr *response.CodeError
  320. require.True(t, errors.As(err, &codeErr))
  321. assert.Equal(t, 400, codeErr.Code())
  322. assert.Contains(t, codeErr.Error(), "已被禁用")
  323. }
  324. // TC-0199: 目标用户不是当前产品成员时拒绝设置权限(L-5修复验证)
  325. func TestSetUserPerms_NonMemberRejected(t *testing.T) {
  326. ctx := ctxhelper.SuperAdminCtx()
  327. svcCtx := svc.NewServiceContext(testutil.GetTestConfig())
  328. conn := testutil.GetTestSqlConn()
  329. username := testutil.UniqueId()
  330. userId := insertTestUser(t, ctx, username, testutil.HashPassword("pass"))
  331. t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user`", userId) })
  332. logic := NewSetUserPermsLogic(ctx, svcCtx)
  333. err := logic.SetUserPerms(&types.SetPermsReq{
  334. UserId: userId,
  335. Perms: []types.UserPermItem{},
  336. })
  337. require.Error(t, err)
  338. var codeErr2 *response.CodeError
  339. require.True(t, errors.As(err, &codeErr2))
  340. assert.Equal(t, 400, codeErr2.Code())
  341. assert.Contains(t, codeErr2.Error(), "不是当前产品的成员")
  342. }