@@ -729,6 +729,157 @@ func UploadFilePost(ctx *context.Context) {
729729 }
730730}
731731
732+ // UploadFilePostJson JSON response for uploading file
733+ func UploadFilePostJson (ctx * context.Context ) {
734+ // `renderCommitRights` is a poorly named; it's not responsible directly for rendering anything,
735+ // it returns a boolean
736+ form := web .GetForm (ctx ).(* auth.UploadRepoFileForm )
737+ canCommit := renderCommitRights (ctx )
738+ oldBranchName := ctx .Repo .BranchName
739+ branchName := oldBranchName
740+
741+ if form .CommitChoice == frmCommitChoiceNewBranch {
742+ branchName = form .NewBranchName
743+ }
744+
745+ form .TreePath = cleanUploadFileName (form .TreePath )
746+
747+ treeNames , _ := getParentTreeFields (form .TreePath )
748+ if len (treeNames ) == 0 {
749+ // We must at least have one element for user to input.
750+ treeNames = []string {"" }
751+ }
752+ response := make (map [string ]string )
753+
754+ if ctx .HasError () {
755+ response ["message" ] = "Failed to commit the files"
756+ ctx .JSON (http .StatusUnprocessableEntity , response )
757+ log .Error ("failed to commit files" )
758+ return
759+ }
760+
761+ if oldBranchName != branchName {
762+ if _ , err := repo_module .GetBranch (ctx .Repo .Repository , branchName ); err == nil {
763+ response ["message" ] = "Branch already exists"
764+ ctx .JSON (http .StatusConflict , response )
765+ return
766+ }
767+ } else if ! canCommit {
768+ response ["message" ] = "Can't commit to protected branch"
769+ ctx .JSON (http .StatusUnauthorized , response )
770+ return
771+ }
772+
773+ var newTreePath string
774+ for _ , part := range treeNames {
775+ newTreePath = path .Join (newTreePath , part )
776+ entry , err := ctx .Repo .Commit .GetTreeEntryByPath (newTreePath )
777+ if err != nil {
778+ if git .IsErrNotExist (err ) {
779+ // Means there is no item with that name, so we're good
780+ break
781+ }
782+ response ["message" ] = "Something went wrong!"
783+ ctx .JSON (http .StatusInternalServerError , response )
784+ return
785+ }
786+
787+ // User can only upload files to a directory.
788+ if ! entry .IsDir () {
789+ ctx .Data ["Err_TreePath" ] = true
790+ ctx .RenderWithErr (ctx .Tr ("repo.editor.directory_is_a_file" , part ), tplUploadFile , & form )
791+ response ["message" ] = "A file with the same name of the new directory already exists."
792+ ctx .JSON (http .StatusConflict , response )
793+ return
794+ }
795+ }
796+
797+ message := strings .TrimSpace (form .CommitSummary )
798+ if len (message ) == 0 {
799+ message = ctx .Tr ("repo.editor.upload_files_to_dir" , form .TreePath )
800+ }
801+
802+ form .CommitMessage = strings .TrimSpace (form .CommitMessage )
803+ if len (form .CommitMessage ) > 0 {
804+ message += "\n \n " + form .CommitMessage
805+ }
806+
807+ if err := repofiles .UploadRepoFiles (ctx .Repo .Repository , ctx .User , & repofiles.UploadRepoFileOptions {
808+ LastCommitID : ctx .Repo .CommitID ,
809+ OldBranch : oldBranchName ,
810+ NewBranch : branchName ,
811+ TreePath : form .TreePath ,
812+ Message : message ,
813+ Files : form .Files ,
814+ }); err != nil {
815+ if models .IsErrLFSFileLocked (err ) {
816+ response ["message" ] = ctx .Tr ("repo.editor.upload_file_is_locked" )
817+ ctx .JSON (http .StatusUnauthorized , response )
818+ } else if models .IsErrFilenameInvalid (err ) {
819+ response ["message" ] = ctx .Tr ("repo.editor.filename_is_invalid" )
820+ ctx .JSON (http .StatusUnprocessableEntity , response )
821+ } else if models .IsErrFilePathInvalid (err ) {
822+ fileErr := err .(models.ErrFilePathInvalid )
823+ switch fileErr .Type {
824+ case git .EntryModeSymlink :
825+ response ["message" ] = ctx .Tr ("repo.editor.file_is_a_symlink" , fileErr .Path )
826+ ctx .JSON (http .StatusConflict , response )
827+ case git .EntryModeTree :
828+ response ["message" ] = ctx .Tr ("repo.editor.filename_is_a_directory" , fileErr .Path )
829+ ctx .JSON (http .StatusConflict , response )
830+ case git .EntryModeBlob :
831+ response ["message" ] = ctx .Tr ("repo.editor.directory_is_a_file" , fileErr .Path )
832+ ctx .JSON (http .StatusConflict , response )
833+ default :
834+ response ["message" ] = "Something went wrong"
835+ ctx .JSON (http .StatusInternalServerError , response )
836+ }
837+ } else if models .IsErrRepoFileAlreadyExists (err ) {
838+ response ["message" ] = ctx .Tr ("repo.editor.file_already_exists" , form .TreePath )
839+ ctx .JSON (http .StatusConflict , response )
840+ } else if git .IsErrBranchNotExist (err ) {
841+ branchErr := err .(git.ErrBranchNotExist )
842+ response ["message" ] = ctx .Tr ("repo.editor.branch_does_not_exist" , branchErr .Name )
843+ ctx .JSON (http .StatusNotFound , response )
844+ } else if models .IsErrBranchAlreadyExists (err ) {
845+ // For when a user specifies a new branch that already exists
846+ branchErr := err .(models.ErrBranchAlreadyExists )
847+ response ["message" ] = ctx .Tr ("repo.editor.branch_already_exists" , branchErr .BranchName )
848+ ctx .JSON (http .StatusConflict , response )
849+ } else if git .IsErrPushOutOfDate (err ) {
850+ response ["message" ] = ctx .Tr (
851+ "repo.editor.file_changed_while_editing" ,
852+ ctx .Repo .RepoLink + "/compare/" + ctx .Repo .CommitID + "..." + form .NewBranchName ,
853+ )
854+ ctx .JSON (http .StatusConflict , response )
855+ } else if git .IsErrPushRejected (err ) {
856+ errPushRej := err .(* git.ErrPushRejected )
857+ if len (errPushRej .Message ) == 0 {
858+ response ["message" ] = ctx .Tr ("repo.editor.push_rejected_no_message" )
859+ ctx .JSON (http .StatusConflict , response )
860+ } else {
861+ response ["response" ] = ctx .Tr ("repo.editor.push_rejected" , utils .SanitizeFlashErrorString (errPushRej .Message ))
862+ ctx .JSON (http .StatusConflict , response )
863+ }
864+ } else {
865+ // os.ErrNotExist - upload file missing in the intervening time?!
866+ log .Error (
867+ "Error during upload to repo: %-v to filepath: %s on %s from %s: %v" ,
868+ ctx .Repo .Repository ,
869+ form .TreePath ,
870+ oldBranchName ,
871+ form .NewBranchName ,
872+ err ,
873+ )
874+ response ["message" ] = ctx .Tr ("repo.editor.unable_to_upload_files" , form .TreePath , err )
875+ ctx .JSON (http .StatusInternalServerError , response )
876+ }
877+ return
878+ }
879+ response ["message" ] = "Committed files successfully."
880+ ctx .JSON (http .StatusCreated , response )
881+ }
882+
732883func cleanUploadFileName (name string ) string {
733884 // Rebase the filename
734885 name = strings .Trim (path .Clean ("/" + name ), " /" )
0 commit comments