[TESTS] auth LinkAccount test coverage (squash)

(cherry picked from commit a2b2e3066b)
This commit is contained in:
Earl Warren 2023-06-27 11:50:09 +02:00
parent 94377ab80f
commit 4cd5e7214b
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
3 changed files with 152 additions and 20 deletions

View file

@ -5,6 +5,7 @@
package auth package auth
import ( import (
"context"
"fmt" "fmt"
"reflect" "reflect"
@ -306,6 +307,17 @@ func GetSourceByID(id int64) (*Source, error) {
return source, nil return source, nil
} }
func GetSourceByName(ctx context.Context, name string) (*Source, error) {
source := &Source{}
has, err := db.GetEngine(ctx).Where("name = ?", name).Get(source)
if err != nil {
return nil, err
} else if !has {
return nil, ErrSourceNotExist{}
}
return source, nil
}
// UpdateSource updates a Source record in DB. // UpdateSource updates a Source record in DB.
func UpdateSource(source *Source) error { func UpdateSource(source *Source) error {
var originalSource *Source var originalSource *Source

View file

@ -35,10 +35,12 @@ import (
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers" "code.gitea.io/gitea/routers"
"code.gitea.io/gitea/services/auth/source/oauth2"
user_service "code.gitea.io/gitea/services/user" user_service "code.gitea.io/gitea/services/user"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
goth_gitlab "github.com/markbates/goth/providers/gitlab"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/xeipuuv/gojsonschema" "github.com/xeipuuv/gojsonschema"
) )
@ -242,6 +244,46 @@ func getUserToken(t testing.TB, userName string, scope ...auth.AccessTokenScope)
return getTokenForLoggedInUser(t, loginUser(t, userName), scope...) return getTokenForLoggedInUser(t, loginUser(t, userName), scope...)
} }
func addAuthSource(t *testing.T, payload map[string]string) *auth.Source {
session := loginUser(t, "user1")
payload["_csrf"] = GetCSRF(t, session, "/admin/auths/new")
req := NewRequestWithValues(t, "POST", "/admin/auths/new", payload)
session.MakeRequest(t, req, http.StatusSeeOther)
source, err := auth.GetSourceByName(context.Background(), payload["name"])
assert.NoError(t, err)
return source
}
func authSourcePayloadOAuth2(name string) map[string]string {
return map[string]string{
"type": fmt.Sprintf("%d", auth.OAuth2),
"name": name,
"is_active": "on",
}
}
func authSourcePayloadGitLab(name string) map[string]string {
payload := authSourcePayloadOAuth2(name)
payload["oauth2_provider"] = "gitlab"
return payload
}
func authSourcePayloadGitLabCustom(name string) map[string]string {
payload := authSourcePayloadGitLab(name)
payload["oauth2_use_custom_url"] = "on"
payload["oauth2_auth_url"] = goth_gitlab.AuthURL
payload["oauth2_token_url"] = goth_gitlab.TokenURL
payload["oauth2_profile_url"] = goth_gitlab.ProfileURL
return payload
}
func authSourcePayloadOIDC(name string) map[string]string {
payload := authSourcePayloadOAuth2(name)
payload["oauth2_provider"] = (&oauth2.OpenIDProvider{}).Name()
payload["open_id_connect_auto_discovery_url"] = codebergURL + "/.well-known/openid-configuration"
return payload
}
func createUser(ctx context.Context, t testing.TB, user *user_model.User) func() { func createUser(ctx context.Context, t testing.TB, user *user_model.User) func() {
user.MustChangePassword = false user.MustChangePassword = false
user.LowerName = strings.ToLower(user.Name) user.LowerName = strings.ToLower(user.Name)

View file

@ -1,12 +1,15 @@
// Copyright 2023 The Forgejo Authors. All rights reserved. // SPDX-FileCopyrightText: Copyright the Forgejo contributors
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
package integration package integration
import ( import (
"context"
"net/http" "net/http"
"testing" "testing"
auth_model "code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user"
gitea_context "code.gitea.io/gitea/modules/context" gitea_context "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/tests" "code.gitea.io/gitea/tests"
@ -14,42 +17,115 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
const codebergURL = "https://codeberg.org"
func TestLinkAccountChoose(t *testing.T) { func TestLinkAccountChoose(t *testing.T) {
defer tests.PrepareTestEnv(t)() defer tests.PrepareTestEnv(t)()
username := "linkaccountuser" ctx := context.Background()
email := "linkaccountuser@example.com"
password := "linkaccountuser" // Create a OIDC source and a known OAuth2 source
defer createUser(t, username, email, password)() codebergName := "codeberg"
codeberg := addAuthSource(t, authSourcePayloadOIDC(codebergName))
gitlabName := "gitlab"
gitlab := addAuthSource(t, authSourcePayloadGitLabCustom(gitlabName))
//
// A local user
//
localUser := &user_model.User{
Name: "linkaccountuser",
Email: "linkaccountuser@example.com",
Passwd: "linkaccountuser",
Type: user_model.UserTypeIndividual,
}
defer createUser(ctx, t, localUser)()
//
// A Codeberg user via OIDC
//
userCodebergUserID := "1234"
userCodeberg := &user_model.User{
Name: "linkaccountcodeberguser",
Email: "linkaccountcodeberguser@example.com",
Passwd: "linkaccountcodeberguser",
Type: user_model.UserTypeIndividual,
LoginType: auth_model.OAuth2,
LoginSource: codeberg.ID,
LoginName: userCodebergUserID,
}
defer createUser(ctx, t, userCodeberg)()
//
// A Gitlab user
//
userGitLabUserID := "5678"
userGitLab := &user_model.User{
Name: "linkaccountgitlabuser",
Email: "linkaccountgitlabuser@example.com",
Passwd: "linkaccountgitlabuser",
Type: user_model.UserTypeIndividual,
LoginType: auth_model.OAuth2,
LoginSource: gitlab.ID,
LoginName: userGitLabUserID,
}
defer createUser(ctx, t, userGitLab)()
defer func() { defer func() {
testMiddlewareHook = nil testMiddlewareHook = nil
}() }()
for _, testCase := range []struct { for _, testCase := range []struct {
title string
gothUser goth.User gothUser goth.User
signupTab string signupTab string
signinTab string signinTab string
}{ }{
{ {
gothUser: goth.User{}, title: "No existing user",
gothUser: goth.User{
Provider: codebergName,
},
signupTab: "item active", signupTab: "item active",
signinTab: "item ", signinTab: "item ",
}, },
{ {
title: "Matched local user",
gothUser: goth.User{ gothUser: goth.User{
Email: email, Provider: codebergName,
Email: localUser.Email,
},
signupTab: "item ",
signinTab: "item active",
},
{
title: "Matched Codeberg local user",
gothUser: goth.User{
Provider: codebergName,
UserID: userCodebergUserID,
Email: userCodeberg.Email,
},
signupTab: "item ",
signinTab: "item active",
},
{
title: "Matched GitLab local user",
gothUser: goth.User{
Provider: gitlabName,
UserID: userGitLabUserID,
Email: userGitLab.Email,
}, },
signupTab: "item ", signupTab: "item ",
signinTab: "item active", signinTab: "item active",
}, },
} { } {
t.Run(testCase.title, func(t *testing.T) {
testMiddlewareHook = func(ctx *gitea_context.Context) { testMiddlewareHook = func(ctx *gitea_context.Context) {
ctx.Session.Set("linkAccountGothUser", testCase.gothUser) ctx.Session.Set("linkAccountGothUser", testCase.gothUser)
} }
req := NewRequest(t, "GET", "/user/link_account") req := NewRequest(t, "GET", "/user/link_account")
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, resp.Code, http.StatusOK, resp.Body) if assert.Equal(t, resp.Code, http.StatusOK, resp.Body) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
class, exists := doc.Find(`.new-menu-inner .item[data-tab="auth-link-signup-tab"]`).Attr("class") class, exists := doc.Find(`.new-menu-inner .item[data-tab="auth-link-signup-tab"]`).Attr("class")
@ -60,4 +136,6 @@ func TestLinkAccountChoose(t *testing.T) {
assert.True(t, exists) assert.True(t, exists)
assert.Equal(t, testCase.signinTab, class) assert.Equal(t, testCase.signinTab, class)
} }
})
}
} }