| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- package pub
- import (
- "context"
- "database/sql"
- "errors"
- "testing"
- "time"
- authHelper "perms-system-server/internal/logic/auth"
- permModel "perms-system-server/internal/model/perm"
- productmemberModel "perms-system-server/internal/model/productmember"
- userModel "perms-system-server/internal/model/user"
- "perms-system-server/internal/response"
- "perms-system-server/internal/testutil"
- "perms-system-server/internal/types"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- )
- func insertRefreshTestUser(t *testing.T, ctx context.Context, username, password string, status, isSuperAdmin int64) (int64, func()) {
- t.Helper()
- svcCtx := newTestSvcCtx()
- conn := testutil.GetTestSqlConn()
- now := time.Now().Unix()
- hashed := testutil.HashPassword(password)
- res, err := svcCtx.SysUserModel.Insert(ctx, &userModel.SysUser{
- Username: username,
- Password: hashed,
- Nickname: username,
- Avatar: sql.NullString{},
- Email: username + "@test.com",
- Phone: "13800000000",
- Remark: "",
- DeptId: 0,
- IsSuperAdmin: isSuperAdmin,
- MustChangePassword: 2,
- Status: status,
- CreateTime: now,
- UpdateTime: now,
- })
- require.NoError(t, err)
- id, _ := res.LastInsertId()
- cleanup := func() {
- testutil.CleanTable(ctx, conn, "`sys_user`", id)
- }
- return id, cleanup
- }
- // TC-0013: 正常刷新(refreshToken从header获取,原样返回不重新生成)
- func TestRefreshToken_Normal(t *testing.T) {
- ctx := context.Background()
- svcCtx := newTestSvcCtx()
- username := testutil.UniqueId()
- password := "TestPass123"
- userId, cleanUser := insertRefreshTestUser(t, ctx, username, password, 1, 2)
- t.Cleanup(cleanUser)
- refreshToken, err := authHelper.GenerateRefreshToken(
- svcCtx.Config.Auth.RefreshSecret,
- svcCtx.Config.Auth.RefreshExpire,
- userId, "",
- )
- require.NoError(t, err)
- logic := NewRefreshTokenLogic(ctx, svcCtx)
- resp, err := logic.RefreshToken(&types.RefreshTokenReq{
- Authorization: "Bearer " + refreshToken,
- })
- require.NoError(t, err)
- require.NotNil(t, resp)
- assert.NotEmpty(t, resp.AccessToken)
- assert.Equal(t, refreshToken, resp.RefreshToken, "refreshToken应原样返回,不重新生成")
- assert.NotEqual(t, resp.AccessToken, resp.RefreshToken, "accessToken和refreshToken应不同")
- assert.True(t, resp.Expires > time.Now().Unix(), "expires应为未来的unix时间戳")
- assert.Equal(t, userId, resp.UserInfo.UserId)
- assert.Equal(t, username, resp.UserInfo.Username)
- }
- // TC-0014: 不带productCode(回退)
- func TestRefreshToken_FallbackToClaimsProductCode(t *testing.T) {
- ctx := context.Background()
- svcCtx := newTestSvcCtx()
- conn := testutil.GetTestSqlConn()
- username := testutil.UniqueId()
- password := "TestPass123"
- pc := testutil.UniqueId()
- now := time.Now().Unix()
- userId, cleanUser := insertRefreshTestUser(t, ctx, username, password, 1, 2)
- t.Cleanup(cleanUser)
- _, cleanProduct := insertTestProduct(t, ctx, svcCtx, pc, testutil.UniqueId(), "secret")
- t.Cleanup(cleanProduct)
- pmRes, err := svcCtx.SysProductMemberModel.Insert(ctx, &productmemberModel.SysProductMember{
- ProductCode: pc, UserId: userId, MemberType: "ADMIN", Status: 1, CreateTime: now, UpdateTime: now,
- })
- require.NoError(t, err)
- pmId, _ := pmRes.LastInsertId()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_product_member`", pmId) })
- permCode := testutil.UniqueId()
- permRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
- ProductCode: pc, Name: "refresh_perm", Code: permCode, Status: 1, CreateTime: now, UpdateTime: now,
- })
- require.NoError(t, err)
- permId, _ := permRes.LastInsertId()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", permId) })
- refreshToken, err := authHelper.GenerateRefreshToken(
- svcCtx.Config.Auth.RefreshSecret,
- svcCtx.Config.Auth.RefreshExpire,
- userId, pc,
- )
- require.NoError(t, err)
- logic := NewRefreshTokenLogic(ctx, svcCtx)
- resp, err := logic.RefreshToken(&types.RefreshTokenReq{
- Authorization: "Bearer " + refreshToken,
- })
- require.NoError(t, err)
- require.NotNil(t, resp)
- assert.Equal(t, "ADMIN", resp.UserInfo.MemberType)
- assert.Contains(t, resp.UserInfo.Perms, permCode)
- }
- // TC-0015: token无效
- func TestRefreshToken_InvalidToken(t *testing.T) {
- ctx := context.Background()
- svcCtx := newTestSvcCtx()
- logic := NewRefreshTokenLogic(ctx, svcCtx)
- resp, err := logic.RefreshToken(&types.RefreshTokenReq{
- Authorization: "Bearer invalid.token.string",
- })
- require.Nil(t, resp)
- require.Error(t, err)
- var codeErr *response.CodeError
- require.True(t, errors.As(err, &codeErr))
- assert.Equal(t, 401, codeErr.Code())
- assert.Equal(t, "refreshToken无效或已过期", codeErr.Error())
- }
- // TC-0016: 用户已删除(UserDetailsLoader 返回 Status=0 → 403 账号已被冻结)
- func TestRefreshToken_UserDeleted(t *testing.T) {
- ctx := context.Background()
- svcCtx := newTestSvcCtx()
- nonExistentUserId := int64(999999999)
- refreshToken, err := authHelper.GenerateRefreshToken(
- svcCtx.Config.Auth.RefreshSecret,
- svcCtx.Config.Auth.RefreshExpire,
- nonExistentUserId, "",
- )
- require.NoError(t, err)
- logic := NewRefreshTokenLogic(ctx, svcCtx)
- resp, err := logic.RefreshToken(&types.RefreshTokenReq{
- Authorization: "Bearer " + refreshToken,
- })
- require.Nil(t, resp)
- require.Error(t, err)
- var codeErr *response.CodeError
- require.True(t, errors.As(err, &codeErr))
- assert.Equal(t, 403, codeErr.Code())
- assert.Equal(t, "账号已被冻结", codeErr.Error())
- }
- // TC-0017: 账号冻结
- func TestRefreshToken_AccountFrozen(t *testing.T) {
- ctx := context.Background()
- svcCtx := newTestSvcCtx()
- username := testutil.UniqueId()
- password := "TestPass123"
- userId, cleanUser := insertRefreshTestUser(t, ctx, username, password, 2, 2)
- t.Cleanup(cleanUser)
- refreshToken, err := authHelper.GenerateRefreshToken(
- svcCtx.Config.Auth.RefreshSecret,
- svcCtx.Config.Auth.RefreshExpire,
- userId, "",
- )
- require.NoError(t, err)
- logic := NewRefreshTokenLogic(ctx, svcCtx)
- resp, err := logic.RefreshToken(&types.RefreshTokenReq{
- Authorization: "Bearer " + refreshToken,
- })
- require.Nil(t, resp)
- require.Error(t, err)
- var codeErr *response.CodeError
- require.True(t, errors.As(err, &codeErr))
- assert.Equal(t, 403, codeErr.Code())
- assert.Equal(t, "账号已被冻结", codeErr.Error())
- }
- // TC-0018: 超管+productCode(refreshToken原样返回)
- func TestRefreshToken_SuperAdminWithProductCode(t *testing.T) {
- ctx := context.Background()
- svcCtx := newTestSvcCtx()
- conn := testutil.GetTestSqlConn()
- username := testutil.UniqueId()
- password := "TestPass123"
- pc := testutil.UniqueId()
- now := time.Now().Unix()
- userId, cleanUser := insertRefreshTestUser(t, ctx, username, password, 1, 1)
- t.Cleanup(cleanUser)
- _, cleanProduct := insertTestProduct(t, ctx, svcCtx, pc, testutil.UniqueId(), "secret")
- t.Cleanup(cleanProduct)
- permCode := testutil.UniqueId()
- permRes, err := svcCtx.SysPermModel.Insert(ctx, &permModel.SysPerm{
- ProductCode: pc, Name: "sa_refresh_perm", Code: permCode, Status: 1, CreateTime: now, UpdateTime: now,
- })
- require.NoError(t, err)
- permId, _ := permRes.LastInsertId()
- t.Cleanup(func() { testutil.CleanTable(ctx, conn, "`sys_perm`", permId) })
- refreshToken, err := authHelper.GenerateRefreshToken(
- svcCtx.Config.Auth.RefreshSecret,
- svcCtx.Config.Auth.RefreshExpire,
- userId, "",
- )
- require.NoError(t, err)
- logic := NewRefreshTokenLogic(ctx, svcCtx)
- resp, err := logic.RefreshToken(&types.RefreshTokenReq{
- Authorization: "Bearer " + refreshToken,
- ProductCode: pc,
- })
- require.NoError(t, err)
- require.NotNil(t, resp)
- assert.Equal(t, refreshToken, resp.RefreshToken, "refreshToken应原样返回,不重新生成")
- assert.Equal(t, "SUPER_ADMIN", resp.UserInfo.MemberType)
- assert.Contains(t, resp.UserInfo.Perms, permCode)
- assert.Equal(t, int64(1), resp.UserInfo.IsSuperAdmin)
- }
|