Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

oauth2_test.go 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package auth_test
  4. import (
  5. "testing"
  6. auth_model "code.gitea.io/gitea/models/auth"
  7. "code.gitea.io/gitea/models/db"
  8. "code.gitea.io/gitea/models/unittest"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. //////////////////// Application
  12. func TestOAuth2Application_GenerateClientSecret(t *testing.T) {
  13. assert.NoError(t, unittest.PrepareTestDatabase())
  14. app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
  15. secret, err := app.GenerateClientSecret()
  16. assert.NoError(t, err)
  17. assert.True(t, len(secret) > 0)
  18. unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1, ClientSecret: app.ClientSecret})
  19. }
  20. func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) {
  21. assert.NoError(b, unittest.PrepareTestDatabase())
  22. app := unittest.AssertExistsAndLoadBean(b, &auth_model.OAuth2Application{ID: 1})
  23. for i := 0; i < b.N; i++ {
  24. _, _ = app.GenerateClientSecret()
  25. }
  26. }
  27. func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
  28. app := &auth_model.OAuth2Application{
  29. RedirectURIs: []string{"a", "b", "c"},
  30. }
  31. assert.True(t, app.ContainsRedirectURI("a"))
  32. assert.True(t, app.ContainsRedirectURI("b"))
  33. assert.True(t, app.ContainsRedirectURI("c"))
  34. assert.False(t, app.ContainsRedirectURI("d"))
  35. }
  36. func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
  37. app := &auth_model.OAuth2Application{
  38. RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"},
  39. ConfidentialClient: false,
  40. }
  41. // http loopback uris should ignore port
  42. // https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
  43. assert.True(t, app.ContainsRedirectURI("http://127.0.0.1:3456/"))
  44. assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
  45. assert.True(t, app.ContainsRedirectURI("http://[::1]:3456/"))
  46. // not http
  47. assert.False(t, app.ContainsRedirectURI("https://127.0.0.1:3456/"))
  48. // not loopback
  49. assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
  50. assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
  51. // unparseable
  52. assert.False(t, app.ContainsRedirectURI(":"))
  53. }
  54. func TestOAuth2Application_ContainsRedirect_Slash(t *testing.T) {
  55. app := &auth_model.OAuth2Application{RedirectURIs: []string{"http://127.0.0.1"}}
  56. assert.True(t, app.ContainsRedirectURI("http://127.0.0.1"))
  57. assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
  58. assert.False(t, app.ContainsRedirectURI("http://127.0.0.1/other"))
  59. app = &auth_model.OAuth2Application{RedirectURIs: []string{"http://127.0.0.1/"}}
  60. assert.True(t, app.ContainsRedirectURI("http://127.0.0.1"))
  61. assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
  62. assert.False(t, app.ContainsRedirectURI("http://127.0.0.1/other"))
  63. }
  64. func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
  65. assert.NoError(t, unittest.PrepareTestDatabase())
  66. app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
  67. secret, err := app.GenerateClientSecret()
  68. assert.NoError(t, err)
  69. assert.True(t, app.ValidateClientSecret([]byte(secret)))
  70. assert.False(t, app.ValidateClientSecret([]byte("fewijfowejgfiowjeoifew")))
  71. }
  72. func TestGetOAuth2ApplicationByClientID(t *testing.T) {
  73. assert.NoError(t, unittest.PrepareTestDatabase())
  74. app, err := auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138")
  75. assert.NoError(t, err)
  76. assert.Equal(t, "da7da3ba-9a13-4167-856f-3899de0b0138", app.ClientID)
  77. app, err = auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id")
  78. assert.Error(t, err)
  79. assert.Nil(t, app)
  80. }
  81. func TestCreateOAuth2Application(t *testing.T) {
  82. assert.NoError(t, unittest.PrepareTestDatabase())
  83. app, err := auth_model.CreateOAuth2Application(db.DefaultContext, auth_model.CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1})
  84. assert.NoError(t, err)
  85. assert.Equal(t, "newapp", app.Name)
  86. assert.Len(t, app.ClientID, 36)
  87. unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{Name: "newapp"})
  88. }
  89. func TestOAuth2Application_TableName(t *testing.T) {
  90. assert.Equal(t, "oauth2_application", new(auth_model.OAuth2Application).TableName())
  91. }
  92. func TestOAuth2Application_GetGrantByUserID(t *testing.T) {
  93. assert.NoError(t, unittest.PrepareTestDatabase())
  94. app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
  95. grant, err := app.GetGrantByUserID(db.DefaultContext, 1)
  96. assert.NoError(t, err)
  97. assert.Equal(t, int64(1), grant.UserID)
  98. grant, err = app.GetGrantByUserID(db.DefaultContext, 34923458)
  99. assert.NoError(t, err)
  100. assert.Nil(t, grant)
  101. }
  102. func TestOAuth2Application_CreateGrant(t *testing.T) {
  103. assert.NoError(t, unittest.PrepareTestDatabase())
  104. app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
  105. grant, err := app.CreateGrant(db.DefaultContext, 2, "")
  106. assert.NoError(t, err)
  107. assert.NotNil(t, grant)
  108. assert.Equal(t, int64(2), grant.UserID)
  109. assert.Equal(t, int64(1), grant.ApplicationID)
  110. assert.Equal(t, "", grant.Scope)
  111. }
  112. //////////////////// Grant
  113. func TestGetOAuth2GrantByID(t *testing.T) {
  114. assert.NoError(t, unittest.PrepareTestDatabase())
  115. grant, err := auth_model.GetOAuth2GrantByID(db.DefaultContext, 1)
  116. assert.NoError(t, err)
  117. assert.Equal(t, int64(1), grant.ID)
  118. grant, err = auth_model.GetOAuth2GrantByID(db.DefaultContext, 34923458)
  119. assert.NoError(t, err)
  120. assert.Nil(t, grant)
  121. }
  122. func TestOAuth2Grant_IncreaseCounter(t *testing.T) {
  123. assert.NoError(t, unittest.PrepareTestDatabase())
  124. grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 1})
  125. assert.NoError(t, grant.IncreaseCounter(db.DefaultContext))
  126. assert.Equal(t, int64(2), grant.Counter)
  127. unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 2})
  128. }
  129. func TestOAuth2Grant_ScopeContains(t *testing.T) {
  130. assert.NoError(t, unittest.PrepareTestDatabase())
  131. grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Scope: "openid profile"})
  132. assert.True(t, grant.ScopeContains("openid"))
  133. assert.True(t, grant.ScopeContains("profile"))
  134. assert.False(t, grant.ScopeContains("profil"))
  135. assert.False(t, grant.ScopeContains("profile2"))
  136. }
  137. func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) {
  138. assert.NoError(t, unittest.PrepareTestDatabase())
  139. grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1})
  140. code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256")
  141. assert.NoError(t, err)
  142. assert.NotNil(t, code)
  143. assert.True(t, len(code.Code) > 32) // secret length > 32
  144. }
  145. func TestOAuth2Grant_TableName(t *testing.T) {
  146. assert.Equal(t, "oauth2_grant", new(auth_model.OAuth2Grant).TableName())
  147. }
  148. func TestGetOAuth2GrantsByUserID(t *testing.T) {
  149. assert.NoError(t, unittest.PrepareTestDatabase())
  150. result, err := auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 1)
  151. assert.NoError(t, err)
  152. assert.Len(t, result, 1)
  153. assert.Equal(t, int64(1), result[0].ID)
  154. assert.Equal(t, result[0].ApplicationID, result[0].Application.ID)
  155. result, err = auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 34134)
  156. assert.NoError(t, err)
  157. assert.Empty(t, result)
  158. }
  159. func TestRevokeOAuth2Grant(t *testing.T) {
  160. assert.NoError(t, unittest.PrepareTestDatabase())
  161. assert.NoError(t, auth_model.RevokeOAuth2Grant(db.DefaultContext, 1, 1))
  162. unittest.AssertNotExistsBean(t, &auth_model.OAuth2Grant{ID: 1, UserID: 1})
  163. }
  164. //////////////////// Authorization Code
  165. func TestGetOAuth2AuthorizationByCode(t *testing.T) {
  166. assert.NoError(t, unittest.PrepareTestDatabase())
  167. code, err := auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode")
  168. assert.NoError(t, err)
  169. assert.NotNil(t, code)
  170. assert.Equal(t, "authcode", code.Code)
  171. assert.Equal(t, int64(1), code.ID)
  172. code, err = auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist")
  173. assert.NoError(t, err)
  174. assert.Nil(t, code)
  175. }
  176. func TestOAuth2AuthorizationCode_ValidateCodeChallenge(t *testing.T) {
  177. // test plain
  178. code := &auth_model.OAuth2AuthorizationCode{
  179. CodeChallengeMethod: "plain",
  180. CodeChallenge: "test123",
  181. }
  182. assert.True(t, code.ValidateCodeChallenge("test123"))
  183. assert.False(t, code.ValidateCodeChallenge("ierwgjoergjio"))
  184. // test S256
  185. code = &auth_model.OAuth2AuthorizationCode{
  186. CodeChallengeMethod: "S256",
  187. CodeChallenge: "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg",
  188. }
  189. assert.True(t, code.ValidateCodeChallenge("N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt"))
  190. assert.False(t, code.ValidateCodeChallenge("wiogjerogorewngoenrgoiuenorg"))
  191. // test unknown
  192. code = &auth_model.OAuth2AuthorizationCode{
  193. CodeChallengeMethod: "monkey",
  194. CodeChallenge: "foiwgjioriogeiogjerger",
  195. }
  196. assert.False(t, code.ValidateCodeChallenge("foiwgjioriogeiogjerger"))
  197. // test no code challenge
  198. code = &auth_model.OAuth2AuthorizationCode{
  199. CodeChallengeMethod: "",
  200. CodeChallenge: "foierjiogerogerg",
  201. }
  202. assert.True(t, code.ValidateCodeChallenge(""))
  203. }
  204. func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) {
  205. code := &auth_model.OAuth2AuthorizationCode{
  206. RedirectURI: "https://example.com/callback",
  207. Code: "thecode",
  208. }
  209. redirect, err := code.GenerateRedirectURI("thestate")
  210. assert.NoError(t, err)
  211. assert.Equal(t, "https://example.com/callback?code=thecode&state=thestate", redirect.String())
  212. redirect, err = code.GenerateRedirectURI("")
  213. assert.NoError(t, err)
  214. assert.Equal(t, "https://example.com/callback?code=thecode", redirect.String())
  215. }
  216. func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) {
  217. assert.NoError(t, unittest.PrepareTestDatabase())
  218. code := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"})
  219. assert.NoError(t, code.Invalidate(db.DefaultContext))
  220. unittest.AssertNotExistsBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"})
  221. }
  222. func TestOAuth2AuthorizationCode_TableName(t *testing.T) {
  223. assert.Equal(t, "oauth2_authorization_code", new(auth_model.OAuth2AuthorizationCode).TableName())
  224. }