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.

138 lines
5.0 KiB

  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "encoding/json"
  7. "testing"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. const defaultAuthorize = "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=a&response_type=code&state=thestate"
  11. func TestNoClientID(t *testing.T) {
  12. prepareTestEnv(t)
  13. req := NewRequest(t, "GET", "/login/oauth/authorize")
  14. ctx := loginUser(t, "user2")
  15. ctx.MakeRequest(t, req, 400)
  16. }
  17. func TestLoginRedirect(t *testing.T) {
  18. prepareTestEnv(t)
  19. req := NewRequest(t, "GET", "/login/oauth/authorize")
  20. assert.Contains(t, MakeRequest(t, req, 302).Body.String(), "/user/login")
  21. }
  22. func TestShowAuthorize(t *testing.T) {
  23. prepareTestEnv(t)
  24. req := NewRequest(t, "GET", defaultAuthorize)
  25. ctx := loginUser(t, "user4")
  26. resp := ctx.MakeRequest(t, req, 200)
  27. htmlDoc := NewHTMLParser(t, resp.Body)
  28. htmlDoc.AssertElement(t, "#authorize-app", true)
  29. htmlDoc.GetCSRF()
  30. }
  31. func TestRedirectWithExistingGrant(t *testing.T) {
  32. prepareTestEnv(t)
  33. req := NewRequest(t, "GET", defaultAuthorize)
  34. ctx := loginUser(t, "user1")
  35. resp := ctx.MakeRequest(t, req, 302)
  36. u, err := resp.Result().Location()
  37. assert.NoError(t, err)
  38. assert.Equal(t, "thestate", u.Query().Get("state"))
  39. assert.Truef(t, len(u.Query().Get("code")) > 30, "authorization code '%s' should be longer then 30", u.Query().Get("code"))
  40. }
  41. func TestAccessTokenExchange(t *testing.T) {
  42. prepareTestEnv(t)
  43. req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  44. "grant_type": "authorization_code",
  45. "client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
  46. "client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
  47. "redirect_uri": "a",
  48. "code": "authcode",
  49. "code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt", // test PKCE additionally
  50. })
  51. resp := MakeRequest(t, req, 200)
  52. type response struct {
  53. AccessToken string `json:"access_token"`
  54. TokenType string `json:"token_type"`
  55. ExpiresIn int64 `json:"expires_in"`
  56. RefreshToken string `json:"refresh_token"`
  57. }
  58. parsed := new(response)
  59. assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), parsed))
  60. assert.True(t, len(parsed.AccessToken) > 10)
  61. assert.True(t, len(parsed.RefreshToken) > 10)
  62. }
  63. func TestAccessTokenExchangeWithoutPKCE(t *testing.T) {
  64. prepareTestEnv(t)
  65. req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  66. "grant_type": "authorization_code",
  67. "client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
  68. "client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
  69. "redirect_uri": "a",
  70. "code": "authcode",
  71. })
  72. MakeRequest(t, req, 400)
  73. }
  74. func TestAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
  75. prepareTestEnv(t)
  76. // invalid client id
  77. req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  78. "grant_type": "authorization_code",
  79. "client_id": "???",
  80. "client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
  81. "redirect_uri": "a",
  82. "code": "authcode",
  83. "code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt", // test PKCE additionally
  84. })
  85. MakeRequest(t, req, 400)
  86. // invalid client secret
  87. req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  88. "grant_type": "authorization_code",
  89. "client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
  90. "client_secret": "???",
  91. "redirect_uri": "a",
  92. "code": "authcode",
  93. "code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt", // test PKCE additionally
  94. })
  95. MakeRequest(t, req, 400)
  96. // invalid redirect uri
  97. req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  98. "grant_type": "authorization_code",
  99. "client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
  100. "client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
  101. "redirect_uri": "???",
  102. "code": "authcode",
  103. "code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt", // test PKCE additionally
  104. })
  105. MakeRequest(t, req, 400)
  106. // invalid authorization code
  107. req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  108. "grant_type": "authorization_code",
  109. "client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
  110. "client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
  111. "redirect_uri": "a",
  112. "code": "???",
  113. "code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt", // test PKCE additionally
  114. })
  115. MakeRequest(t, req, 400)
  116. // invalid grant_type
  117. req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
  118. "grant_type": "???",
  119. "client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
  120. "client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
  121. "redirect_uri": "a",
  122. "code": "authcode",
  123. "code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt", // test PKCE additionally
  124. })
  125. MakeRequest(t, req, 400)
  126. }