Skip to content

Commit cdb48f7

Browse files
authored
Merge branch 'main' into lunny/upgrade_certmanager
2 parents 0c518a5 + 385dc6a commit cdb48f7

File tree

3 files changed

+57
-26
lines changed

3 files changed

+57
-26
lines changed

models/lfs.go

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ package models
77
import (
88
"context"
99
"errors"
10+
"fmt"
1011

1112
"code.gitea.io/gitea/models/db"
1213
repo_model "code.gitea.io/gitea/models/repo"
1314
user_model "code.gitea.io/gitea/models/user"
1415
"code.gitea.io/gitea/modules/lfs"
16+
"code.gitea.io/gitea/modules/log"
1517
"code.gitea.io/gitea/modules/timeutil"
1618

1719
"xorm.io/builder"
@@ -145,6 +147,11 @@ func LFSObjectAccessible(user *user_model.User, oid string) (bool, error) {
145147
return count > 0, err
146148
}
147149

150+
// LFSObjectIsAssociated checks if a provided Oid is associated
151+
func LFSObjectIsAssociated(oid string) (bool, error) {
152+
return db.GetEngine(db.DefaultContext).Exist(&LFSMetaObject{Pointer: lfs.Pointer{Oid: oid}})
153+
}
154+
148155
// LFSAutoAssociate auto associates accessible LFSMetaObjects
149156
func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int64) error {
150157
ctx, committer, err := db.TxContext()
@@ -162,23 +169,39 @@ func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int6
162169
oidMap[meta.Oid] = meta
163170
}
164171

165-
cond := builder.NewCond()
166172
if !user.IsAdmin {
167-
cond = builder.In("`lfs_meta_object`.repository_id",
168-
builder.Select("`repository`.id").From("repository").Where(accessibleRepositoryCondition(user)))
169-
}
170-
newMetas := make([]*LFSMetaObject, 0, len(metas))
171-
if err := sess.Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas); err != nil {
172-
return err
173-
}
174-
for i := range newMetas {
175-
newMetas[i].Size = oidMap[newMetas[i].Oid].Size
176-
newMetas[i].RepositoryID = repoID
177-
}
178-
if err := db.Insert(ctx, newMetas); err != nil {
179-
return err
173+
newMetas := make([]*LFSMetaObject, 0, len(metas))
174+
cond := builder.In(
175+
"`lfs_meta_object`.repository_id",
176+
builder.Select("`repository`.id").From("repository").Where(accessibleRepositoryCondition(user)),
177+
)
178+
err = sess.Cols("oid").Where(cond).In("oid", oids...).GroupBy("oid").Find(&newMetas)
179+
if err != nil {
180+
return err
181+
}
182+
if len(newMetas) != len(oidMap) {
183+
return fmt.Errorf("unable collect all LFS objects from database, expected %d, actually %d", len(oidMap), len(newMetas))
184+
}
185+
for i := range newMetas {
186+
newMetas[i].Size = oidMap[newMetas[i].Oid].Size
187+
newMetas[i].RepositoryID = repoID
188+
}
189+
if err = db.Insert(ctx, newMetas); err != nil {
190+
return err
191+
}
192+
} else {
193+
// admin can associate any LFS object to any repository, and we do not care about errors (eg: duplicated unique key),
194+
// even if error occurs, it won't hurt users and won't make things worse
195+
for i := range metas {
196+
_, err = sess.Insert(&LFSMetaObject{
197+
Pointer: lfs.Pointer{Oid: metas[i].Oid, Size: metas[i].Size},
198+
RepositoryID: repoID,
199+
})
200+
if err != nil {
201+
log.Warn("failed to insert LFS meta object into database, err=%v", err)
202+
}
203+
}
180204
}
181-
182205
return committer.Commit()
183206
}
184207

routers/web/repo/lfs.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -421,12 +421,13 @@ func LFSPointerFiles(ctx *context.Context) {
421421
var numAssociated, numNoExist, numAssociatable int
422422

423423
type pointerResult struct {
424-
SHA string
425-
Oid string
426-
Size int64
427-
InRepo bool
428-
Exists bool
429-
Accessible bool
424+
SHA string
425+
Oid string
426+
Size int64
427+
InRepo bool
428+
Exists bool
429+
Accessible bool
430+
Associatable bool
430431
}
431432

432433
results := []pointerResult{}
@@ -461,22 +462,29 @@ func LFSPointerFiles(ctx *context.Context) {
461462
// Can we fix?
462463
// OK well that's "simple"
463464
// - we need to check whether current user has access to a repo that has access to the file
464-
result.Accessible, err = models.LFSObjectAccessible(ctx.User, pointerBlob.Oid)
465+
result.Associatable, err = models.LFSObjectAccessible(ctx.User, pointerBlob.Oid)
465466
if err != nil {
466467
return err
467468
}
468-
} else {
469-
result.Accessible = true
469+
if !result.Associatable {
470+
associated, err := models.LFSObjectIsAssociated(pointerBlob.Oid)
471+
if err != nil {
472+
return err
473+
}
474+
result.Associatable = !associated
475+
}
470476
}
471477
}
472478

479+
result.Accessible = result.InRepo || result.Associatable
480+
473481
if result.InRepo {
474482
numAssociated++
475483
}
476484
if !result.Exists {
477485
numNoExist++
478486
}
479-
if !result.InRepo && result.Accessible {
487+
if result.Associatable {
480488
numAssociatable++
481489
}
482490

templates/repo/settings/lfs_pointers.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<form class="ui form" method="post" action="{{$.Link}}/associate">
1212
{{.CsrfTokenHtml}}
1313
{{range .Pointers}}
14-
{{if and (not .InRepo) .Exists .Accessible}}
14+
{{if .Associatable}}
1515
<input type="hidden" name="oid" value="{{.Oid}} {{.Size}}"/>
1616
{{end}}
1717
{{end}}

0 commit comments

Comments
 (0)