gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "net/http"
  6. "testing"
  7. "time"
  8. auth_model "code.gitea.io/gitea/models/auth"
  9. "code.gitea.io/gitea/models/unittest"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "code.gitea.io/gitea/tests"
  12. "github.com/pquerna/otp/totp"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func TestAPITwoFactor(t *testing.T) {
  16. defer tests.PrepareTestEnv(t)()
  17. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16})
  18. req := NewRequest(t, "GET", "/api/v1/user").
  19. AddBasicAuth(user.Name)
  20. MakeRequest(t, req, http.StatusOK)
  21. otpKey, err := totp.Generate(totp.GenerateOpts{
  22. SecretSize: 40,
  23. Issuer: "gitea-test",
  24. AccountName: user.Name,
  25. })
  26. assert.NoError(t, err)
  27. tfa := &auth_model.TwoFactor{
  28. UID: user.ID,
  29. }
  30. assert.NoError(t, tfa.SetSecret(otpKey.Secret()))
  31. assert.NoError(t, auth_model.NewTwoFactor(t.Context(), tfa))
  32. req = NewRequest(t, "GET", "/api/v1/user").
  33. AddBasicAuth(user.Name)
  34. MakeRequest(t, req, http.StatusUnauthorized)
  35. passcode, err := totp.GenerateCode(otpKey.Secret(), time.Now())
  36. assert.NoError(t, err)
  37. req = NewRequest(t, "GET", "/api/v1/user").
  38. AddBasicAuth(user.Name)
  39. req.Header.Set("X-Gitea-OTP", passcode)
  40. MakeRequest(t, req, http.StatusOK)
  41. }
  42. func TestBasicAuthWithWebAuthn(t *testing.T) {
  43. defer tests.PrepareTestEnv(t)()
  44. // user1 has no webauthn enrolled, he can request API with basic auth
  45. user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  46. unittest.AssertNotExistsBean(t, &auth_model.WebAuthnCredential{UserID: user1.ID})
  47. req := NewRequest(t, "GET", "/api/v1/user")
  48. req.SetBasicAuth(user1.Name, "password")
  49. MakeRequest(t, req, http.StatusOK)
  50. // user1 has no webauthn enrolled, he can request git protocol with basic auth
  51. req = NewRequest(t, "GET", "/user2/repo1/info/refs")
  52. req.SetBasicAuth(user1.Name, "password")
  53. MakeRequest(t, req, http.StatusOK)
  54. // user1 has no webauthn enrolled, he can request container package with basic auth
  55. req = NewRequest(t, "GET", "/v2/token")
  56. req.SetBasicAuth(user1.Name, "password")
  57. resp := MakeRequest(t, req, http.StatusOK)
  58. type tokenResponse struct {
  59. Token string `json:"token"`
  60. }
  61. var tokenParsed tokenResponse
  62. DecodeJSON(t, resp, &tokenParsed)
  63. assert.NotEmpty(t, tokenParsed.Token)
  64. // user32 has webauthn enrolled, he can't request API with basic auth
  65. user32 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 32})
  66. unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{UserID: user32.ID})
  67. req = NewRequest(t, "GET", "/api/v1/user")
  68. req.SetBasicAuth(user32.Name, "notpassword")
  69. resp = MakeRequest(t, req, http.StatusUnauthorized)
  70. type userResponse struct {
  71. Message string `json:"message"`
  72. }
  73. var userParsed userResponse
  74. DecodeJSON(t, resp, &userParsed)
  75. assert.Equal(t, "basic authorization is not allowed while WebAuthn enrolled", userParsed.Message)
  76. // user32 has webauthn enrolled, he can't request git protocol with basic auth
  77. req = NewRequest(t, "GET", "/user2/repo1/info/refs")
  78. req.SetBasicAuth(user32.Name, "notpassword")
  79. MakeRequest(t, req, http.StatusUnauthorized)
  80. // user32 has webauthn enrolled, he can't request container package with basic auth
  81. req = NewRequest(t, "GET", "/v2/token")
  82. req.SetBasicAuth(user1.Name, "notpassword")
  83. MakeRequest(t, req, http.StatusUnauthorized)
  84. }