perms_test.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. package auth
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "math/rand"
  7. "testing"
  8. "time"
  9. deptModel "perms-system-server/internal/model/dept"
  10. "perms-system-server/internal/model/perm"
  11. "perms-system-server/internal/model/productmember"
  12. "perms-system-server/internal/model/role"
  13. "perms-system-server/internal/model/roleperm"
  14. userModel "perms-system-server/internal/model/user"
  15. "perms-system-server/internal/model/userperm"
  16. "perms-system-server/internal/model/userrole"
  17. "perms-system-server/internal/svc"
  18. "perms-system-server/internal/testutil"
  19. "github.com/stretchr/testify/assert"
  20. "github.com/stretchr/testify/require"
  21. "github.com/zeromicro/go-zero/core/stores/sqlx"
  22. )
  23. func newTestSvcCtx() *svc.ServiceContext {
  24. c := testutil.GetTestConfig()
  25. return svc.NewServiceContext(c)
  26. }
  27. func createPermsTestUser(t *testing.T, ctx context.Context, svcCtx *svc.ServiceContext, isSuperAdmin int64, deptId int64) (int64, func()) {
  28. t.Helper()
  29. conn := testutil.GetTestSqlConn()
  30. now := time.Now().Unix()
  31. username := fmt.Sprintf("perms_u_%d", rand.Intn(1000000))
  32. res, err := svcCtx.SysUserModel.Insert(ctx, &userModel.SysUser{
  33. Username: username,
  34. Password: testutil.HashPassword("pass123"),
  35. Nickname: username,
  36. Avatar: sql.NullString{},
  37. DeptId: deptId,
  38. IsSuperAdmin: isSuperAdmin,
  39. MustChangePassword: 2,
  40. Status: 1,
  41. CreateTime: now,
  42. UpdateTime: now,
  43. })
  44. require.NoError(t, err)
  45. id, _ := res.LastInsertId()
  46. return id, func() { testutil.CleanTable(ctx, conn, "`sys_user`", id) }
  47. }
  48. // TC-0231: superAdmin gets all enabled perms
  49. func TestGetUserPerms_SuperAdmin(t *testing.T) {
  50. ctx := context.Background()
  51. svcCtx := newTestSvcCtx()
  52. conn := testutil.GetTestSqlConn()
  53. now := time.Now().Unix()
  54. pc := fmt.Sprintf("tp_%d", rand.Intn(100000))
  55. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 1, 0)
  56. t.Cleanup(cleanUser)
  57. p1, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  58. ProductCode: pc, Name: "sa_perm1", Code: "sa_code1", Status: 1, CreateTime: now, UpdateTime: now,
  59. })
  60. require.NoError(t, err)
  61. p1Id, _ := p1.LastInsertId()
  62. p2, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  63. ProductCode: pc, Name: "sa_perm2", Code: "sa_code2", Status: 1, CreateTime: now, UpdateTime: now,
  64. })
  65. require.NoError(t, err)
  66. p2Id, _ := p2.LastInsertId()
  67. p3, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  68. ProductCode: pc, Name: "sa_disabled", Code: "sa_code3", Status: 2, CreateTime: now, UpdateTime: now,
  69. })
  70. require.NoError(t, err)
  71. p3Id, _ := p3.LastInsertId()
  72. t.Cleanup(func() {
  73. testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id, p2Id, p3Id)
  74. })
  75. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, true)
  76. require.NoError(t, err)
  77. assert.Equal(t, "SUPER_ADMIN", memberType)
  78. assert.ElementsMatch(t, []string{"sa_code1", "sa_code2"}, perms)
  79. }
  80. // TC-0232: superAdmin with empty product
  81. func TestGetUserPerms_SuperAdmin_EmptyProduct(t *testing.T) {
  82. ctx := context.Background()
  83. svcCtx := newTestSvcCtx()
  84. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 1, 0)
  85. t.Cleanup(cleanUser)
  86. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, "nonexist_product_xyz", true)
  87. require.NoError(t, err)
  88. assert.Equal(t, "SUPER_ADMIN", memberType)
  89. assert.Empty(t, perms)
  90. }
  91. // TC-0233: non product member
  92. func TestGetUserPerms_NotProductMember(t *testing.T) {
  93. ctx := context.Background()
  94. svcCtx := newTestSvcCtx()
  95. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  96. t.Cleanup(cleanUser)
  97. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, "some_product", false)
  98. require.NoError(t, err)
  99. assert.Empty(t, memberType)
  100. assert.Nil(t, perms)
  101. }
  102. // TC-0235: DEVELOPER member
  103. func TestGetUserPerms_Developer(t *testing.T) {
  104. ctx := context.Background()
  105. svcCtx := newTestSvcCtx()
  106. conn := testutil.GetTestSqlConn()
  107. now := time.Now().Unix()
  108. pc := fmt.Sprintf("tp_dev_%d", rand.Intn(100000))
  109. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  110. t.Cleanup(cleanUser)
  111. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  112. ProductCode: pc, UserId: userId, MemberType: "DEVELOPER", Status: 1, CreateTime: now, UpdateTime: now,
  113. })
  114. require.NoError(t, err)
  115. pmId, _ := pmRes.LastInsertId()
  116. p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  117. ProductCode: pc, Name: "dev_p1", Code: "dev_c1", Status: 1, CreateTime: now, UpdateTime: now,
  118. })
  119. require.NoError(t, err)
  120. p1Id, _ := p1Res.LastInsertId()
  121. t.Cleanup(func() {
  122. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  123. testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id)
  124. })
  125. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  126. require.NoError(t, err)
  127. assert.Equal(t, "DEVELOPER", memberType)
  128. assert.Contains(t, perms, "dev_c1")
  129. }
  130. // TC-0236: ADMIN member
  131. func TestGetUserPerms_Admin(t *testing.T) {
  132. ctx := context.Background()
  133. svcCtx := newTestSvcCtx()
  134. conn := testutil.GetTestSqlConn()
  135. now := time.Now().Unix()
  136. pc := fmt.Sprintf("tp_adm_%d", rand.Intn(100000))
  137. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  138. t.Cleanup(cleanUser)
  139. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  140. ProductCode: pc, UserId: userId, MemberType: "ADMIN", Status: 1, CreateTime: now, UpdateTime: now,
  141. })
  142. require.NoError(t, err)
  143. pmId, _ := pmRes.LastInsertId()
  144. p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  145. ProductCode: pc, Name: "adm_p1", Code: "adm_c1", Status: 1, CreateTime: now, UpdateTime: now,
  146. })
  147. require.NoError(t, err)
  148. p1Id, _ := p1Res.LastInsertId()
  149. t.Cleanup(func() {
  150. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  151. testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id)
  152. })
  153. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  154. require.NoError(t, err)
  155. assert.Equal(t, "ADMIN", memberType)
  156. assert.Contains(t, perms, "adm_c1")
  157. }
  158. // TC-0243: MEMBER no roles no user perms
  159. func TestGetUserPerms_Member_NoRolesNoUserPerms(t *testing.T) {
  160. ctx := context.Background()
  161. svcCtx := newTestSvcCtx()
  162. conn := testutil.GetTestSqlConn()
  163. now := time.Now().Unix()
  164. pc := fmt.Sprintf("tp_mbr0_%d", rand.Intn(100000))
  165. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  166. t.Cleanup(cleanUser)
  167. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  168. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  169. })
  170. require.NoError(t, err)
  171. pmId, _ := pmRes.LastInsertId()
  172. t.Cleanup(func() {
  173. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  174. })
  175. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  176. require.NoError(t, err)
  177. assert.Equal(t, "MEMBER", memberType)
  178. assert.Empty(t, perms)
  179. }
  180. // TC-0244: MEMBER with roles
  181. func TestGetUserPerms_Member_WithRoles(t *testing.T) {
  182. ctx := context.Background()
  183. svcCtx := newTestSvcCtx()
  184. conn := testutil.GetTestSqlConn()
  185. now := time.Now().Unix()
  186. pc := fmt.Sprintf("tp_mbrr_%d", rand.Intn(100000))
  187. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  188. t.Cleanup(cleanUser)
  189. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  190. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  191. })
  192. require.NoError(t, err)
  193. pmId, _ := pmRes.LastInsertId()
  194. roleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{
  195. ProductCode: pc, Name: fmt.Sprintf("role_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now,
  196. })
  197. require.NoError(t, err)
  198. roleId, _ := roleRes.LastInsertId()
  199. perm1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  200. ProductCode: pc, Name: "role_perm1", Code: fmt.Sprintf("rc1_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  201. })
  202. require.NoError(t, err)
  203. perm1Id, _ := perm1Res.LastInsertId()
  204. perm2Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  205. ProductCode: pc, Name: "role_perm2", Code: fmt.Sprintf("rc2_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  206. })
  207. require.NoError(t, err)
  208. perm2Id, _ := perm2Res.LastInsertId()
  209. urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{
  210. UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now,
  211. })
  212. require.NoError(t, err)
  213. urId, _ := urRes.LastInsertId()
  214. rpRes1, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{
  215. RoleId: roleId, PermId: perm1Id, CreateTime: now, UpdateTime: now,
  216. })
  217. require.NoError(t, err)
  218. rpId1, _ := rpRes1.LastInsertId()
  219. rpRes2, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{
  220. RoleId: roleId, PermId: perm2Id, CreateTime: now, UpdateTime: now,
  221. })
  222. require.NoError(t, err)
  223. rpId2, _ := rpRes2.LastInsertId()
  224. t.Cleanup(func() {
  225. testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpId1, rpId2)
  226. testutil.CleanTable(ctx, conn, "`sys_user_role`", urId)
  227. testutil.CleanTable(ctx, conn, "`sys_perm`", perm1Id, perm2Id)
  228. testutil.CleanTable(ctx, conn, "`sys_role`", roleId)
  229. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  230. })
  231. perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  232. require.NoError(t, err)
  233. assert.Equal(t, "MEMBER", memberType)
  234. assert.Len(t, perms, 2)
  235. p1, _ := svcCtx.SysPermModel.FindOne(ctx, perm1Id)
  236. p2, _ := svcCtx.SysPermModel.FindOne(ctx, perm2Id)
  237. assert.ElementsMatch(t, []string{p1.Code, p2.Code}, perms)
  238. }
  239. // TC-0248: DENY overrides role perm
  240. func TestGetUserPerms_Member_DENYOverridesRolePerm(t *testing.T) {
  241. ctx := context.Background()
  242. svcCtx := newTestSvcCtx()
  243. conn := testutil.GetTestSqlConn()
  244. now := time.Now().Unix()
  245. pc := fmt.Sprintf("tp_deny_%d", rand.Intn(100000))
  246. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  247. t.Cleanup(cleanUser)
  248. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  249. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  250. })
  251. require.NoError(t, err)
  252. pmId, _ := pmRes.LastInsertId()
  253. roleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{
  254. ProductCode: pc, Name: fmt.Sprintf("role_deny_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now,
  255. })
  256. require.NoError(t, err)
  257. roleId, _ := roleRes.LastInsertId()
  258. permARes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  259. ProductCode: pc, Name: "pA", Code: fmt.Sprintf("pA_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  260. })
  261. require.NoError(t, err)
  262. permAId, _ := permARes.LastInsertId()
  263. permBRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  264. ProductCode: pc, Name: "pB", Code: fmt.Sprintf("pB_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  265. })
  266. require.NoError(t, err)
  267. permBId, _ := permBRes.LastInsertId()
  268. urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{
  269. UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now,
  270. })
  271. require.NoError(t, err)
  272. urId, _ := urRes.LastInsertId()
  273. rpA, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{
  274. RoleId: roleId, PermId: permAId, CreateTime: now, UpdateTime: now,
  275. })
  276. require.NoError(t, err)
  277. rpAId, _ := rpA.LastInsertId()
  278. rpB, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{
  279. RoleId: roleId, PermId: permBId, CreateTime: now, UpdateTime: now,
  280. })
  281. require.NoError(t, err)
  282. rpBId, _ := rpB.LastInsertId()
  283. denyRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{
  284. UserId: userId, PermId: permAId, Effect: "DENY", CreateTime: now, UpdateTime: now,
  285. })
  286. require.NoError(t, err)
  287. denyId, _ := denyRes.LastInsertId()
  288. t.Cleanup(func() {
  289. testutil.CleanTable(ctx, conn, "`sys_user_perm`", denyId)
  290. testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpAId, rpBId)
  291. testutil.CleanTable(ctx, conn, "`sys_user_role`", urId)
  292. testutil.CleanTable(ctx, conn, "`sys_perm`", permAId, permBId)
  293. testutil.CleanTable(ctx, conn, "`sys_role`", roleId)
  294. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  295. })
  296. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  297. require.NoError(t, err)
  298. assert.Equal(t, "MEMBER", memberType)
  299. permB, _ := svcCtx.SysPermModel.FindOne(ctx, permBId)
  300. assert.Equal(t, []string{permB.Code}, permsResult)
  301. }
  302. // TC-0247: ALLOW adds extra perm
  303. func TestGetUserPerms_Member_ALLOWAddsExtra(t *testing.T) {
  304. ctx := context.Background()
  305. svcCtx := newTestSvcCtx()
  306. conn := testutil.GetTestSqlConn()
  307. now := time.Now().Unix()
  308. pc := fmt.Sprintf("tp_allow_%d", rand.Intn(100000))
  309. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  310. t.Cleanup(cleanUser)
  311. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  312. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  313. })
  314. require.NoError(t, err)
  315. pmId, _ := pmRes.LastInsertId()
  316. permRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  317. ProductCode: pc, Name: "extra_p", Code: fmt.Sprintf("ex_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  318. })
  319. require.NoError(t, err)
  320. permId, _ := permRes.LastInsertId()
  321. allowRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{
  322. UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: now, UpdateTime: now,
  323. })
  324. require.NoError(t, err)
  325. allowId, _ := allowRes.LastInsertId()
  326. t.Cleanup(func() {
  327. testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowId)
  328. testutil.CleanTable(ctx, conn, "`sys_perm`", permId)
  329. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  330. })
  331. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  332. require.NoError(t, err)
  333. assert.Equal(t, "MEMBER", memberType)
  334. assert.Len(t, permsResult, 1)
  335. permObj, _ := svcCtx.SysPermModel.FindOne(ctx, permId)
  336. assert.Contains(t, permsResult, permObj.Code)
  337. }
  338. // TC-0245: cross-product role filter
  339. func TestGetUserPerms_Member_CrossProductRoleFilter(t *testing.T) {
  340. ctx := context.Background()
  341. svcCtx := newTestSvcCtx()
  342. conn := testutil.GetTestSqlConn()
  343. now := time.Now().Unix()
  344. pcTarget := fmt.Sprintf("tp_cross_t_%d", rand.Intn(100000))
  345. pcOther := fmt.Sprintf("tp_cross_o_%d", rand.Intn(100000))
  346. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  347. t.Cleanup(cleanUser)
  348. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  349. ProductCode: pcTarget, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  350. })
  351. require.NoError(t, err)
  352. pmId, _ := pmRes.LastInsertId()
  353. targetRoleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{
  354. ProductCode: pcTarget, Name: fmt.Sprintf("tr_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now,
  355. })
  356. require.NoError(t, err)
  357. targetRoleId, _ := targetRoleRes.LastInsertId()
  358. otherRoleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{
  359. ProductCode: pcOther, Name: fmt.Sprintf("or_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now,
  360. })
  361. require.NoError(t, err)
  362. otherRoleId, _ := otherRoleRes.LastInsertId()
  363. targetPermRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  364. ProductCode: pcTarget, Name: "tp", Code: fmt.Sprintf("tp_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  365. })
  366. require.NoError(t, err)
  367. targetPermId, _ := targetPermRes.LastInsertId()
  368. otherPermRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  369. ProductCode: pcOther, Name: "op", Code: fmt.Sprintf("op_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  370. })
  371. require.NoError(t, err)
  372. otherPermId, _ := otherPermRes.LastInsertId()
  373. ur1, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{UserId: userId, RoleId: targetRoleId, CreateTime: now, UpdateTime: now})
  374. require.NoError(t, err)
  375. ur1Id, _ := ur1.LastInsertId()
  376. ur2, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{UserId: userId, RoleId: otherRoleId, CreateTime: now, UpdateTime: now})
  377. require.NoError(t, err)
  378. ur2Id, _ := ur2.LastInsertId()
  379. rp1, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{RoleId: targetRoleId, PermId: targetPermId, CreateTime: now, UpdateTime: now})
  380. require.NoError(t, err)
  381. rp1Id, _ := rp1.LastInsertId()
  382. rp2, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{RoleId: otherRoleId, PermId: otherPermId, CreateTime: now, UpdateTime: now})
  383. require.NoError(t, err)
  384. rp2Id, _ := rp2.LastInsertId()
  385. t.Cleanup(func() {
  386. testutil.CleanTable(ctx, conn, "`sys_role_perm`", rp1Id, rp2Id)
  387. testutil.CleanTable(ctx, conn, "`sys_user_role`", ur1Id, ur2Id)
  388. testutil.CleanTable(ctx, conn, "`sys_perm`", targetPermId, otherPermId)
  389. testutil.CleanTable(ctx, conn, "`sys_role`", targetRoleId, otherRoleId)
  390. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  391. })
  392. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pcTarget, false)
  393. require.NoError(t, err)
  394. assert.Equal(t, "MEMBER", memberType)
  395. targetPerm, _ := svcCtx.SysPermModel.FindOne(ctx, targetPermId)
  396. assert.Equal(t, []string{targetPerm.Code}, permsResult)
  397. }
  398. // TC-0246: disabled role filtered
  399. func TestGetUserPerms_Member_DisabledRoleFiltered(t *testing.T) {
  400. ctx := context.Background()
  401. svcCtx := newTestSvcCtx()
  402. conn := testutil.GetTestSqlConn()
  403. now := time.Now().Unix()
  404. pc := fmt.Sprintf("tp_disrole_%d", rand.Intn(100000))
  405. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  406. t.Cleanup(cleanUser)
  407. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  408. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  409. })
  410. require.NoError(t, err)
  411. pmId, _ := pmRes.LastInsertId()
  412. disabledRoleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{
  413. ProductCode: pc, Name: fmt.Sprintf("dis_%d", rand.Intn(100000)), Status: 2, PermsLevel: 1, CreateTime: now, UpdateTime: now,
  414. })
  415. require.NoError(t, err)
  416. disabledRoleId, _ := disabledRoleRes.LastInsertId()
  417. permRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  418. ProductCode: pc, Name: "dp", Code: fmt.Sprintf("dp_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  419. })
  420. require.NoError(t, err)
  421. permId, _ := permRes.LastInsertId()
  422. urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{UserId: userId, RoleId: disabledRoleId, CreateTime: now, UpdateTime: now})
  423. require.NoError(t, err)
  424. urId, _ := urRes.LastInsertId()
  425. rpRes, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{RoleId: disabledRoleId, PermId: permId, CreateTime: now, UpdateTime: now})
  426. require.NoError(t, err)
  427. rpId, _ := rpRes.LastInsertId()
  428. t.Cleanup(func() {
  429. testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpId)
  430. testutil.CleanTable(ctx, conn, "`sys_user_role`", urId)
  431. testutil.CleanTable(ctx, conn, "`sys_perm`", permId)
  432. testutil.CleanTable(ctx, conn, "`sys_role`", disabledRoleId)
  433. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  434. })
  435. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  436. require.NoError(t, err)
  437. assert.Equal(t, "MEMBER", memberType)
  438. assert.Empty(t, permsResult)
  439. }
  440. // TC-0251: disabled perm filtered
  441. func TestGetUserPerms_Member_DisabledPermFiltered(t *testing.T) {
  442. ctx := context.Background()
  443. svcCtx := newTestSvcCtx()
  444. conn := testutil.GetTestSqlConn()
  445. now := time.Now().Unix()
  446. pc := fmt.Sprintf("tp_disperm_%d", rand.Intn(100000))
  447. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  448. t.Cleanup(cleanUser)
  449. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  450. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  451. })
  452. require.NoError(t, err)
  453. pmId, _ := pmRes.LastInsertId()
  454. disabledPermRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  455. ProductCode: pc, Name: "dp2", Code: fmt.Sprintf("dp2_%d", rand.Intn(100000)), Status: 2, CreateTime: now, UpdateTime: now,
  456. })
  457. require.NoError(t, err)
  458. disabledPermId, _ := disabledPermRes.LastInsertId()
  459. allowRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{
  460. UserId: userId, PermId: disabledPermId, Effect: "ALLOW", CreateTime: now, UpdateTime: now,
  461. })
  462. require.NoError(t, err)
  463. allowId, _ := allowRes.LastInsertId()
  464. t.Cleanup(func() {
  465. testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowId)
  466. testutil.CleanTable(ctx, conn, "`sys_perm`", disabledPermId)
  467. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  468. })
  469. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  470. require.NoError(t, err)
  471. assert.Equal(t, "MEMBER", memberType)
  472. assert.Empty(t, permsResult)
  473. }
  474. // TC-0249: DENY only excludes target perm
  475. func TestGetUserPerms_Member_DENYOnlyExcludesTargetPerm(t *testing.T) {
  476. ctx := context.Background()
  477. svcCtx := newTestSvcCtx()
  478. conn := testutil.GetTestSqlConn()
  479. now := time.Now().Unix()
  480. pc := fmt.Sprintf("tp_denyonly_%d", rand.Intn(100000))
  481. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  482. t.Cleanup(cleanUser)
  483. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  484. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  485. })
  486. require.NoError(t, err)
  487. pmId, _ := pmRes.LastInsertId()
  488. permARes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  489. ProductCode: pc, Name: "pA", Code: fmt.Sprintf("doA_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  490. })
  491. require.NoError(t, err)
  492. permAId, _ := permARes.LastInsertId()
  493. permBRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  494. ProductCode: pc, Name: "pB", Code: fmt.Sprintf("doB_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  495. })
  496. require.NoError(t, err)
  497. permBId, _ := permBRes.LastInsertId()
  498. allowARes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{
  499. UserId: userId, PermId: permAId, Effect: "ALLOW", CreateTime: now, UpdateTime: now,
  500. })
  501. require.NoError(t, err)
  502. allowAId, _ := allowARes.LastInsertId()
  503. denyBRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{
  504. UserId: userId, PermId: permBId, Effect: "DENY", CreateTime: now, UpdateTime: now,
  505. })
  506. require.NoError(t, err)
  507. denyBId, _ := denyBRes.LastInsertId()
  508. t.Cleanup(func() {
  509. testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowAId, denyBId)
  510. testutil.CleanTable(ctx, conn, "`sys_perm`", permAId, permBId)
  511. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  512. })
  513. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  514. require.NoError(t, err)
  515. assert.Equal(t, "MEMBER", memberType)
  516. permA, _ := svcCtx.SysPermModel.FindOne(ctx, permAId)
  517. permB, _ := svcCtx.SysPermModel.FindOne(ctx, permBId)
  518. assert.Contains(t, permsResult, permA.Code, "ALLOW perm should be present")
  519. assert.NotContains(t, permsResult, permB.Code, "DENY perm should be excluded even if it exists")
  520. }
  521. // TC-0250: ALLOW + role dedup
  522. func TestGetUserPerms_Member_ALLOWAndRoleDedup(t *testing.T) {
  523. ctx := context.Background()
  524. svcCtx := newTestSvcCtx()
  525. conn := testutil.GetTestSqlConn()
  526. now := time.Now().Unix()
  527. pc := fmt.Sprintf("tp_dedup_%d", rand.Intn(100000))
  528. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0)
  529. t.Cleanup(cleanUser)
  530. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  531. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  532. })
  533. require.NoError(t, err)
  534. pmId, _ := pmRes.LastInsertId()
  535. roleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{
  536. ProductCode: pc, Name: fmt.Sprintf("dedup_r_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now,
  537. })
  538. require.NoError(t, err)
  539. roleId, _ := roleRes.LastInsertId()
  540. permRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  541. ProductCode: pc, Name: "dedup_p", Code: fmt.Sprintf("dd_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  542. })
  543. require.NoError(t, err)
  544. permId, _ := permRes.LastInsertId()
  545. urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{
  546. UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now,
  547. })
  548. require.NoError(t, err)
  549. urId, _ := urRes.LastInsertId()
  550. rpRes, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{
  551. RoleId: roleId, PermId: permId, CreateTime: now, UpdateTime: now,
  552. })
  553. require.NoError(t, err)
  554. rpId, _ := rpRes.LastInsertId()
  555. allowRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{
  556. UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: now, UpdateTime: now,
  557. })
  558. require.NoError(t, err)
  559. allowId, _ := allowRes.LastInsertId()
  560. t.Cleanup(func() {
  561. testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowId)
  562. testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpId)
  563. testutil.CleanTable(ctx, conn, "`sys_user_role`", urId)
  564. testutil.CleanTable(ctx, conn, "`sys_perm`", permId)
  565. testutil.CleanTable(ctx, conn, "`sys_role`", roleId)
  566. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  567. })
  568. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false)
  569. require.NoError(t, err)
  570. assert.Equal(t, "MEMBER", memberType)
  571. permObj, _ := svcCtx.SysPermModel.FindOne(ctx, permId)
  572. assert.Len(t, permsResult, 1, "role perm and ALLOW same perm should be deduped")
  573. assert.Equal(t, permObj.Code, permsResult[0])
  574. }
  575. // TC-0238: DEV dept member gets all perms
  576. func TestGetUserPerms_Member_DevDept_AllPerms(t *testing.T) {
  577. ctx := context.Background()
  578. svcCtx := newTestSvcCtx()
  579. conn := testutil.GetTestSqlConn()
  580. now := time.Now().Unix()
  581. pc := fmt.Sprintf("tp_devdept_%d", rand.Intn(100000))
  582. deptRes, err := svcCtx.SysDeptModel.Insert(ctx, &deptModel.SysDept{
  583. ParentId: 0, Name: "dev_dept_" + fmt.Sprintf("%d", rand.Intn(100000)),
  584. Path: "/", Sort: 1, DeptType: "DEV", Status: 1, CreateTime: now, UpdateTime: now,
  585. })
  586. require.NoError(t, err)
  587. deptId, _ := deptRes.LastInsertId()
  588. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, deptId)
  589. t.Cleanup(cleanUser)
  590. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  591. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  592. })
  593. require.NoError(t, err)
  594. pmId, _ := pmRes.LastInsertId()
  595. p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  596. ProductCode: pc, Name: "dp1", Code: fmt.Sprintf("dc1_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  597. })
  598. require.NoError(t, err)
  599. p1Id, _ := p1Res.LastInsertId()
  600. p2Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  601. ProductCode: pc, Name: "dp2", Code: fmt.Sprintf("dc2_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  602. })
  603. require.NoError(t, err)
  604. p2Id, _ := p2Res.LastInsertId()
  605. t.Cleanup(func() {
  606. testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id, p2Id)
  607. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  608. testutil.CleanTable(ctx, conn, "`sys_dept`", deptId)
  609. })
  610. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, deptId, pc, false)
  611. require.NoError(t, err)
  612. assert.Equal(t, "MEMBER", memberType)
  613. p1, _ := svcCtx.SysPermModel.FindOne(ctx, p1Id)
  614. p2, _ := svcCtx.SysPermModel.FindOne(ctx, p2Id)
  615. assert.ElementsMatch(t, []string{p1.Code, p2.Code}, permsResult)
  616. }
  617. // TC-0240: NORMAL dept member no auto perms
  618. func TestGetUserPerms_Member_NormalDept_NoAutoPerms(t *testing.T) {
  619. ctx := context.Background()
  620. svcCtx := newTestSvcCtx()
  621. conn := testutil.GetTestSqlConn()
  622. now := time.Now().Unix()
  623. pc := fmt.Sprintf("tp_normdept_%d", rand.Intn(100000))
  624. deptRes, err := svcCtx.SysDeptModel.Insert(ctx, &deptModel.SysDept{
  625. ParentId: 0, Name: "normal_dept_" + fmt.Sprintf("%d", rand.Intn(100000)),
  626. Path: "/", Sort: 1, DeptType: "NORMAL", Status: 1, CreateTime: now, UpdateTime: now,
  627. })
  628. require.NoError(t, err)
  629. deptId, _ := deptRes.LastInsertId()
  630. userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, deptId)
  631. t.Cleanup(cleanUser)
  632. pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{
  633. ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now,
  634. })
  635. require.NoError(t, err)
  636. pmId, _ := pmRes.LastInsertId()
  637. p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{
  638. ProductCode: pc, Name: "np1", Code: fmt.Sprintf("nc1_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now,
  639. })
  640. require.NoError(t, err)
  641. p1Id, _ := p1Res.LastInsertId()
  642. t.Cleanup(func() {
  643. testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id)
  644. testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId)
  645. testutil.CleanTable(ctx, conn, "`sys_dept`", deptId)
  646. })
  647. permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, deptId, pc, false)
  648. require.NoError(t, err)
  649. assert.Equal(t, "MEMBER", memberType)
  650. assert.Empty(t, permsResult)
  651. }
  652. // suppress unused import
  653. var _ = sqlx.ErrNotFound