setUserPermsLogic_test.go 12 KB

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