You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pwn_test.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package pwn
  4. import (
  5. "math/rand/v2"
  6. "net/http"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. var client = New(WithHTTP(&http.Client{
  13. Timeout: time.Second * 2,
  14. }))
  15. func TestPassword(t *testing.T) {
  16. // Check input error
  17. _, err := client.CheckPassword("", false)
  18. assert.ErrorIs(t, err, ErrEmptyPassword, "blank input should return ErrEmptyPassword")
  19. // Should fail
  20. fail := "password1234"
  21. count, err := client.CheckPassword(fail, false)
  22. assert.NotEmpty(t, count, "%s should fail as a password", fail)
  23. assert.NoError(t, err)
  24. // Should fail (with padding)
  25. failPad := "administrator"
  26. count, err = client.CheckPassword(failPad, true)
  27. assert.NotEmpty(t, count, "%s should fail as a password", failPad)
  28. assert.NoError(t, err)
  29. // Checking for a "good" password isn't going to be perfect, but we can give it a good try
  30. // with hopefully minimal error. Try five times?
  31. assert.Condition(t, func() bool {
  32. for i := 0; i <= 5; i++ {
  33. count, err = client.CheckPassword(testPassword(), false)
  34. assert.NoError(t, err)
  35. if count == 0 {
  36. return true
  37. }
  38. }
  39. return false
  40. }, "no generated passwords passed. there is a chance this is a fluke")
  41. // Again, but with padded responses
  42. assert.Condition(t, func() bool {
  43. for i := 0; i <= 5; i++ {
  44. count, err = client.CheckPassword(testPassword(), true)
  45. assert.NoError(t, err)
  46. if count == 0 {
  47. return true
  48. }
  49. }
  50. return false
  51. }, "no generated passwords passed. there is a chance this is a fluke")
  52. }
  53. // Credit to https://golangbyexample.com/generate-random-password-golang/
  54. // DO NOT USE THIS FOR AN ACTUAL PASSWORD GENERATOR
  55. var (
  56. lowerCharSet = "abcdedfghijklmnopqrst"
  57. upperCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  58. specialCharSet = "!@#$%&*"
  59. numberSet = "0123456789"
  60. allCharSet = lowerCharSet + upperCharSet + specialCharSet + numberSet
  61. )
  62. func testPassword() string {
  63. var password strings.Builder
  64. // Set special character
  65. for i := 0; i < 5; i++ {
  66. random := rand.IntN(len(specialCharSet))
  67. password.WriteString(string(specialCharSet[random]))
  68. }
  69. // Set numeric
  70. for i := 0; i < 5; i++ {
  71. random := rand.IntN(len(numberSet))
  72. password.WriteString(string(numberSet[random]))
  73. }
  74. // Set uppercase
  75. for i := 0; i < 5; i++ {
  76. random := rand.IntN(len(upperCharSet))
  77. password.WriteString(string(upperCharSet[random]))
  78. }
  79. for i := 0; i < 5; i++ {
  80. random := rand.IntN(len(allCharSet))
  81. password.WriteString(string(allCharSet[random]))
  82. }
  83. inRune := []rune(password.String())
  84. rand.Shuffle(len(inRune), func(i, j int) {
  85. inRune[i], inRune[j] = inRune[j], inRune[i]
  86. })
  87. return string(inRune)
  88. }