Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Introduce OrgList and add LoadTeams, optimaze Load teams for orgs (go-gitea#32543)
  Refactor markup render system (go-gitea#32645)
  Fix: passkey login not working anymore (go-gitea#32623)
  Refactor some frontend problems (go-gitea#32646)
  Bypass vitest bug (go-gitea#32647)
  Fix race condition in mermaid observer (go-gitea#32599)
  Improve oauth2 scope token handling (go-gitea#32633)
  Fixed Issue of Review Menu Shown Behind (go-gitea#32631)
  Add github compatible tarball download API endpoints (go-gitea#32572)
  Fix markup render regression and fix some tests (go-gitea#32640)
  Fix sqlite3 test (go-gitea#32622)
  Strict pagination check (go-gitea#32548)
  • Loading branch information
zjjhot committed Nov 27, 2024
2 parents 444ebe9 + f49d823 commit 71463b8
Show file tree
Hide file tree
Showing 74 changed files with 798 additions and 563 deletions.
4 changes: 2 additions & 2 deletions models/activities/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -770,15 +770,15 @@ func DeleteIssueActions(ctx context.Context, repoID, issueID, issueIndex int64)
// CountActionCreatedUnixString count actions where created_unix is an empty string
func CountActionCreatedUnixString(ctx context.Context) (int64, error) {
if setting.Database.Type.IsSQLite3() {
return db.GetEngine(ctx).Where(`created_unix = ""`).Count(new(Action))
return db.GetEngine(ctx).Where(`created_unix = ''`).Count(new(Action))
}
return 0, nil
}

// FixActionCreatedUnixString set created_unix to zero if it is an empty string
func FixActionCreatedUnixString(ctx context.Context) (int64, error) {
if setting.Database.Type.IsSQLite3() {
res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ""`)
res, err := db.GetEngine(ctx).Exec(`UPDATE action SET created_unix = 0 WHERE created_unix = ''`)
if err != nil {
return 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion models/activities/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func TestConsistencyUpdateAction(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ID: int64(id),
})
_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id)
_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = '' WHERE id = ?`, id)
assert.NoError(t, err)
actions := make([]*activities_model.Action, 0, 1)
//
Expand Down
22 changes: 21 additions & 1 deletion models/auth/webauthn.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"

"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
)

Expand Down Expand Up @@ -89,14 +90,33 @@ func (cred *WebAuthnCredential) AfterLoad() {
// WebAuthnCredentialList is a list of *WebAuthnCredential
type WebAuthnCredentialList []*WebAuthnCredential

// newCredentialFlagsFromAuthenticatorFlags is copied from https://github.com/go-webauthn/webauthn/pull/337
// to convert protocol.AuthenticatorFlags to webauthn.CredentialFlags
func newCredentialFlagsFromAuthenticatorFlags(flags protocol.AuthenticatorFlags) webauthn.CredentialFlags {
return webauthn.CredentialFlags{
UserPresent: flags.HasUserPresent(),
UserVerified: flags.HasUserVerified(),
BackupEligible: flags.HasBackupEligible(),
BackupState: flags.HasBackupState(),
}
}

// ToCredentials will convert all WebAuthnCredentials to webauthn.Credentials
func (list WebAuthnCredentialList) ToCredentials() []webauthn.Credential {
func (list WebAuthnCredentialList) ToCredentials(defaultAuthFlags ...protocol.AuthenticatorFlags) []webauthn.Credential {
// TODO: at the moment, Gitea doesn't store or check the flags
// so we need to use the default flags from the authenticator to make the login validation pass
// In the future, we should:
// 1. store the flags when registering the credential
// 2. provide the stored flags when converting the credentials (for login)
// 3. for old users, still use this fallback to the default flags
defAuthFlags := util.OptionalArg(defaultAuthFlags)
creds := make([]webauthn.Credential, 0, len(list))
for _, cred := range list {
creds = append(creds, webauthn.Credential{
ID: cred.CredentialID,
PublicKey: cred.PublicKey,
AttestationType: cred.AttestationType,
Flags: newCredentialFlagsFromAuthenticatorFlags(defAuthFlags),
Authenticator: webauthn.Authenticator{
AAGUID: cred.AAGUID,
SignCount: cred.SignCount,
Expand Down
3 changes: 3 additions & 0 deletions models/db/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ func SyncAllTables() error {
func InitEngine(ctx context.Context) error {
xormEngine, err := newXORMEngine()
if err != nil {
if strings.Contains(err.Error(), "SQLite3 support") {
return fmt.Errorf(`sqlite3 requires: -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err)
}
return fmt.Errorf("failed to connect to database: %w", err)
}

Expand Down
2 changes: 1 addition & 1 deletion models/issues/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ func FindComments(ctx context.Context, opts *FindCommentsOptions) (CommentList,
sess.Join("INNER", "issue", "issue.id = comment.issue_id")
}

if opts.Page != 0 {
if opts.Page > 0 {
sess = db.SetSessionPagination(sess, opts)
}

Expand Down
2 changes: 1 addition & 1 deletion models/issues/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ func (issue *Issue) BlockedByDependencies(ctx context.Context, opts db.ListOptio
Where("issue_id = ?", issue.ID).
// sort by repo id then created date, with the issues of the same repo at the beginning of the list
OrderBy("CASE WHEN issue.repo_id = ? THEN 0 ELSE issue.repo_id END, issue.created_unix DESC", issue.RepoID)
if opts.Page != 0 {
if opts.Page > 0 {
sess = db.SetSessionPagination(sess, &opts)
}
err = sess.Find(&issueDeps)
Expand Down
2 changes: 1 addition & 1 deletion models/issues/issue_watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func GetIssueWatchers(ctx context.Context, issueID int64, listOptions db.ListOpt
And("`user`.prohibit_login = ?", false).
Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id")

if listOptions.Page != 0 {
if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
watches := make([]*IssueWatch, 0, listOptions.PageSize)
return watches, sess.Find(&watches)
Expand Down
4 changes: 2 additions & 2 deletions models/issues/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func GetLabelsByRepoID(ctx context.Context, repoID int64, sortType string, listO
sess.Asc("name")
}

if listOptions.Page != 0 {
if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}

Expand Down Expand Up @@ -462,7 +462,7 @@ func GetLabelsByOrgID(ctx context.Context, orgID int64, sortType string, listOpt
sess.Asc("name")
}

if listOptions.Page != 0 {
if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}

Expand Down
2 changes: 1 addition & 1 deletion models/issues/label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func TestDeleteIssueLabel(t *testing.T) {
PosterID: doerID,
IssueID: issueID,
LabelID: labelID,
}, `content=""`)
}, `content=''`)
label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
assert.EqualValues(t, expectedNumIssues, label.NumIssues)
assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues)
Expand Down
2 changes: 1 addition & 1 deletion models/issues/reaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func FindReactions(ctx context.Context, opts FindReactionsOptions) (ReactionList
Where(opts.toConds()).
In("reaction.`type`", setting.UI.Reactions).
Asc("reaction.issue_id", "reaction.comment_id", "reaction.created_unix", "reaction.id")
if opts.Page != 0 {
if opts.Page > 0 {
sess = db.SetSessionPagination(sess, &opts)

reactions := make([]*Reaction, 0, opts.PageSize)
Expand Down
2 changes: 1 addition & 1 deletion models/issues/stopwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func GetUIDsAndStopwatch(ctx context.Context) ([]*UserStopwatch, error) {
func GetUserStopwatches(ctx context.Context, userID int64, listOptions db.ListOptions) ([]*Stopwatch, error) {
sws := make([]*Stopwatch, 0, 8)
sess := db.GetEngine(ctx).Where("stopwatch.user_id = ?", userID)
if listOptions.Page != 0 {
if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}

Expand Down
2 changes: 1 addition & 1 deletion models/issues/tracked_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func (opts *FindTrackedTimesOptions) toSession(e db.Engine) db.Engine {

sess = sess.Where(opts.ToConds())

if opts.Page != 0 {
if opts.Page > 0 {
sess = db.SetSessionPagination(sess, opts)
}

Expand Down
8 changes: 4 additions & 4 deletions models/migrations/base/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/testlogger"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"xorm.io/xorm"
)

Expand All @@ -33,15 +33,15 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
ourSkip := 2
ourSkip += skip
deferFn := testlogger.PrintCurrentTest(t, ourSkip)
assert.NoError(t, unittest.SyncDirs(filepath.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
require.NoError(t, unittest.SyncDirs(filepath.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))

if err := deleteDB(); err != nil {
t.Errorf("unable to reset database: %v", err)
t.Fatalf("unable to reset database: %v", err)
return nil, deferFn
}

x, err := newXORMEngine()
assert.NoError(t, err)
require.NoError(t, err)
if x != nil {
oldDefer := deferFn
deferFn = func() {
Expand Down
25 changes: 25 additions & 0 deletions models/organization/org_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,31 @@ import (
"xorm.io/builder"
)

type OrgList []*Organization

func (orgs OrgList) LoadTeams(ctx context.Context) (map[int64]TeamList, error) {
if len(orgs) == 0 {
return map[int64]TeamList{}, nil
}

orgIDs := make([]int64, len(orgs))
for i, org := range orgs {
orgIDs[i] = org.ID
}

teams, err := GetTeamsByOrgIDs(ctx, orgIDs)
if err != nil {
return nil, err
}

teamMap := make(map[int64]TeamList, len(orgs))
for _, team := range teams {
teamMap[team.OrgID] = append(teamMap[team.OrgID], team)
}

return teamMap, nil
}

// SearchOrganizationsOptions options to filter organizations
type SearchOrganizationsOptions struct {
db.ListOptions
Expand Down
11 changes: 11 additions & 0 deletions models/organization/org_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,14 @@ func TestGetUserOrgsList(t *testing.T) {
assert.EqualValues(t, 2, orgs[0].NumRepos)
}
}

func TestLoadOrgListTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
orgs, err := organization.GetUserOrgsList(db.DefaultContext, &user_model.User{ID: 4})
assert.NoError(t, err)
assert.Len(t, orgs, 1)
teamsMap, err := organization.OrgList(orgs).LoadTeams(db.DefaultContext)
assert.NoError(t, err)
assert.Len(t, teamsMap, 1)
assert.Len(t, teamsMap[3], 5)
}
5 changes: 5 additions & 0 deletions models/organization/team_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,8 @@ func GetUserRepoTeams(ctx context.Context, orgID, userID, repoID int64) (teams T
And("team_repo.repo_id=?", repoID).
Find(&teams)
}

func GetTeamsByOrgIDs(ctx context.Context, orgIDs []int64) (TeamList, error) {
teams := make([]*Team, 0, 10)
return teams, db.GetEngine(ctx).Where(builder.In("org_id", orgIDs)).Find(&teams)
}
2 changes: 1 addition & 1 deletion models/user/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func SearchUsers(ctx context.Context, opts *SearchUserOptions) (users []*User, _

sessQuery := opts.toSearchQueryBase(ctx).OrderBy(opts.OrderBy.String())
defer sessQuery.Close()
if opts.Page != 0 {
if opts.Page > 0 {
sessQuery = db.SetSessionPagination(sessQuery, opts)
}

Expand Down
4 changes: 2 additions & 2 deletions models/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListO
And("`user`.type=?", UserTypeIndividual).
And(isUserVisibleToViewerCond(viewer))

if listOptions.Page != 0 {
if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)

users := make([]*User, 0, listOptions.PageSize)
Expand All @@ -352,7 +352,7 @@ func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListO
And("`user`.type IN (?, ?)", UserTypeIndividual, UserTypeOrganization).
And(isUserVisibleToViewerCond(viewer))

if listOptions.Page != 0 {
if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)

users := make([]*User, 0, listOptions.PageSize)
Expand Down
45 changes: 24 additions & 21 deletions modules/auth/webauthn/webauthn.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
package webauthn

import (
"context"
"encoding/binary"
"encoding/gob"

"code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"

"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
Expand Down Expand Up @@ -38,40 +39,42 @@ func Init() {
}
}

// User represents an implementation of webauthn.User based on User model
type User user_model.User
// user represents an implementation of webauthn.User based on User model
type user struct {
ctx context.Context
User *user_model.User

defaultAuthFlags protocol.AuthenticatorFlags
}

var _ webauthn.User = (*user)(nil)

func NewWebAuthnUser(ctx context.Context, u *user_model.User, defaultAuthFlags ...protocol.AuthenticatorFlags) webauthn.User {
return &user{ctx: ctx, User: u, defaultAuthFlags: util.OptionalArg(defaultAuthFlags)}
}

// WebAuthnID implements the webauthn.User interface
func (u *User) WebAuthnID() []byte {
func (u *user) WebAuthnID() []byte {
id := make([]byte, 8)
binary.PutVarint(id, u.ID)
binary.PutVarint(id, u.User.ID)
return id
}

// WebAuthnName implements the webauthn.User interface
func (u *User) WebAuthnName() string {
if u.LoginName == "" {
return u.Name
}
return u.LoginName
func (u *user) WebAuthnName() string {
return util.IfZero(u.User.LoginName, u.User.Name)
}

// WebAuthnDisplayName implements the webauthn.User interface
func (u *User) WebAuthnDisplayName() string {
return (*user_model.User)(u).DisplayName()
}

// WebAuthnIcon implements the webauthn.User interface
func (u *User) WebAuthnIcon() string {
return (*user_model.User)(u).AvatarLink(db.DefaultContext)
func (u *user) WebAuthnDisplayName() string {
return u.User.DisplayName()
}

// WebAuthnCredentials implements the webauthn.User interface
func (u *User) WebAuthnCredentials() []webauthn.Credential {
dbCreds, err := auth.GetWebAuthnCredentialsByUID(db.DefaultContext, u.ID)
func (u *user) WebAuthnCredentials() []webauthn.Credential {
dbCreds, err := auth.GetWebAuthnCredentialsByUID(u.ctx, u.User.ID)
if err != nil {
return nil
}

return dbCreds.ToCredentials()
return dbCreds.ToCredentials(u.defaultAuthFlags)
}
2 changes: 0 additions & 2 deletions modules/indexer/code/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

_ "github.com/mattn/go-sqlite3"
)

type codeSearchResult struct {
Expand Down
Loading

0 comments on commit 71463b8

Please sign in to comment.