package auth import ( "context" "database/sql" "fmt" "math/rand" "testing" "time" deptModel "perms-system-server/internal/model/dept" "perms-system-server/internal/model/perm" "perms-system-server/internal/model/productmember" "perms-system-server/internal/model/role" "perms-system-server/internal/model/roleperm" userModel "perms-system-server/internal/model/user" "perms-system-server/internal/model/userperm" "perms-system-server/internal/model/userrole" "perms-system-server/internal/svc" "perms-system-server/internal/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zeromicro/go-zero/core/stores/sqlx" ) func newTestSvcCtx() *svc.ServiceContext { c := testutil.GetTestConfig() return svc.NewServiceContext(c) } func createPermsTestUser(t *testing.T, ctx context.Context, svcCtx *svc.ServiceContext, isSuperAdmin int64, deptId int64) (int64, func()) { t.Helper() conn := testutil.GetTestSqlConn() now := time.Now().Unix() username := fmt.Sprintf("perms_u_%d", rand.Intn(1000000)) res, err := svcCtx.SysUserModel.Insert(ctx, &userModel.SysUser{ Username: username, Password: testutil.HashPassword("pass123"), Nickname: username, Avatar: sql.NullString{}, DeptId: deptId, IsSuperAdmin: isSuperAdmin, MustChangePassword: 2, Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) id, _ := res.LastInsertId() return id, func() { testutil.CleanTable(ctx, conn, "`sys_user`", id) } } // TC-0231: superAdmin gets all enabled perms func TestGetUserPerms_SuperAdmin(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 1, 0) t.Cleanup(cleanUser) p1, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "sa_perm1", Code: "sa_code1", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p1Id, _ := p1.LastInsertId() p2, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "sa_perm2", Code: "sa_code2", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p2Id, _ := p2.LastInsertId() p3, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "sa_disabled", Code: "sa_code3", Status: 2, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p3Id, _ := p3.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id, p2Id, p3Id) }) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, true) require.NoError(t, err) assert.Equal(t, "SUPER_ADMIN", memberType) assert.ElementsMatch(t, []string{"sa_code1", "sa_code2"}, perms) } // TC-0232: superAdmin with empty product func TestGetUserPerms_SuperAdmin_EmptyProduct(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 1, 0) t.Cleanup(cleanUser) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, "nonexist_product_xyz", true) require.NoError(t, err) assert.Equal(t, "SUPER_ADMIN", memberType) assert.Empty(t, perms) } // TC-0233: non product member func TestGetUserPerms_NotProductMember(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, "some_product", false) require.NoError(t, err) assert.Empty(t, memberType) assert.Nil(t, perms) } // TC-0235: DEVELOPER member func TestGetUserPerms_Developer(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_dev_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "DEVELOPER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "dev_p1", Code: "dev_c1", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p1Id, _ := p1Res.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id) }) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "DEVELOPER", memberType) assert.Contains(t, perms, "dev_c1") } // TC-0236: ADMIN member func TestGetUserPerms_Admin(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_adm_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "ADMIN", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "adm_p1", Code: "adm_c1", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p1Id, _ := p1Res.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id) }) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "ADMIN", memberType) assert.Contains(t, perms, "adm_c1") } // TC-0243: MEMBER no roles no user perms func TestGetUserPerms_Member_NoRolesNoUserPerms(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_mbr0_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) assert.Empty(t, perms) } // TC-0244: MEMBER with roles func TestGetUserPerms_Member_WithRoles(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_mbrr_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() roleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{ ProductCode: pc, Name: fmt.Sprintf("role_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) roleId, _ := roleRes.LastInsertId() perm1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "role_perm1", Code: fmt.Sprintf("rc1_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) perm1Id, _ := perm1Res.LastInsertId() perm2Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "role_perm2", Code: fmt.Sprintf("rc2_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) perm2Id, _ := perm2Res.LastInsertId() urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{ UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) urId, _ := urRes.LastInsertId() rpRes1, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{ RoleId: roleId, PermId: perm1Id, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) rpId1, _ := rpRes1.LastInsertId() rpRes2, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{ RoleId: roleId, PermId: perm2Id, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) rpId2, _ := rpRes2.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpId1, rpId2) testutil.CleanTable(ctx, conn, "`sys_user_role`", urId) testutil.CleanTable(ctx, conn, "`sys_perm`", perm1Id, perm2Id) testutil.CleanTable(ctx, conn, "`sys_role`", roleId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) perms, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) assert.Len(t, perms, 2) p1, _ := svcCtx.SysPermModel.FindOne(ctx, perm1Id) p2, _ := svcCtx.SysPermModel.FindOne(ctx, perm2Id) assert.ElementsMatch(t, []string{p1.Code, p2.Code}, perms) } // TC-0248: DENY overrides role perm func TestGetUserPerms_Member_DENYOverridesRolePerm(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_deny_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() roleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{ ProductCode: pc, Name: fmt.Sprintf("role_deny_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) roleId, _ := roleRes.LastInsertId() permARes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "pA", Code: fmt.Sprintf("pA_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permAId, _ := permARes.LastInsertId() permBRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "pB", Code: fmt.Sprintf("pB_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permBId, _ := permBRes.LastInsertId() urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{ UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) urId, _ := urRes.LastInsertId() rpA, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{ RoleId: roleId, PermId: permAId, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) rpAId, _ := rpA.LastInsertId() rpB, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{ RoleId: roleId, PermId: permBId, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) rpBId, _ := rpB.LastInsertId() denyRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{ UserId: userId, PermId: permAId, Effect: "DENY", CreateTime: now, UpdateTime: now, }) require.NoError(t, err) denyId, _ := denyRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user_perm`", denyId) testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpAId, rpBId) testutil.CleanTable(ctx, conn, "`sys_user_role`", urId) testutil.CleanTable(ctx, conn, "`sys_perm`", permAId, permBId) testutil.CleanTable(ctx, conn, "`sys_role`", roleId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) permB, _ := svcCtx.SysPermModel.FindOne(ctx, permBId) assert.Equal(t, []string{permB.Code}, permsResult) } // TC-0247: ALLOW adds extra perm func TestGetUserPerms_Member_ALLOWAddsExtra(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_allow_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() permRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "extra_p", Code: fmt.Sprintf("ex_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permId, _ := permRes.LastInsertId() allowRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{ UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: now, UpdateTime: now, }) require.NoError(t, err) allowId, _ := allowRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowId) testutil.CleanTable(ctx, conn, "`sys_perm`", permId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) assert.Len(t, permsResult, 1) permObj, _ := svcCtx.SysPermModel.FindOne(ctx, permId) assert.Contains(t, permsResult, permObj.Code) } // TC-0245: cross-product role filter func TestGetUserPerms_Member_CrossProductRoleFilter(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pcTarget := fmt.Sprintf("tp_cross_t_%d", rand.Intn(100000)) pcOther := fmt.Sprintf("tp_cross_o_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pcTarget, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() targetRoleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{ ProductCode: pcTarget, Name: fmt.Sprintf("tr_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) targetRoleId, _ := targetRoleRes.LastInsertId() otherRoleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{ ProductCode: pcOther, Name: fmt.Sprintf("or_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) otherRoleId, _ := otherRoleRes.LastInsertId() targetPermRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pcTarget, Name: "tp", Code: fmt.Sprintf("tp_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) targetPermId, _ := targetPermRes.LastInsertId() otherPermRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pcOther, Name: "op", Code: fmt.Sprintf("op_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) otherPermId, _ := otherPermRes.LastInsertId() ur1, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{UserId: userId, RoleId: targetRoleId, CreateTime: now, UpdateTime: now}) require.NoError(t, err) ur1Id, _ := ur1.LastInsertId() ur2, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{UserId: userId, RoleId: otherRoleId, CreateTime: now, UpdateTime: now}) require.NoError(t, err) ur2Id, _ := ur2.LastInsertId() rp1, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{RoleId: targetRoleId, PermId: targetPermId, CreateTime: now, UpdateTime: now}) require.NoError(t, err) rp1Id, _ := rp1.LastInsertId() rp2, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{RoleId: otherRoleId, PermId: otherPermId, CreateTime: now, UpdateTime: now}) require.NoError(t, err) rp2Id, _ := rp2.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_role_perm`", rp1Id, rp2Id) testutil.CleanTable(ctx, conn, "`sys_user_role`", ur1Id, ur2Id) testutil.CleanTable(ctx, conn, "`sys_perm`", targetPermId, otherPermId) testutil.CleanTable(ctx, conn, "`sys_role`", targetRoleId, otherRoleId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pcTarget, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) targetPerm, _ := svcCtx.SysPermModel.FindOne(ctx, targetPermId) assert.Equal(t, []string{targetPerm.Code}, permsResult) } // TC-0246: disabled role filtered func TestGetUserPerms_Member_DisabledRoleFiltered(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_disrole_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() disabledRoleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{ ProductCode: pc, Name: fmt.Sprintf("dis_%d", rand.Intn(100000)), Status: 2, PermsLevel: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) disabledRoleId, _ := disabledRoleRes.LastInsertId() permRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "dp", Code: fmt.Sprintf("dp_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permId, _ := permRes.LastInsertId() urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{UserId: userId, RoleId: disabledRoleId, CreateTime: now, UpdateTime: now}) require.NoError(t, err) urId, _ := urRes.LastInsertId() rpRes, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{RoleId: disabledRoleId, PermId: permId, CreateTime: now, UpdateTime: now}) require.NoError(t, err) rpId, _ := rpRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpId) testutil.CleanTable(ctx, conn, "`sys_user_role`", urId) testutil.CleanTable(ctx, conn, "`sys_perm`", permId) testutil.CleanTable(ctx, conn, "`sys_role`", disabledRoleId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) assert.Empty(t, permsResult) } // TC-0251: disabled perm filtered func TestGetUserPerms_Member_DisabledPermFiltered(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_disperm_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() disabledPermRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "dp2", Code: fmt.Sprintf("dp2_%d", rand.Intn(100000)), Status: 2, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) disabledPermId, _ := disabledPermRes.LastInsertId() allowRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{ UserId: userId, PermId: disabledPermId, Effect: "ALLOW", CreateTime: now, UpdateTime: now, }) require.NoError(t, err) allowId, _ := allowRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowId) testutil.CleanTable(ctx, conn, "`sys_perm`", disabledPermId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) assert.Empty(t, permsResult) } // TC-0249: DENY only excludes target perm func TestGetUserPerms_Member_DENYOnlyExcludesTargetPerm(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_denyonly_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() permARes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "pA", Code: fmt.Sprintf("doA_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permAId, _ := permARes.LastInsertId() permBRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "pB", Code: fmt.Sprintf("doB_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permBId, _ := permBRes.LastInsertId() allowARes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{ UserId: userId, PermId: permAId, Effect: "ALLOW", CreateTime: now, UpdateTime: now, }) require.NoError(t, err) allowAId, _ := allowARes.LastInsertId() denyBRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{ UserId: userId, PermId: permBId, Effect: "DENY", CreateTime: now, UpdateTime: now, }) require.NoError(t, err) denyBId, _ := denyBRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowAId, denyBId) testutil.CleanTable(ctx, conn, "`sys_perm`", permAId, permBId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) permA, _ := svcCtx.SysPermModel.FindOne(ctx, permAId) permB, _ := svcCtx.SysPermModel.FindOne(ctx, permBId) assert.Contains(t, permsResult, permA.Code, "ALLOW perm should be present") assert.NotContains(t, permsResult, permB.Code, "DENY perm should be excluded even if it exists") } // TC-0250: ALLOW + role dedup func TestGetUserPerms_Member_ALLOWAndRoleDedup(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_dedup_%d", rand.Intn(100000)) userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, 0) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() roleRes, err := svcCtx.SysRoleModel.Insert(ctx, &role.SysRole{ ProductCode: pc, Name: fmt.Sprintf("dedup_r_%d", rand.Intn(100000)), Status: 1, PermsLevel: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) roleId, _ := roleRes.LastInsertId() permRes, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "dedup_p", Code: fmt.Sprintf("dd_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) permId, _ := permRes.LastInsertId() urRes, err := svcCtx.SysUserRoleModel.Insert(ctx, &userrole.SysUserRole{ UserId: userId, RoleId: roleId, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) urId, _ := urRes.LastInsertId() rpRes, err := svcCtx.SysRolePermModel.Insert(ctx, &roleperm.SysRolePerm{ RoleId: roleId, PermId: permId, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) rpId, _ := rpRes.LastInsertId() allowRes, err := svcCtx.SysUserPermModel.Insert(ctx, &userperm.SysUserPerm{ UserId: userId, PermId: permId, Effect: "ALLOW", CreateTime: now, UpdateTime: now, }) require.NoError(t, err) allowId, _ := allowRes.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_user_perm`", allowId) testutil.CleanTable(ctx, conn, "`sys_role_perm`", rpId) testutil.CleanTable(ctx, conn, "`sys_user_role`", urId) testutil.CleanTable(ctx, conn, "`sys_perm`", permId) testutil.CleanTable(ctx, conn, "`sys_role`", roleId) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, 0, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) permObj, _ := svcCtx.SysPermModel.FindOne(ctx, permId) assert.Len(t, permsResult, 1, "role perm and ALLOW same perm should be deduped") assert.Equal(t, permObj.Code, permsResult[0]) } // TC-0238: DEV dept member gets all perms func TestGetUserPerms_Member_DevDept_AllPerms(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_devdept_%d", rand.Intn(100000)) deptRes, err := svcCtx.SysDeptModel.Insert(ctx, &deptModel.SysDept{ ParentId: 0, Name: "dev_dept_" + fmt.Sprintf("%d", rand.Intn(100000)), Path: "/", Sort: 1, DeptType: "DEV", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) deptId, _ := deptRes.LastInsertId() userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, deptId) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "dp1", Code: fmt.Sprintf("dc1_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p1Id, _ := p1Res.LastInsertId() p2Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "dp2", Code: fmt.Sprintf("dc2_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p2Id, _ := p2Res.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id, p2Id) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) testutil.CleanTable(ctx, conn, "`sys_dept`", deptId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, deptId, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) p1, _ := svcCtx.SysPermModel.FindOne(ctx, p1Id) p2, _ := svcCtx.SysPermModel.FindOne(ctx, p2Id) assert.ElementsMatch(t, []string{p1.Code, p2.Code}, permsResult) } // TC-0240: NORMAL dept member no auto perms func TestGetUserPerms_Member_NormalDept_NoAutoPerms(t *testing.T) { ctx := context.Background() svcCtx := newTestSvcCtx() conn := testutil.GetTestSqlConn() now := time.Now().Unix() pc := fmt.Sprintf("tp_normdept_%d", rand.Intn(100000)) deptRes, err := svcCtx.SysDeptModel.Insert(ctx, &deptModel.SysDept{ ParentId: 0, Name: "normal_dept_" + fmt.Sprintf("%d", rand.Intn(100000)), Path: "/", Sort: 1, DeptType: "NORMAL", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) deptId, _ := deptRes.LastInsertId() userId, cleanUser := createPermsTestUser(t, ctx, svcCtx, 2, deptId) t.Cleanup(cleanUser) pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmember.SysProductMember{ ProductCode: pc, UserId: userId, MemberType: "MEMBER", Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) pmId, _ := pmRes.LastInsertId() p1Res, err := svcCtx.SysPermModel.Insert(ctx, &perm.SysPerm{ ProductCode: pc, Name: "np1", Code: fmt.Sprintf("nc1_%d", rand.Intn(100000)), Status: 1, CreateTime: now, UpdateTime: now, }) require.NoError(t, err) p1Id, _ := p1Res.LastInsertId() t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", p1Id) testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) testutil.CleanTable(ctx, conn, "`sys_dept`", deptId) }) permsResult, memberType, err := GetUserPerms(ctx, svcCtx, userId, deptId, pc, false) require.NoError(t, err) assert.Equal(t, "MEMBER", memberType) assert.Empty(t, permsResult) } // suppress unused import var _ = sqlx.ErrNotFound