adminLoginLogic_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package pub
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "time"
  7. "perms-system-server/internal/response"
  8. "perms-system-server/internal/testutil"
  9. "perms-system-server/internal/types"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/require"
  12. )
  13. // TC-0015: 超管正常登录(管理后台)
  14. func TestAdminLogin_SuperAdmin(t *testing.T) {
  15. ctx := context.Background()
  16. svcCtx := newTestSvcCtx()
  17. username := testutil.UniqueId()
  18. password := "TestPass123"
  19. _, cleanUser := insertTestUser(t, ctx, svcCtx, username, password, 1, 1)
  20. t.Cleanup(cleanUser)
  21. logic := NewAdminLoginLogic(ctx, svcCtx)
  22. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  23. Username: username,
  24. Password: password,
  25. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  26. })
  27. require.NoError(t, err)
  28. require.NotNil(t, resp)
  29. assert.NotEmpty(t, resp.AccessToken)
  30. assert.NotEmpty(t, resp.RefreshToken)
  31. assert.True(t, resp.Expires > time.Now().Unix(), "expires应为未来的unix时间戳")
  32. assert.Equal(t, username, resp.UserInfo.Username)
  33. assert.Equal(t, int64(1), resp.UserInfo.IsSuperAdmin)
  34. assert.Nil(t, resp.UserInfo.Perms)
  35. assert.Equal(t, "SUPER_ADMIN", resp.UserInfo.MemberType)
  36. }
  37. // TC-0016: 普通用户被拒绝(审计H1修复: 仅超管可通过管理后台登录)
  38. func TestAdminLogin_NormalUserRejected(t *testing.T) {
  39. ctx := context.Background()
  40. svcCtx := newTestSvcCtx()
  41. username := testutil.UniqueId()
  42. password := "TestPass123"
  43. _, cleanUser := insertTestUser(t, ctx, svcCtx, username, password, 1, 2)
  44. t.Cleanup(cleanUser)
  45. logic := NewAdminLoginLogic(ctx, svcCtx)
  46. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  47. Username: username,
  48. Password: password,
  49. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  50. })
  51. require.Nil(t, resp)
  52. require.Error(t, err)
  53. var codeErr *response.CodeError
  54. require.True(t, errors.As(err, &codeErr))
  55. assert.Equal(t, 403, codeErr.Code())
  56. assert.Equal(t, "仅超级管理员可通过管理后台登录", codeErr.Error())
  57. }
  58. // TC-0017: managementKey无效
  59. func TestAdminLogin_InvalidManagementKey(t *testing.T) {
  60. ctx := context.Background()
  61. svcCtx := newTestSvcCtx()
  62. logic := NewAdminLoginLogic(ctx, svcCtx)
  63. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  64. Username: "anyone",
  65. Password: "pass",
  66. ManagementKey: "wrong-key",
  67. })
  68. require.Nil(t, resp)
  69. require.Error(t, err)
  70. var codeErr *response.CodeError
  71. require.True(t, errors.As(err, &codeErr))
  72. assert.Equal(t, 401, codeErr.Code())
  73. assert.Equal(t, "managementKey无效", codeErr.Error())
  74. }
  75. // TC-0018: managementKey为空
  76. func TestAdminLogin_EmptyManagementKey(t *testing.T) {
  77. ctx := context.Background()
  78. svcCtx := newTestSvcCtx()
  79. logic := NewAdminLoginLogic(ctx, svcCtx)
  80. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  81. Username: "anyone",
  82. Password: "pass",
  83. ManagementKey: "",
  84. })
  85. require.Nil(t, resp)
  86. require.Error(t, err)
  87. var codeErr *response.CodeError
  88. require.True(t, errors.As(err, &codeErr))
  89. assert.Equal(t, 401, codeErr.Code())
  90. assert.Equal(t, "managementKey无效", codeErr.Error())
  91. }
  92. // TC-0019: 用户不存在
  93. func TestAdminLogin_UserNotFound(t *testing.T) {
  94. ctx := context.Background()
  95. svcCtx := newTestSvcCtx()
  96. logic := NewAdminLoginLogic(ctx, svcCtx)
  97. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  98. Username: "nonexistent_" + testutil.UniqueId(),
  99. Password: "whatever",
  100. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  101. })
  102. require.Nil(t, resp)
  103. require.Error(t, err)
  104. var codeErr *response.CodeError
  105. require.True(t, errors.As(err, &codeErr))
  106. assert.Equal(t, 401, codeErr.Code())
  107. assert.Equal(t, "用户名或密码错误", codeErr.Error())
  108. }
  109. // TC-0020: 密码错误
  110. func TestAdminLogin_WrongPassword(t *testing.T) {
  111. ctx := context.Background()
  112. svcCtx := newTestSvcCtx()
  113. username := testutil.UniqueId()
  114. _, cleanUser := insertTestUser(t, ctx, svcCtx, username, "CorrectPass", 1, 2)
  115. t.Cleanup(cleanUser)
  116. logic := NewAdminLoginLogic(ctx, svcCtx)
  117. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  118. Username: username,
  119. Password: "WrongPass",
  120. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  121. })
  122. require.Nil(t, resp)
  123. require.Error(t, err)
  124. var codeErr *response.CodeError
  125. require.True(t, errors.As(err, &codeErr))
  126. assert.Equal(t, 401, codeErr.Code())
  127. assert.Equal(t, "用户名或密码错误", codeErr.Error())
  128. }
  129. // TC-0021: 账号冻结
  130. func TestAdminLogin_AccountFrozen(t *testing.T) {
  131. ctx := context.Background()
  132. svcCtx := newTestSvcCtx()
  133. username := testutil.UniqueId()
  134. password := "TestPass123"
  135. _, cleanUser := insertTestUser(t, ctx, svcCtx, username, password, 2, 2)
  136. t.Cleanup(cleanUser)
  137. logic := NewAdminLoginLogic(ctx, svcCtx)
  138. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  139. Username: username,
  140. Password: password,
  141. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  142. })
  143. require.Nil(t, resp)
  144. require.Error(t, err)
  145. var codeErr *response.CodeError
  146. require.True(t, errors.As(err, &codeErr))
  147. assert.Equal(t, 403, codeErr.Code())
  148. assert.Equal(t, "账号已被冻结", codeErr.Error())
  149. }
  150. // TC-0022: 不带productCode时token无权限(perms为空)
  151. func TestAdminLogin_NoPermsWithoutProductCode(t *testing.T) {
  152. ctx := context.Background()
  153. svcCtx := newTestSvcCtx()
  154. username := testutil.UniqueId()
  155. password := "TestPass123"
  156. _, cleanUser := insertTestUser(t, ctx, svcCtx, username, password, 1, 1)
  157. t.Cleanup(cleanUser)
  158. logic := NewAdminLoginLogic(ctx, svcCtx)
  159. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  160. Username: username,
  161. Password: password,
  162. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  163. })
  164. require.NoError(t, err)
  165. require.NotNil(t, resp)
  166. assert.Nil(t, resp.UserInfo.Perms, "管理后台不传productCode,不应加载权限列表")
  167. assert.Equal(t, "SUPER_ADMIN", resp.UserInfo.MemberType, "超管即使不传productCode也会被标记SUPER_ADMIN")
  168. }
  169. // TC-0025: adminLogin 用户名级别限流(H-2修复验证)
  170. func TestAdminLogin_UsernameRateLimit(t *testing.T) {
  171. ctx := context.Background()
  172. svcCtx := newTestSvcCtx()
  173. require.NotNil(t, svcCtx.UsernameLoginLimit, "UsernameLoginLimit 应被配置")
  174. username := "rl_" + testutil.UniqueId()
  175. logic := NewAdminLoginLogic(ctx, svcCtx)
  176. var last error
  177. for i := 0; i < 11; i++ {
  178. _, last = logic.AdminLogin(&types.AdminLoginReq{
  179. Username: username,
  180. Password: "wrong_pass",
  181. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  182. })
  183. require.Error(t, last)
  184. }
  185. var ce *response.CodeError
  186. require.True(t, errors.As(last, &ce))
  187. assert.Equal(t, 429, ce.Code(), "第11次应被用户名级限流")
  188. }
  189. // TC-0024: SQL注入username
  190. func TestAdminLogin_SQLInjection(t *testing.T) {
  191. ctx := context.Background()
  192. svcCtx := newTestSvcCtx()
  193. logic := NewAdminLoginLogic(ctx, svcCtx)
  194. resp, err := logic.AdminLogin(&types.AdminLoginReq{
  195. Username: "' OR 1=1 --",
  196. Password: "anything",
  197. ManagementKey: svcCtx.Config.Auth.ManagementKey,
  198. })
  199. require.Nil(t, resp)
  200. require.Error(t, err)
  201. var codeErr *response.CodeError
  202. require.True(t, errors.As(err, &codeErr))
  203. assert.Equal(t, 401, codeErr.Code())
  204. assert.Equal(t, "用户名或密码错误", codeErr.Error())
  205. }