gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "net/http"
  6. "net/url"
  7. "strings"
  8. "testing"
  9. auth_model "code.gitea.io/gitea/models/auth"
  10. "code.gitea.io/gitea/models/db"
  11. "code.gitea.io/gitea/models/unittest"
  12. user_model "code.gitea.io/gitea/models/user"
  13. "code.gitea.io/gitea/modules/setting"
  14. "code.gitea.io/gitea/modules/test"
  15. "code.gitea.io/gitea/modules/translation"
  16. "code.gitea.io/gitea/modules/web"
  17. "code.gitea.io/gitea/routers"
  18. "code.gitea.io/gitea/routers/web/auth"
  19. "code.gitea.io/gitea/services/context"
  20. "code.gitea.io/gitea/tests"
  21. "github.com/markbates/goth"
  22. "github.com/stretchr/testify/assert"
  23. "github.com/stretchr/testify/require"
  24. )
  25. func testLoginFailed(t *testing.T, username, password, message string) {
  26. session := emptyTestSession(t)
  27. req := NewRequestWithValues(t, "POST", "/user/login", map[string]string{
  28. "user_name": username,
  29. "password": password,
  30. })
  31. resp := session.MakeRequest(t, req, http.StatusOK)
  32. htmlDoc := NewHTMLParser(t, resp.Body)
  33. resultMsg := htmlDoc.doc.Find(".ui.message>p").Text()
  34. assert.Equal(t, message, resultMsg)
  35. }
  36. func TestSignin(t *testing.T) {
  37. defer tests.PrepareTestEnv(t)()
  38. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  39. // add new user with user2's email
  40. user.Name = "testuser"
  41. user.LowerName = strings.ToLower(user.Name)
  42. user.ID = 0
  43. require.NoError(t, db.Insert(t.Context(), user))
  44. samples := []struct {
  45. username string
  46. password string
  47. message string
  48. }{
  49. {username: "wrongUsername", password: "wrongPassword", message: translation.NewLocale("en-US").TrString("form.username_password_incorrect")},
  50. {username: "wrongUsername", password: "password", message: translation.NewLocale("en-US").TrString("form.username_password_incorrect")},
  51. {username: "user15", password: "wrongPassword", message: translation.NewLocale("en-US").TrString("form.username_password_incorrect")},
  52. {username: "user1@example.com", password: "wrongPassword", message: translation.NewLocale("en-US").TrString("form.username_password_incorrect")},
  53. }
  54. for _, s := range samples {
  55. testLoginFailed(t, s.username, s.password, s.message)
  56. }
  57. }
  58. func TestSigninWithRememberMe(t *testing.T) {
  59. defer tests.PrepareTestEnv(t)()
  60. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  61. baseURL, _ := url.Parse(setting.AppURL)
  62. session := emptyTestSession(t)
  63. req := NewRequestWithValues(t, "POST", "/user/login", map[string]string{
  64. "user_name": user.Name,
  65. "password": userPassword,
  66. "remember": "on",
  67. })
  68. session.MakeRequest(t, req, http.StatusSeeOther)
  69. c := session.GetRawCookie(setting.CookieRememberName)
  70. assert.NotNil(t, c)
  71. session = emptyTestSession(t)
  72. // Without session the settings page should not be reachable
  73. req = NewRequest(t, "GET", "/user/settings")
  74. session.MakeRequest(t, req, http.StatusSeeOther)
  75. req = NewRequest(t, "GET", "/user/login")
  76. // Set the remember me cookie for the login GET request
  77. session.jar.SetCookies(baseURL, []*http.Cookie{c})
  78. session.MakeRequest(t, req, http.StatusSeeOther)
  79. // With session the settings page should be reachable
  80. req = NewRequest(t, "GET", "/user/settings")
  81. session.MakeRequest(t, req, http.StatusOK)
  82. }
  83. func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) {
  84. defer tests.PrepareTestEnv(t)()
  85. mockLinkAccount := func(ctx *context.Context) {
  86. authSource := auth_model.Source{ID: 1}
  87. gothUser := goth.User{Email: "invalid-email", Name: "."}
  88. _ = auth.Oauth2SetLinkAccountData(ctx, auth.LinkAccountData{AuthSourceID: authSource.ID, GothUser: gothUser})
  89. }
  90. t.Run("EnablePasswordSignInForm=false", func(t *testing.T) {
  91. defer tests.PrintCurrentTest(t)()
  92. defer test.MockVariableValue(&setting.Service.EnablePasswordSignInForm, false)()
  93. req := NewRequest(t, "GET", "/user/login")
  94. resp := MakeRequest(t, req, http.StatusOK)
  95. doc := NewHTMLParser(t, resp.Body)
  96. AssertHTMLElement(t, doc, "form[action='/user/login']", false)
  97. req = NewRequest(t, "POST", "/user/login")
  98. MakeRequest(t, req, http.StatusForbidden)
  99. req = NewRequest(t, "GET", "/user/link_account")
  100. defer web.RouteMockReset()
  101. web.RouteMock(web.MockAfterMiddlewares, mockLinkAccount)
  102. resp = MakeRequest(t, req, http.StatusOK)
  103. doc = NewHTMLParser(t, resp.Body)
  104. AssertHTMLElement(t, doc, "form[action='/user/link_account_signin']", false)
  105. })
  106. t.Run("EnablePasswordSignInForm=true", func(t *testing.T) {
  107. defer tests.PrintCurrentTest(t)()
  108. defer test.MockVariableValue(&setting.Service.EnablePasswordSignInForm, true)()
  109. req := NewRequest(t, "GET", "/user/login")
  110. resp := MakeRequest(t, req, http.StatusOK)
  111. doc := NewHTMLParser(t, resp.Body)
  112. AssertHTMLElement(t, doc, "form[action='/user/login']", true)
  113. req = NewRequest(t, "POST", "/user/login")
  114. MakeRequest(t, req, http.StatusOK)
  115. req = NewRequest(t, "GET", "/user/link_account")
  116. defer web.RouteMockReset()
  117. web.RouteMock(web.MockAfterMiddlewares, mockLinkAccount)
  118. resp = MakeRequest(t, req, http.StatusOK)
  119. doc = NewHTMLParser(t, resp.Body)
  120. AssertHTMLElement(t, doc, "form[action='/user/link_account_signin']", true)
  121. })
  122. t.Run("EnablePasskeyAuth=false", func(t *testing.T) {
  123. defer tests.PrintCurrentTest(t)()
  124. defer test.MockVariableValue(&setting.Service.EnablePasskeyAuth, false)()
  125. req := NewRequest(t, "GET", "/user/login")
  126. resp := MakeRequest(t, req, http.StatusOK)
  127. doc := NewHTMLParser(t, resp.Body)
  128. AssertHTMLElement(t, doc, ".signin-passkey", false)
  129. })
  130. t.Run("EnablePasskeyAuth=true", func(t *testing.T) {
  131. defer tests.PrintCurrentTest(t)()
  132. defer test.MockVariableValue(&setting.Service.EnablePasskeyAuth, true)()
  133. req := NewRequest(t, "GET", "/user/login")
  134. resp := MakeRequest(t, req, http.StatusOK)
  135. doc := NewHTMLParser(t, resp.Body)
  136. AssertHTMLElement(t, doc, ".signin-passkey", true)
  137. })
  138. }
  139. func TestRequireSignInView(t *testing.T) {
  140. defer tests.PrepareTestEnv(t)()
  141. t.Run("NoRequireSignInView", func(t *testing.T) {
  142. require.False(t, setting.Service.RequireSignInViewStrict)
  143. require.False(t, setting.Service.BlockAnonymousAccessExpensive)
  144. req := NewRequest(t, "GET", "/user2/repo1/src/branch/master")
  145. MakeRequest(t, req, http.StatusOK)
  146. })
  147. t.Run("RequireSignInView", func(t *testing.T) {
  148. defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)()
  149. defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())()
  150. req := NewRequest(t, "GET", "/user2/repo1/src/branch/master")
  151. resp := MakeRequest(t, req, http.StatusSeeOther)
  152. assert.Equal(t, "/user/login", resp.Header().Get("Location"))
  153. })
  154. t.Run("BlockAnonymousAccessExpensive", func(t *testing.T) {
  155. defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, false)()
  156. defer test.MockVariableValue(&setting.Service.BlockAnonymousAccessExpensive, true)()
  157. defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())()
  158. req := NewRequest(t, "GET", "/user2/repo1")
  159. MakeRequest(t, req, http.StatusOK)
  160. req = NewRequest(t, "GET", "/user2/repo1/src/branch/master")
  161. resp := MakeRequest(t, req, http.StatusSeeOther)
  162. assert.Equal(t, "/user/login", resp.Header().Get("Location"))
  163. })
  164. }