mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-06 08:26:41 -04:00
Support for Custom URI Schemes in OAuth2 Redirect URIs (#37356)
Fix #34349 By the way, remove `(ctx *APIContext) HasAPIError() ` and `(ctx *APIContext) GetErrMsg()` because they do nothing, the error handling has been done in API's middeware The existing OAuth2 tests were not quite right, refactored them together
This commit is contained in:
@@ -11,10 +11,13 @@ import (
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestOAuth2Application(t *testing.T) {
|
||||
@@ -28,18 +31,17 @@ func TestOAuth2Application(t *testing.T) {
|
||||
|
||||
func testAPICreateOAuth2Application(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
appBody := api.CreateOAuth2ApplicationOptions{
|
||||
Name: "test-app-1",
|
||||
RedirectURIs: []string{
|
||||
"http://www.google.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
}
|
||||
redirectURIs := []string{"http://www.google.com", "my-app:foo"}
|
||||
appBody := api.CreateOAuth2ApplicationOptions{Name: "test-app-1", RedirectURIs: redirectURIs, ConfidentialClient: true}
|
||||
|
||||
req := NewRequestWithJSON(t, "POST", "/api/v1/user/applications/oauth2", &appBody).
|
||||
AddBasicAuth(user.Name)
|
||||
// no custom scheme
|
||||
req := NewRequestWithJSON(t, "POST", "/api/v1/user/applications/oauth2", &appBody).AddBasicAuth(user.Name)
|
||||
MakeRequest(t, req, http.StatusBadRequest)
|
||||
|
||||
// with custom scheme
|
||||
defer test.MockVariableValue(&setting.OAuth2.CustomSchemes, []string{"my-app"})()
|
||||
req = NewRequestWithJSON(t, "POST", "/api/v1/user/applications/oauth2", &appBody).AddBasicAuth(user.Name)
|
||||
resp := MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
createdApp := DecodeJSON(t, resp, &api.OAuth2Application{})
|
||||
|
||||
assert.Equal(t, appBody.Name, createdApp.Name)
|
||||
@@ -47,7 +49,7 @@ func testAPICreateOAuth2Application(t *testing.T) {
|
||||
assert.Len(t, createdApp.ClientID, 36)
|
||||
assert.True(t, createdApp.ConfidentialClient)
|
||||
assert.NotEmpty(t, createdApp.Created)
|
||||
assert.Equal(t, appBody.RedirectURIs[0], createdApp.RedirectURIs[0])
|
||||
assert.Equal(t, redirectURIs, createdApp.RedirectURIs)
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: createdApp.Name})
|
||||
}
|
||||
|
||||
@@ -56,21 +58,13 @@ func testAPIListOAuth2Applications(t *testing.T) {
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser)
|
||||
|
||||
existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
|
||||
UID: user.ID,
|
||||
Name: "test-app-1",
|
||||
RedirectURIs: []string{
|
||||
"http://www.google.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
})
|
||||
existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: "test-app-1", ConfidentialClient: true})
|
||||
require.NotEmpty(t, existApp.RedirectURIs)
|
||||
|
||||
req := NewRequest(t, "GET", "/api/v1/user/applications/oauth2").
|
||||
AddTokenAuth(token)
|
||||
req := NewRequest(t, "GET", "/api/v1/user/applications/oauth2").AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var appList api.OAuth2ApplicationList
|
||||
DecodeJSON(t, resp, &appList)
|
||||
appList := DecodeJSON(t, resp, api.OAuth2ApplicationList{})
|
||||
expectedApp := appList[0]
|
||||
|
||||
assert.Equal(t, expectedApp.Name, existApp.Name)
|
||||
@@ -78,7 +72,7 @@ func testAPIListOAuth2Applications(t *testing.T) {
|
||||
assert.Equal(t, expectedApp.ConfidentialClient, existApp.ConfidentialClient)
|
||||
assert.Len(t, expectedApp.ClientID, 36)
|
||||
assert.Empty(t, expectedApp.ClientSecret)
|
||||
assert.Equal(t, existApp.RedirectURIs[0], expectedApp.RedirectURIs[0])
|
||||
assert.Equal(t, expectedApp.RedirectURIs, existApp.RedirectURIs)
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
|
||||
}
|
||||
|
||||
@@ -87,21 +81,16 @@ func testAPIDeleteOAuth2Application(t *testing.T) {
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
|
||||
|
||||
oldApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
|
||||
UID: user.ID,
|
||||
Name: "test-app-1",
|
||||
})
|
||||
oldApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: "test-app-1"})
|
||||
|
||||
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d", oldApp.ID)
|
||||
req := NewRequest(t, "DELETE", urlStr).
|
||||
AddTokenAuth(token)
|
||||
req := NewRequest(t, "DELETE", urlStr).AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusNoContent)
|
||||
|
||||
unittest.AssertNotExistsBean(t, &auth_model.OAuth2Application{UID: oldApp.UID, Name: oldApp.Name})
|
||||
|
||||
// Delete again will return not found
|
||||
req = NewRequest(t, "DELETE", urlStr).
|
||||
AddTokenAuth(token)
|
||||
req = NewRequest(t, "DELETE", urlStr).AddTokenAuth(token)
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
}
|
||||
|
||||
@@ -110,65 +99,41 @@ func testAPIGetOAuth2Application(t *testing.T) {
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser)
|
||||
|
||||
existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
|
||||
UID: user.ID,
|
||||
Name: "test-app-1",
|
||||
RedirectURIs: []string{
|
||||
"http://www.google.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
})
|
||||
existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: "test-app-1", ConfidentialClient: true})
|
||||
require.NotEmpty(t, existApp.RedirectURIs)
|
||||
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/applications/oauth2/%d", existApp.ID)).
|
||||
AddTokenAuth(token)
|
||||
req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/applications/oauth2/%d", existApp.ID)).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var app api.OAuth2Application
|
||||
DecodeJSON(t, resp, &app)
|
||||
expectedApp := app
|
||||
expectedApp := DecodeJSON(t, resp, &api.OAuth2Application{})
|
||||
|
||||
assert.Equal(t, expectedApp.Name, existApp.Name)
|
||||
assert.Equal(t, expectedApp.ClientID, existApp.ClientID)
|
||||
assert.Equal(t, expectedApp.ConfidentialClient, existApp.ConfidentialClient)
|
||||
assert.Len(t, expectedApp.ClientID, 36)
|
||||
assert.Empty(t, expectedApp.ClientSecret)
|
||||
assert.Len(t, expectedApp.RedirectURIs, 1)
|
||||
assert.Equal(t, expectedApp.RedirectURIs[0], existApp.RedirectURIs[0])
|
||||
assert.Equal(t, expectedApp.RedirectURIs, existApp.RedirectURIs)
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
|
||||
}
|
||||
|
||||
func testAPIUpdateOAuth2Application(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
|
||||
existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{
|
||||
UID: user.ID,
|
||||
Name: "test-app-1",
|
||||
RedirectURIs: []string{
|
||||
"http://www.google.com",
|
||||
},
|
||||
})
|
||||
|
||||
appBody := api.CreateOAuth2ApplicationOptions{
|
||||
Name: "test-app-1",
|
||||
RedirectURIs: []string{
|
||||
"http://www.google.com/",
|
||||
"http://www.github.com/",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
}
|
||||
|
||||
existApp := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: "test-app-1"})
|
||||
redirectURIs := []string{"https://www.google.com", "my-app:foo"}
|
||||
appBody := api.CreateOAuth2ApplicationOptions{Name: "test-app-1", RedirectURIs: redirectURIs, ConfidentialClient: true}
|
||||
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d", existApp.ID)
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &appBody).
|
||||
AddBasicAuth(user.Name)
|
||||
|
||||
// no custom scheme
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &appBody).AddBasicAuth(user.Name)
|
||||
MakeRequest(t, req, http.StatusBadRequest)
|
||||
|
||||
// with custom scheme
|
||||
defer test.MockVariableValue(&setting.OAuth2.CustomSchemes, []string{"my-app"})()
|
||||
req = NewRequestWithJSON(t, "PATCH", urlStr, &appBody).AddBasicAuth(user.Name)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var app api.OAuth2Application
|
||||
DecodeJSON(t, resp, &app)
|
||||
expectedApp := app
|
||||
|
||||
assert.Len(t, expectedApp.RedirectURIs, 2)
|
||||
assert.Equal(t, expectedApp.RedirectURIs[0], appBody.RedirectURIs[0])
|
||||
assert.Equal(t, expectedApp.RedirectURIs[1], appBody.RedirectURIs[1])
|
||||
expectedApp := DecodeJSON(t, resp, &api.OAuth2Application{})
|
||||
assert.Equal(t, expectedApp.RedirectURIs, appBody.RedirectURIs)
|
||||
assert.Equal(t, expectedApp.ConfidentialClient, appBody.ConfidentialClient)
|
||||
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name})
|
||||
}
|
||||
|
||||
+116
-88
@@ -23,6 +23,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
"code.gitea.io/gitea/services/oauth2_provider"
|
||||
@@ -35,17 +36,57 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestOAuth2Provider(t *testing.T) {
|
||||
func testOAuth2PrepareTestCode(t *testing.T) {
|
||||
require.NoError(t, db.TruncateBeans(t.Context(), &auth_model.OAuth2AuthorizationCode{}))
|
||||
err := db.Insert(t.Context(), &auth_model.OAuth2AuthorizationCode{
|
||||
GrantID: 1,
|
||||
Code: "authcode",
|
||||
CodeChallenge: "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", // Code Verifier: N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt
|
||||
CodeChallengeMethod: "S256",
|
||||
RedirectURI: "https://example.com",
|
||||
ValidUntil: timeutil.TimeStampNow() + 86400,
|
||||
}, &auth_model.OAuth2AuthorizationCode{
|
||||
GrantID: 4,
|
||||
Code: "authcodepublic",
|
||||
CodeChallenge: "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", //# Code Verifier: N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt
|
||||
CodeChallengeMethod: "S256",
|
||||
RedirectURI: "http://127.0.0.1/",
|
||||
ValidUntil: timeutil.TimeStampNow() + 86400,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestOAuth2(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
t.Run("AuthorizeNoClientID", testAuthorizeNoClientID)
|
||||
t.Run("AuthorizeUnregisteredRedirect", testAuthorizeUnregisteredRedirect)
|
||||
t.Run("AuthorizeUnsupportedResponseType", testAuthorizeUnsupportedResponseType)
|
||||
t.Run("AuthorizeUnsupportedCodeChallengeMethod", testAuthorizeUnsupportedCodeChallengeMethod)
|
||||
t.Run("AuthorizeLoginRedirect", testAuthorizeLoginRedirect)
|
||||
|
||||
t.Run("OAuth2WellKnown", testOAuth2WellKnown)
|
||||
t.Run("OAuthSourceSpecialChars", testOAuthSourceSpecialChars)
|
||||
t.Run("Provider", func(t *testing.T) {
|
||||
t.Run("AuthorizeNoClientID", testAuthorizeNoClientID)
|
||||
t.Run("AuthorizeUnregisteredRedirect", testAuthorizeUnregisteredRedirect)
|
||||
t.Run("AuthorizeUnsupportedResponseType", testAuthorizeUnsupportedResponseType)
|
||||
t.Run("AuthorizeUnsupportedCodeChallengeMethod", testAuthorizeUnsupportedCodeChallengeMethod)
|
||||
t.Run("AuthorizeLoginRedirect", testAuthorizeLoginRedirect)
|
||||
t.Run("AuthorizeShow", testAuthorizeShow)
|
||||
t.Run("AuthorizeGrantS256RequiresVerifier", testAuthorizeGrantS256RequiresVerifier)
|
||||
t.Run("AuthorizeRedirectWithExistingGrant", testAuthorizeRedirectWithExistingGrant)
|
||||
t.Run("AuthorizePKCERequiredForPublicClient", testAuthorizePKCERequiredForPublicClient)
|
||||
t.Run("AccessTokenExchange", testAccessTokenExchange)
|
||||
t.Run("AccessTokenExchangeWithPublicClient", testAccessTokenExchangeWithPublicClient)
|
||||
t.Run("AccessTokenExchangeJSON", testAccessTokenExchangeJSON)
|
||||
t.Run("AccessTokenExchangeWithoutPKCE", testAccessTokenExchangeWithoutPKCE)
|
||||
t.Run("AccessTokenExchangeWithInvalidCredentials", testAccessTokenExchangeWithInvalidCredentials)
|
||||
t.Run("AccessTokenExchangeWithBasicAuth", testAccessTokenExchangeWithBasicAuth)
|
||||
t.Run("RefreshTokenInvalidation", testRefreshTokenInvalidation)
|
||||
t.Run("OAuthIntrospection", testOAuthIntrospection)
|
||||
t.Run("OAuthGrantScopesReadUserFailRepos", testOAuthGrantScopesReadUserFailRepos)
|
||||
t.Run("OAuthGrantScopesReadRepositoryFailOrganization", testOAuthGrantScopesReadRepositoryFailOrganization)
|
||||
t.Run("OAuthGrantScopesClaimPublicOnlyGroups", testOAuthGrantScopesClaimPublicOnlyGroups)
|
||||
t.Run("OAuthGrantScopesClaimAllGroups", testOAuthGrantScopesClaimAllGroups)
|
||||
t.Run("OAuth2WellKnown", testOAuth2WellKnown)
|
||||
})
|
||||
t.Run("Client", func(t *testing.T) {
|
||||
t.Run("OAuthSourceSpecialChars", testOAuthSourceSpecialChars)
|
||||
t.Run("SignInOauthCallbackSyncSSHKeys", testSignInOauthCallbackSyncSSHKeys)
|
||||
})
|
||||
// TODO: move more tests as sub-tests here, avoid unnecessary PrepareTestEnv
|
||||
}
|
||||
|
||||
@@ -64,7 +105,7 @@ func testAuthorizeUnregisteredRedirect(t *testing.T) {
|
||||
}
|
||||
|
||||
func testAuthorizeUnsupportedResponseType(t *testing.T) {
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=a&response_type=UNEXPECTED&state=thestate")
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=https://example.com&response_type=UNEXPECTED&state=thestate")
|
||||
ctx := loginUser(t, "user1")
|
||||
resp := ctx.MakeRequest(t, req, http.StatusSeeOther)
|
||||
u, err := resp.Result().Location()
|
||||
@@ -74,7 +115,7 @@ func testAuthorizeUnsupportedResponseType(t *testing.T) {
|
||||
}
|
||||
|
||||
func testAuthorizeUnsupportedCodeChallengeMethod(t *testing.T) {
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=a&response_type=code&state=thestate&code_challenge_method=UNEXPECTED")
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=https://example.com&response_type=code&state=thestate&code_challenge_method=UNEXPECTED")
|
||||
ctx := loginUser(t, "user1")
|
||||
resp := ctx.MakeRequest(t, req, http.StatusSeeOther)
|
||||
u, err := resp.Result().Location()
|
||||
@@ -88,9 +129,8 @@ func testAuthorizeLoginRedirect(t *testing.T) {
|
||||
assert.Contains(t, MakeRequest(t, req, http.StatusSeeOther).Body.String(), "/user/login")
|
||||
}
|
||||
|
||||
func TestAuthorizeShow(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=a&response_type=code&state=thestate")
|
||||
func testAuthorizeShow(t *testing.T) {
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=https://example.com&response_type=code&state=thestate")
|
||||
ctx := loginUser(t, "user4")
|
||||
resp := ctx.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
@@ -98,11 +138,10 @@ func TestAuthorizeShow(t *testing.T) {
|
||||
AssertHTMLElement(t, htmlDoc, "#authorize-app", true)
|
||||
}
|
||||
|
||||
func TestAuthorizeGrantS256RequiresVerifier(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAuthorizeGrantS256RequiresVerifier(t *testing.T) {
|
||||
ctx := loginUser(t, "user4")
|
||||
codeChallenge := "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg"
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=a&response_type=code&state=thestate&code_challenge_method=S256&code_challenge="+url.QueryEscape(codeChallenge))
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=https://example.com&response_type=code&state=thestate&code_challenge_method=S256&code_challenge="+url.QueryEscape(codeChallenge))
|
||||
resp := ctx.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||
@@ -113,7 +152,7 @@ func TestAuthorizeGrantS256RequiresVerifier(t *testing.T) {
|
||||
"state": "thestate",
|
||||
"scope": "",
|
||||
"nonce": "",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"granted": "true",
|
||||
})
|
||||
grantResp := ctx.MakeRequest(t, grantReq, http.StatusSeeOther)
|
||||
@@ -126,7 +165,7 @@ func TestAuthorizeGrantS256RequiresVerifier(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": code,
|
||||
})
|
||||
accessResp := MakeRequest(t, accessReq, http.StatusBadRequest)
|
||||
@@ -136,9 +175,8 @@ func TestAuthorizeGrantS256RequiresVerifier(t *testing.T) {
|
||||
assert.Equal(t, "failed PKCE code challenge", parsedError.ErrorDescription)
|
||||
}
|
||||
|
||||
func TestAuthorizeRedirectWithExistingGrant(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=https%3A%2F%2Fexample.com%2Fxyzzy&response_type=code&state=thestate")
|
||||
func testAuthorizeRedirectWithExistingGrant(t *testing.T) {
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=da7da3ba-9a13-4167-856f-3899de0b0138&redirect_uri=https://example.com/&response_type=code&state=thestate")
|
||||
ctx := loginUser(t, "user1")
|
||||
resp := ctx.MakeRequest(t, req, http.StatusSeeOther)
|
||||
u, err := resp.Result().Location()
|
||||
@@ -146,11 +184,11 @@ func TestAuthorizeRedirectWithExistingGrant(t *testing.T) {
|
||||
assert.Equal(t, "thestate", u.Query().Get("state"))
|
||||
assert.Greaterf(t, len(u.Query().Get("code")), 30, "authorization code '%s' should be longer then 30", u.Query().Get("code"))
|
||||
u.RawQuery = ""
|
||||
assert.Equal(t, "https://example.com/xyzzy", u.String())
|
||||
assert.Equal(t, "https://example.com/", u.String())
|
||||
}
|
||||
|
||||
func TestAuthorizePKCERequiredForPublicClient(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAuthorizePKCERequiredForPublicClient(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequest(t, "GET", "/login/oauth/authorize?client_id=ce5a1322-42a7-11ed-b878-0242ac120002&redirect_uri=http%3A%2F%2F127.0.0.1&response_type=code&state=thestate")
|
||||
ctx := loginUser(t, "user1")
|
||||
resp := ctx.MakeRequest(t, req, http.StatusSeeOther)
|
||||
@@ -160,13 +198,13 @@ func TestAuthorizePKCERequiredForPublicClient(t *testing.T) {
|
||||
assert.Equal(t, "PKCE is required for public clients", u.Query().Get("error_description"))
|
||||
}
|
||||
|
||||
func TestAccessTokenExchange(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAccessTokenExchange(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -184,8 +222,8 @@ func TestAccessTokenExchange(t *testing.T) {
|
||||
assert.Greater(t, len(parsed.RefreshToken), 10)
|
||||
}
|
||||
|
||||
func TestAccessTokenExchangeWithPublicClient(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAccessTokenExchangeWithPublicClient(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "ce5a1322-42a7-11ed-b878-0242ac120002",
|
||||
@@ -207,13 +245,13 @@ func TestAccessTokenExchangeWithPublicClient(t *testing.T) {
|
||||
assert.Greater(t, len(parsed.RefreshToken), 10)
|
||||
}
|
||||
|
||||
func TestAccessTokenExchangeJSON(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAccessTokenExchangeJSON(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithJSON(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -231,13 +269,13 @@ func TestAccessTokenExchangeJSON(t *testing.T) {
|
||||
assert.Greater(t, len(parsed.RefreshToken), 10)
|
||||
}
|
||||
|
||||
func TestAccessTokenExchangeWithoutPKCE(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAccessTokenExchangeWithoutPKCE(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
})
|
||||
resp := MakeRequest(t, req, http.StatusBadRequest)
|
||||
@@ -247,14 +285,14 @@ func TestAccessTokenExchangeWithoutPKCE(t *testing.T) {
|
||||
assert.Equal(t, "failed PKCE code challenge", parsedError.ErrorDescription)
|
||||
}
|
||||
|
||||
func TestAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
// invalid client id
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "???",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -269,7 +307,7 @@ func TestAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "???",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -299,7 +337,7 @@ func TestAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "???",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -314,7 +352,7 @@ func TestAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
|
||||
"grant_type": "???",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -325,11 +363,11 @@ func TestAccessTokenExchangeWithInvalidCredentials(t *testing.T) {
|
||||
assert.Equal(t, "Only refresh_token or authorization_code grant type is supported", parsedError.ErrorDescription)
|
||||
}
|
||||
|
||||
func TestAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -350,7 +388,7 @@ func TestAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
// use wrong client_secret
|
||||
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -364,7 +402,7 @@ func TestAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
// missing header
|
||||
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -377,7 +415,7 @@ func TestAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
// client_id inconsistent with Authorization header
|
||||
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"client_id": "inconsistent",
|
||||
})
|
||||
@@ -391,7 +429,7 @@ func TestAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
// client_secret inconsistent with Authorization header
|
||||
req = NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"client_secret": "inconsistent",
|
||||
})
|
||||
@@ -403,13 +441,13 @@ func TestAccessTokenExchangeWithBasicAuth(t *testing.T) {
|
||||
assert.Equal(t, "client_secret in request body inconsistent with Authorization header", parsedError.ErrorDescription)
|
||||
}
|
||||
|
||||
func TestRefreshTokenInvalidation(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testRefreshTokenInvalidation(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -431,7 +469,7 @@ func TestRefreshTokenInvalidation(t *testing.T) {
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
// omit secret
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"refresh_token": parsed.RefreshToken,
|
||||
})
|
||||
resp = MakeRequest(t, req, http.StatusBadRequest)
|
||||
@@ -444,7 +482,7 @@ func TestRefreshTokenInvalidation(t *testing.T) {
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"refresh_token": "UNEXPECTED",
|
||||
})
|
||||
resp = MakeRequest(t, req, http.StatusBadRequest)
|
||||
@@ -457,7 +495,7 @@ func TestRefreshTokenInvalidation(t *testing.T) {
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"refresh_token": parsed.RefreshToken,
|
||||
})
|
||||
|
||||
@@ -484,13 +522,13 @@ func TestRefreshTokenInvalidation(t *testing.T) {
|
||||
assert.Equal(t, "token was already used", parsedError.ErrorDescription)
|
||||
}
|
||||
|
||||
func TestOAuthIntrospection(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
func testOAuthIntrospection(t *testing.T) {
|
||||
testOAuth2PrepareTestCode(t)
|
||||
req := NewRequestWithValues(t, "POST", "/login/oauth/access_token", map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": "da7da3ba-9a13-4167-856f-3899de0b0138",
|
||||
"client_secret": "4MK8Na6R55smdCY0WuCCumZ6hjRPnGY5saWVRHHjJiA=",
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": "authcode",
|
||||
"code_verifier": "N1Zo9-8Rfwhkt68r1r29ty8YwIraXR8eh_1Qwxg7yQXsonBt",
|
||||
})
|
||||
@@ -542,14 +580,12 @@ func TestOAuthIntrospection(t *testing.T) {
|
||||
assert.Contains(t, resp.Body.String(), "no valid authorization")
|
||||
}
|
||||
|
||||
func TestOAuth_GrantScopesReadUserFailRepos(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
func testOAuthGrantScopesReadUserFailRepos(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
appBody := api.CreateOAuth2ApplicationOptions{
|
||||
Name: "oauth-provider-scopes-test",
|
||||
RedirectURIs: []string{
|
||||
"a",
|
||||
"https://example.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
}
|
||||
@@ -573,7 +609,7 @@ func TestOAuth_GrantScopesReadUserFailRepos(t *testing.T) {
|
||||
|
||||
ctx := loginUser(t, user.Name)
|
||||
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=a&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=https://example.com&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeReq := NewRequest(t, "GET", authorizeURL)
|
||||
authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther)
|
||||
|
||||
@@ -583,7 +619,7 @@ func TestOAuth_GrantScopesReadUserFailRepos(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": app.ClientID,
|
||||
"client_secret": app.ClientSecret,
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": authcode,
|
||||
})
|
||||
accessTokenResp := ctx.MakeRequest(t, accessTokenReq, 200)
|
||||
@@ -622,14 +658,12 @@ func TestOAuth_GrantScopesReadUserFailRepos(t *testing.T) {
|
||||
assert.Contains(t, errorParsed.Message, "token does not have at least one of required scope(s), required=[read:repository]")
|
||||
}
|
||||
|
||||
func TestOAuth_GrantScopesReadRepositoryFailOrganization(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
func testOAuthGrantScopesReadRepositoryFailOrganization(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
||||
appBody := api.CreateOAuth2ApplicationOptions{
|
||||
Name: "oauth-provider-scopes-test",
|
||||
RedirectURIs: []string{
|
||||
"a",
|
||||
"https://example.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
}
|
||||
@@ -653,7 +687,7 @@ func TestOAuth_GrantScopesReadRepositoryFailOrganization(t *testing.T) {
|
||||
|
||||
ctx := loginUser(t, user.Name)
|
||||
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=a&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=https://example.com&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeReq := NewRequest(t, "GET", authorizeURL)
|
||||
authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther)
|
||||
|
||||
@@ -662,7 +696,7 @@ func TestOAuth_GrantScopesReadRepositoryFailOrganization(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": app.ClientID,
|
||||
"client_secret": app.ClientSecret,
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": authcode,
|
||||
})
|
||||
accessTokenResp := ctx.MakeRequest(t, accessTokenReq, http.StatusOK)
|
||||
@@ -760,15 +794,13 @@ func TestOAuth_GrantScopesReadRepositoryFailOrganization(t *testing.T) {
|
||||
assert.Contains(t, errorParsed.Message, "token does not have at least one of required scope(s), required=[read:user read:organization]")
|
||||
}
|
||||
|
||||
func TestOAuth_GrantScopesClaimPublicOnlyGroups(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
func testOAuthGrantScopesClaimPublicOnlyGroups(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
|
||||
|
||||
appBody := api.CreateOAuth2ApplicationOptions{
|
||||
Name: "oauth-provider-scopes-test",
|
||||
RedirectURIs: []string{
|
||||
"a",
|
||||
"https://example.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
}
|
||||
@@ -792,7 +824,7 @@ func TestOAuth_GrantScopesClaimPublicOnlyGroups(t *testing.T) {
|
||||
|
||||
ctx := loginUser(t, user.Name)
|
||||
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=a&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=https://example.com&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeReq := NewRequest(t, "GET", authorizeURL)
|
||||
authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther)
|
||||
|
||||
@@ -802,7 +834,7 @@ func TestOAuth_GrantScopesClaimPublicOnlyGroups(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": app.ClientID,
|
||||
"client_secret": app.ClientSecret,
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": authcode,
|
||||
})
|
||||
accessTokenResp := ctx.MakeRequest(t, accessTokenReq, http.StatusOK)
|
||||
@@ -860,15 +892,13 @@ func TestOAuth_GrantScopesClaimPublicOnlyGroups(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOAuth_GrantScopesClaimAllGroups(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
func testOAuthGrantScopesClaimAllGroups(t *testing.T) {
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
|
||||
|
||||
appBody := api.CreateOAuth2ApplicationOptions{
|
||||
Name: "oauth-provider-scopes-test",
|
||||
RedirectURIs: []string{
|
||||
"a",
|
||||
"https://example.com",
|
||||
},
|
||||
ConfidentialClient: true,
|
||||
}
|
||||
@@ -892,7 +922,7 @@ func TestOAuth_GrantScopesClaimAllGroups(t *testing.T) {
|
||||
|
||||
ctx := loginUser(t, user.Name)
|
||||
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=a&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeURL := fmt.Sprintf("/login/oauth/authorize?client_id=%s&redirect_uri=https://example.com&response_type=code&state=thestate", app.ClientID)
|
||||
authorizeReq := NewRequest(t, "GET", authorizeURL)
|
||||
authorizeResp := ctx.MakeRequest(t, authorizeReq, http.StatusSeeOther)
|
||||
|
||||
@@ -902,7 +932,7 @@ func TestOAuth_GrantScopesClaimAllGroups(t *testing.T) {
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": app.ClientID,
|
||||
"client_secret": app.ClientSecret,
|
||||
"redirect_uri": "a",
|
||||
"redirect_uri": "https://example.com",
|
||||
"code": authcode,
|
||||
})
|
||||
accessTokenResp := ctx.MakeRequest(t, accessTokenReq, http.StatusOK)
|
||||
@@ -998,7 +1028,7 @@ func addOAuth2Source(t *testing.T, authName string, cfg oauth2.Source) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func createMockServer() *httptest.Server {
|
||||
func createOAuth2MockProvider() *httptest.Server {
|
||||
var mockServer *httptest.Server
|
||||
mockServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
@@ -1017,10 +1047,8 @@ func createMockServer() *httptest.Server {
|
||||
return mockServer
|
||||
}
|
||||
|
||||
func TestSignInOauthCallbackSyncSSHKeys(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
mockServer := createMockServer()
|
||||
func testSignInOauthCallbackSyncSSHKeys(t *testing.T) {
|
||||
mockServer := createOAuth2MockProvider()
|
||||
defer mockServer.Close()
|
||||
|
||||
ctx := t.Context()
|
||||
@@ -1100,7 +1128,7 @@ func TestSignInOauthCallbackSyncSSHKeys(t *testing.T) {
|
||||
// Checks if an OAuth provider with spaces within the name does work,
|
||||
// with the encoding of its names in the URL (PR#37327)
|
||||
func testOAuthSourceSpecialChars(t *testing.T) {
|
||||
mockServer := createMockServer()
|
||||
mockServer := createOAuth2MockProvider()
|
||||
defer mockServer.Close()
|
||||
|
||||
addOAuth2Source(t, "test space", oauth2.Source{
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
"code.gitea.io/gitea/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -311,18 +312,25 @@ func TestUserSettingsApplications(t *testing.T) {
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
msg := strings.TrimSpace(doc.Find(".ui.message.flash-message").Text())
|
||||
assert.Equal(t, `form.RedirectURIs"ftp://127.0.0.1" is not a valid URL.`, msg)
|
||||
assert.Equal(t, `RedirectURIs: "ftp://127.0.0.1" is not a valid URL.`, msg)
|
||||
})
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
defer test.MockVariableValue(&setting.OAuth2.CustomSchemes, []string{"my-app"})()
|
||||
req := NewRequestWithValues(t, "POST", "/user/settings/applications/oauth2/2", map[string]string{
|
||||
"application_name": "Test native app",
|
||||
"redirect_uris": "http://127.0.0.1",
|
||||
"confidential_client": "false",
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
|
||||
req = NewRequestWithValues(t, "POST", "/user/settings/applications/oauth2/2", map[string]string{
|
||||
"application_name": "Test native app",
|
||||
"redirect_uris": "my-app://127.0.0.1",
|
||||
"confidential_client": "false",
|
||||
})
|
||||
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user