Prevent upload (overwrite) of lfs locked file (#8769)
* Check if file is locked on upload file commit. * Better user message if file is locked. * Check lfs lock before creating temporary repository. fix some errors. * move lines * Add comment that enabled setting is checked.
This commit is contained in:
parent
9d663dfde6
commit
232340f5e3
4 changed files with 40 additions and 8 deletions
|
@ -647,6 +647,23 @@ func (err ErrLFSLockAlreadyExist) Error() string {
|
||||||
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
|
return fmt.Sprintf("lfs lock already exists [rid: %d, path: %s]", err.RepoID, err.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ErrLFSFileLocked represents a "LFSFileLocked" kind of error.
|
||||||
|
type ErrLFSFileLocked struct {
|
||||||
|
RepoID int64
|
||||||
|
Path string
|
||||||
|
UserName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrLFSFileLocked checks if an error is a ErrLFSFileLocked.
|
||||||
|
func IsErrLFSFileLocked(err error) bool {
|
||||||
|
_, ok := err.(ErrLFSFileLocked)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrLFSFileLocked) Error() string {
|
||||||
|
return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path)
|
||||||
|
}
|
||||||
|
|
||||||
// __________ .__ __
|
// __________ .__ __
|
||||||
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
|
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
|
||||||
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
|
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |
|
||||||
|
|
|
@ -55,6 +55,23 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||||
return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err)
|
return fmt.Errorf("GetUploadsByUUIDs [uuids: %v]: %v", opts.Files, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
names := make([]string, len(uploads))
|
||||||
|
infos := make([]uploadInfo, len(uploads))
|
||||||
|
for i, upload := range uploads {
|
||||||
|
// Check file is not lfs locked, will return nil if lock setting not enabled
|
||||||
|
filepath := path.Join(opts.TreePath, upload.Name)
|
||||||
|
lfsLock, err := repo.GetTreePathLock(filepath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if lfsLock != nil && lfsLock.OwnerID != doer.ID {
|
||||||
|
return models.ErrLFSFileLocked{RepoID: repo.ID, Path: filepath, UserName: lfsLock.Owner.Name}
|
||||||
|
}
|
||||||
|
|
||||||
|
names[i] = upload.Name
|
||||||
|
infos[i] = uploadInfo{upload: upload}
|
||||||
|
}
|
||||||
|
|
||||||
t, err := NewTemporaryUploadRepository(repo)
|
t, err := NewTemporaryUploadRepository(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -67,13 +84,6 @@ func UploadRepoFiles(repo *models.Repository, doer *models.User, opts *UploadRep
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
names := make([]string, len(uploads))
|
|
||||||
infos := make([]uploadInfo, len(uploads))
|
|
||||||
for i, upload := range uploads {
|
|
||||||
names[i] = upload.Name
|
|
||||||
infos[i] = uploadInfo{upload: upload}
|
|
||||||
}
|
|
||||||
|
|
||||||
var filename2attribute2info map[string]map[string]string
|
var filename2attribute2info map[string]map[string]string
|
||||||
if setting.LFS.StartServer {
|
if setting.LFS.StartServer {
|
||||||
filename2attribute2info, err = t.CheckAttribute("filter", names...)
|
filename2attribute2info, err = t.CheckAttribute("filter", names...)
|
||||||
|
|
|
@ -742,6 +742,7 @@ editor.no_changes_to_show = There are no changes to show.
|
||||||
editor.fail_to_update_file = Failed to update/create file '%s' with error: %v
|
editor.fail_to_update_file = Failed to update/create file '%s' with error: %v
|
||||||
editor.add_subdir = Add a directory…
|
editor.add_subdir = Add a directory…
|
||||||
editor.unable_to_upload_files = Failed to upload files to '%s' with error: %v
|
editor.unable_to_upload_files = Failed to upload files to '%s' with error: %v
|
||||||
|
editor.upload_file_is_locked = File '%s' is locked by %s.
|
||||||
editor.upload_files_to_dir = Upload files to '%s'
|
editor.upload_files_to_dir = Upload files to '%s'
|
||||||
editor.cannot_commit_to_protected_branch = Cannot commit to protected branch '%s'.
|
editor.cannot_commit_to_protected_branch = Cannot commit to protected branch '%s'.
|
||||||
|
|
||||||
|
|
|
@ -585,7 +585,11 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) {
|
||||||
Files: form.Files,
|
Files: form.Files,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
ctx.Data["Err_TreePath"] = true
|
ctx.Data["Err_TreePath"] = true
|
||||||
|
if models.IsErrLFSFileLocked(err) {
|
||||||
|
ctx.RenderWithErr(ctx.Tr("repo.editor.upload_file_is_locked", err.(models.ErrLFSFileLocked).Path, err.(models.ErrLFSFileLocked).UserName), tplUploadFile, &form)
|
||||||
|
} else {
|
||||||
ctx.RenderWithErr(ctx.Tr("repo.editor.unable_to_upload_files", form.TreePath, err), tplUploadFile, &form)
|
ctx.RenderWithErr(ctx.Tr("repo.editor.unable_to_upload_files", form.TreePath, err), tplUploadFile, &form)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue