code.gitea.io/gitea@v1.22.3/routers/api/v1/repo/patch.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repo
     5  
     6  import (
     7  	"net/http"
     8  	"time"
     9  
    10  	"code.gitea.io/gitea/models"
    11  	git_model "code.gitea.io/gitea/models/git"
    12  	repo_model "code.gitea.io/gitea/models/repo"
    13  	"code.gitea.io/gitea/modules/git"
    14  	api "code.gitea.io/gitea/modules/structs"
    15  	"code.gitea.io/gitea/modules/web"
    16  	"code.gitea.io/gitea/services/context"
    17  	"code.gitea.io/gitea/services/repository/files"
    18  )
    19  
    20  // ApplyDiffPatch handles API call for applying a patch
    21  func ApplyDiffPatch(ctx *context.APIContext) {
    22  	// swagger:operation POST /repos/{owner}/{repo}/diffpatch repository repoApplyDiffPatch
    23  	// ---
    24  	// summary: Apply diff patch to repository
    25  	// consumes:
    26  	// - application/json
    27  	// produces:
    28  	// - application/json
    29  	// parameters:
    30  	// - name: owner
    31  	//   in: path
    32  	//   description: owner of the repo
    33  	//   type: string
    34  	//   required: true
    35  	// - name: repo
    36  	//   in: path
    37  	//   description: name of the repo
    38  	//   type: string
    39  	//   required: true
    40  	// - name: body
    41  	//   in: body
    42  	//   required: true
    43  	//   schema:
    44  	//     "$ref": "#/definitions/UpdateFileOptions"
    45  	// responses:
    46  	//   "200":
    47  	//     "$ref": "#/responses/FileResponse"
    48  	//   "404":
    49  	//     "$ref": "#/responses/notFound"
    50  	//   "423":
    51  	//     "$ref": "#/responses/repoArchivedError"
    52  	apiOpts := web.GetForm(ctx).(*api.ApplyDiffPatchFileOptions)
    53  
    54  	opts := &files.ApplyDiffPatchOptions{
    55  		Content:   apiOpts.Content,
    56  		SHA:       apiOpts.SHA,
    57  		Message:   apiOpts.Message,
    58  		OldBranch: apiOpts.BranchName,
    59  		NewBranch: apiOpts.NewBranchName,
    60  		Committer: &files.IdentityOptions{
    61  			Name:  apiOpts.Committer.Name,
    62  			Email: apiOpts.Committer.Email,
    63  		},
    64  		Author: &files.IdentityOptions{
    65  			Name:  apiOpts.Author.Name,
    66  			Email: apiOpts.Author.Email,
    67  		},
    68  		Dates: &files.CommitDateOptions{
    69  			Author:    apiOpts.Dates.Author,
    70  			Committer: apiOpts.Dates.Committer,
    71  		},
    72  		Signoff: apiOpts.Signoff,
    73  	}
    74  	if opts.Dates.Author.IsZero() {
    75  		opts.Dates.Author = time.Now()
    76  	}
    77  	if opts.Dates.Committer.IsZero() {
    78  		opts.Dates.Committer = time.Now()
    79  	}
    80  
    81  	if opts.Message == "" {
    82  		opts.Message = "apply-patch"
    83  	}
    84  
    85  	if !canWriteFiles(ctx, apiOpts.BranchName) {
    86  		ctx.Error(http.StatusInternalServerError, "ApplyPatch", repo_model.ErrUserDoesNotHaveAccessToRepo{
    87  			UserID:   ctx.Doer.ID,
    88  			RepoName: ctx.Repo.Repository.LowerName,
    89  		})
    90  		return
    91  	}
    92  
    93  	fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts)
    94  	if err != nil {
    95  		if models.IsErrUserCannotCommit(err) || models.IsErrFilePathProtected(err) {
    96  			ctx.Error(http.StatusForbidden, "Access", err)
    97  			return
    98  		}
    99  		if git_model.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
   100  			models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
   101  			ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
   102  			return
   103  		}
   104  		if git_model.IsErrBranchNotExist(err) || git.IsErrBranchNotExist(err) {
   105  			ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err)
   106  			return
   107  		}
   108  		ctx.Error(http.StatusInternalServerError, "ApplyPatch", err)
   109  	} else {
   110  		ctx.JSON(http.StatusCreated, fileResponse)
   111  	}
   112  }