Skip to content

Commit 28f9b31

Browse files
authored
Updates to the API for archived repos (#27149)
1 parent 7520cd6 commit 28f9b31

File tree

22 files changed

+249
-34
lines changed

22 files changed

+249
-34
lines changed

models/git/protected_branch.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,11 @@ type WhitelistOptions struct {
315315
// This function also performs check if whitelist user and team's IDs have been changed
316316
// to avoid unnecessary whitelist delete and regenerate.
317317
func UpdateProtectBranch(ctx context.Context, repo *repo_model.Repository, protectBranch *ProtectedBranch, opts WhitelistOptions) (err error) {
318+
err = repo.MustNotBeArchived()
319+
if err != nil {
320+
return err
321+
}
322+
318323
if err = repo.LoadOwner(ctx); err != nil {
319324
return fmt.Errorf("LoadOwner: %v", err)
320325
}
@@ -445,9 +450,14 @@ func updateTeamWhitelist(ctx context.Context, repo *repo_model.Repository, curre
445450
}
446451

447452
// DeleteProtectedBranch removes ProtectedBranch relation between the user and repository.
448-
func DeleteProtectedBranch(ctx context.Context, repoID, id int64) (err error) {
453+
func DeleteProtectedBranch(ctx context.Context, repo *repo_model.Repository, id int64) (err error) {
454+
err = repo.MustNotBeArchived()
455+
if err != nil {
456+
return err
457+
}
458+
449459
protectedBranch := &ProtectedBranch{
450-
RepoID: repoID,
460+
RepoID: repo.ID,
451461
ID: id,
452462
}
453463

models/repo/repo.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ func (err ErrUserDoesNotHaveAccessToRepo) Unwrap() error {
4747
return util.ErrPermissionDenied
4848
}
4949

50+
type ErrRepoIsArchived struct {
51+
Repo *Repository
52+
}
53+
54+
func (err ErrRepoIsArchived) Error() string {
55+
return fmt.Sprintf("%s is archived", err.Repo.LogString())
56+
}
57+
5058
var (
5159
reservedRepoNames = []string{".", "..", "-"}
5260
reservedRepoPatterns = []string{"*.git", "*.wiki", "*.rss", "*.atom"}
@@ -654,6 +662,14 @@ func (repo *Repository) GetTrustModel() TrustModelType {
654662
return trustModel
655663
}
656664

665+
// MustNotBeArchived returns ErrRepoIsArchived if the repo is archived
666+
func (repo *Repository) MustNotBeArchived() error {
667+
if repo.IsArchived {
668+
return ErrRepoIsArchived{Repo: repo}
669+
}
670+
return nil
671+
}
672+
657673
// __________ .__ __
658674
// \______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__.
659675
// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | |

modules/context/api.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ type APIRedirect struct{}
101101
// swagger:response string
102102
type APIString string
103103

104+
// APIRepoArchivedError is an error that is raised when an archived repo should be modified
105+
// swagger:response repoArchivedError
106+
type APIRepoArchivedError struct {
107+
APIError
108+
}
109+
104110
// ServerError responds with error message, status is 500
105111
func (ctx *APIContext) ServerError(title string, err error) {
106112
ctx.Error(http.StatusInternalServerError, title, err)

routers/api/v1/api.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ func mustEnableWiki(ctx *context.APIContext) {
675675

676676
func mustNotBeArchived(ctx *context.APIContext) {
677677
if ctx.Repo.Repository.IsArchived {
678-
ctx.NotFound()
678+
ctx.Error(http.StatusLocked, "RepoArchived", fmt.Errorf("%s is archived", ctx.Repo.Repository.LogString()))
679679
return
680680
}
681681
}
@@ -1108,23 +1108,23 @@ func Routes() *web.Route {
11081108
m.Group("/branches", func() {
11091109
m.Get("", repo.ListBranches)
11101110
m.Get("/*", repo.GetBranch)
1111-
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), repo.DeleteBranch)
1112-
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
1111+
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteBranch)
1112+
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
11131113
}, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode))
11141114
m.Group("/branch_protections", func() {
11151115
m.Get("", repo.ListBranchProtections)
1116-
m.Post("", bind(api.CreateBranchProtectionOption{}), repo.CreateBranchProtection)
1116+
m.Post("", bind(api.CreateBranchProtectionOption{}), mustNotBeArchived, repo.CreateBranchProtection)
11171117
m.Group("/{name}", func() {
11181118
m.Get("", repo.GetBranchProtection)
1119-
m.Patch("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection)
1119+
m.Patch("", bind(api.EditBranchProtectionOption{}), mustNotBeArchived, repo.EditBranchProtection)
11201120
m.Delete("", repo.DeleteBranchProtection)
11211121
})
11221122
}, reqToken(), reqAdmin())
11231123
m.Group("/tags", func() {
11241124
m.Get("", repo.ListTags)
11251125
m.Get("/*", repo.GetTag)
1126-
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), bind(api.CreateTagOption{}), repo.CreateTag)
1127-
m.Delete("/*", reqToken(), repo.DeleteTag)
1126+
m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateTagOption{}), repo.CreateTag)
1127+
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteTag)
11281128
}, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true))
11291129
m.Group("/keys", func() {
11301130
m.Combo("").Get(repo.ListDeployKeys).
@@ -1245,15 +1245,15 @@ func Routes() *web.Route {
12451245
m.Get("/tags/{sha}", repo.GetAnnotatedTag)
12461246
m.Get("/notes/{sha}", repo.GetNote)
12471247
}, context.ReferencesGitRepo(true), reqRepoReader(unit.TypeCode))
1248-
m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), repo.ApplyDiffPatch)
1248+
m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), mustNotBeArchived, repo.ApplyDiffPatch)
12491249
m.Group("/contents", func() {
12501250
m.Get("", repo.GetContentsList)
1251-
m.Post("", reqToken(), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, repo.ChangeFiles)
1251+
m.Post("", reqToken(), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.ChangeFiles)
12521252
m.Get("/*", repo.GetContents)
12531253
m.Group("/*", func() {
1254-
m.Post("", bind(api.CreateFileOptions{}), reqRepoBranchWriter, repo.CreateFile)
1255-
m.Put("", bind(api.UpdateFileOptions{}), reqRepoBranchWriter, repo.UpdateFile)
1256-
m.Delete("", bind(api.DeleteFileOptions{}), reqRepoBranchWriter, repo.DeleteFile)
1254+
m.Post("", bind(api.CreateFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.CreateFile)
1255+
m.Put("", bind(api.UpdateFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.UpdateFile)
1256+
m.Delete("", bind(api.DeleteFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.DeleteFile)
12571257
}, reqToken())
12581258
}, reqRepoReader(unit.TypeCode))
12591259
m.Get("/signing-key.gpg", misc.SigningKey)

routers/api/v1/repo/branch.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,13 @@ func DeleteBranch(ctx *context.APIContext) {
117117
// "$ref": "#/responses/error"
118118
// "404":
119119
// "$ref": "#/responses/notFound"
120-
120+
// "423":
121+
// "$ref": "#/responses/repoArchivedError"
121122
if ctx.Repo.Repository.IsEmpty {
122123
ctx.Error(http.StatusNotFound, "", "Git Repository is empty.")
123124
return
124125
}
125126

126-
if ctx.Repo.Repository.IsArchived {
127-
ctx.Error(http.StatusForbidden, "", "Git Repository is archived.")
128-
return
129-
}
130-
131127
if ctx.Repo.Repository.IsMirror {
132128
ctx.Error(http.StatusForbidden, "", "Git Repository is a mirror.")
133129
return
@@ -157,10 +153,6 @@ func DeleteBranch(ctx *context.APIContext) {
157153
}
158154
}
159155

160-
if ctx.Repo.Repository.IsArchived {
161-
ctx.Error(http.StatusForbidden, "IsArchived", fmt.Errorf("can not delete branch of an archived repository"))
162-
return
163-
}
164156
if ctx.Repo.Repository.IsMirror {
165157
ctx.Error(http.StatusForbidden, "IsMirrored", fmt.Errorf("can not delete branch of an mirror repository"))
166158
return
@@ -216,17 +208,14 @@ func CreateBranch(ctx *context.APIContext) {
216208
// description: The old branch does not exist.
217209
// "409":
218210
// description: The branch with the same name already exists.
211+
// "423":
212+
// "$ref": "#/responses/repoArchivedError"
219213

220214
if ctx.Repo.Repository.IsEmpty {
221215
ctx.Error(http.StatusNotFound, "", "Git Repository is empty.")
222216
return
223217
}
224218

225-
if ctx.Repo.Repository.IsArchived {
226-
ctx.Error(http.StatusForbidden, "", "Git Repository is archived.")
227-
return
228-
}
229-
230219
if ctx.Repo.Repository.IsMirror {
231220
ctx.Error(http.StatusForbidden, "", "Git Repository is a mirror.")
232221
return
@@ -519,6 +508,8 @@ func CreateBranchProtection(ctx *context.APIContext) {
519508
// "$ref": "#/responses/notFound"
520509
// "422":
521510
// "$ref": "#/responses/validationError"
511+
// "423":
512+
// "$ref": "#/responses/repoArchivedError"
522513

523514
form := web.GetForm(ctx).(*api.CreateBranchProtectionOption)
524515
repo := ctx.Repo.Repository
@@ -727,6 +718,8 @@ func EditBranchProtection(ctx *context.APIContext) {
727718
// "$ref": "#/responses/notFound"
728719
// "422":
729720
// "$ref": "#/responses/validationError"
721+
// "423":
722+
// "$ref": "#/responses/repoArchivedError"
730723
form := web.GetForm(ctx).(*api.EditBranchProtectionOption)
731724
repo := ctx.Repo.Repository
732725
bpName := ctx.Params(":name")
@@ -1004,7 +997,7 @@ func DeleteBranchProtection(ctx *context.APIContext) {
1004997
return
1005998
}
1006999

1007-
if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository.ID, bp.ID); err != nil {
1000+
if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository, bp.ID); err != nil {
10081001
ctx.Error(http.StatusInternalServerError, "DeleteProtectedBranch", err)
10091002
return
10101003
}

routers/api/v1/repo/file.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ func ChangeFiles(ctx *context.APIContext) {
450450
// "$ref": "#/responses/notFound"
451451
// "422":
452452
// "$ref": "#/responses/error"
453+
// "423":
454+
// "$ref": "#/responses/repoArchivedError"
453455

454456
apiOpts := web.GetForm(ctx).(*api.ChangeFilesOptions)
455457

@@ -550,6 +552,8 @@ func CreateFile(ctx *context.APIContext) {
550552
// "$ref": "#/responses/notFound"
551553
// "422":
552554
// "$ref": "#/responses/error"
555+
// "423":
556+
// "$ref": "#/responses/repoArchivedError"
553557

554558
apiOpts := web.GetForm(ctx).(*api.CreateFileOptions)
555559

@@ -646,6 +650,8 @@ func UpdateFile(ctx *context.APIContext) {
646650
// "$ref": "#/responses/notFound"
647651
// "422":
648652
// "$ref": "#/responses/error"
653+
// "423":
654+
// "$ref": "#/responses/repoArchivedError"
649655
apiOpts := web.GetForm(ctx).(*api.UpdateFileOptions)
650656
if ctx.Repo.Repository.IsEmpty {
651657
ctx.Error(http.StatusUnprocessableEntity, "RepoIsEmpty", fmt.Errorf("repo is empty"))
@@ -806,6 +812,8 @@ func DeleteFile(ctx *context.APIContext) {
806812
// "$ref": "#/responses/error"
807813
// "404":
808814
// "$ref": "#/responses/error"
815+
// "423":
816+
// "$ref": "#/responses/repoArchivedError"
809817

810818
apiOpts := web.GetForm(ctx).(*api.DeleteFileOptions)
811819
if !canWriteFiles(ctx, apiOpts.BranchName) {

routers/api/v1/repo/issue.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ func CreateIssue(ctx *context.APIContext) {
631631
// "$ref": "#/responses/error"
632632
// "422":
633633
// "$ref": "#/responses/validationError"
634+
// "423":
635+
// "$ref": "#/responses/repoArchivedError"
634636
form := web.GetForm(ctx).(*api.CreateIssueOption)
635637
var deadlineUnix timeutil.TimeStamp
636638
if form.Deadline != nil && ctx.Repo.CanWrite(unit.TypeIssues) {

routers/api/v1/repo/issue_attachment.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ func CreateIssueAttachment(ctx *context.APIContext) {
153153
// "$ref": "#/responses/error"
154154
// "404":
155155
// "$ref": "#/responses/error"
156+
// "423":
157+
// "$ref": "#/responses/repoArchivedError"
156158

157159
issue := getIssueFromContext(ctx)
158160
if issue == nil {
@@ -238,6 +240,8 @@ func EditIssueAttachment(ctx *context.APIContext) {
238240
// "$ref": "#/responses/Attachment"
239241
// "404":
240242
// "$ref": "#/responses/error"
243+
// "423":
244+
// "$ref": "#/responses/repoArchivedError"
241245

242246
attachment := getIssueAttachmentSafeWrite(ctx)
243247
if attachment == nil {
@@ -292,6 +296,8 @@ func DeleteIssueAttachment(ctx *context.APIContext) {
292296
// "$ref": "#/responses/empty"
293297
// "404":
294298
// "$ref": "#/responses/error"
299+
// "423":
300+
// "$ref": "#/responses/repoArchivedError"
295301

296302
attachment := getIssueAttachmentSafeWrite(ctx)
297303
if attachment == nil {

routers/api/v1/repo/issue_comment.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,8 @@ func CreateIssueComment(ctx *context.APIContext) {
358358
// "$ref": "#/responses/forbidden"
359359
// "404":
360360
// "$ref": "#/responses/notFound"
361+
// "423":
362+
// "$ref": "#/responses/repoArchivedError"
361363
form := web.GetForm(ctx).(*api.CreateIssueCommentOption)
362364
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
363365
if err != nil {
@@ -486,7 +488,8 @@ func EditIssueComment(ctx *context.APIContext) {
486488
// "$ref": "#/responses/forbidden"
487489
// "404":
488490
// "$ref": "#/responses/notFound"
489-
491+
// "423":
492+
// "$ref": "#/responses/repoArchivedError"
490493
form := web.GetForm(ctx).(*api.EditIssueCommentOption)
491494
editIssueComment(ctx, *form)
492495
}

routers/api/v1/repo/issue_comment_attachment.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) {
156156
// "$ref": "#/responses/error"
157157
// "404":
158158
// "$ref": "#/responses/error"
159+
// "423":
160+
// "$ref": "#/responses/repoArchivedError"
159161

160162
// Check if comment exists and load comment
161163
comment := getIssueCommentSafe(ctx)
@@ -245,7 +247,8 @@ func EditIssueCommentAttachment(ctx *context.APIContext) {
245247
// "$ref": "#/responses/Attachment"
246248
// "404":
247249
// "$ref": "#/responses/error"
248-
250+
// "423":
251+
// "$ref": "#/responses/repoArchivedError"
249252
attach := getIssueCommentAttachmentSafeWrite(ctx)
250253
if attach == nil {
251254
return
@@ -297,7 +300,8 @@ func DeleteIssueCommentAttachment(ctx *context.APIContext) {
297300
// "$ref": "#/responses/empty"
298301
// "404":
299302
// "$ref": "#/responses/error"
300-
303+
// "423":
304+
// "$ref": "#/responses/repoArchivedError"
301305
attach := getIssueCommentAttachmentSafeWrite(ctx)
302306
if attach == nil {
303307
return

routers/api/v1/repo/issue_dependency.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ func CreateIssueDependency(ctx *context.APIContext) {
187187
// "$ref": "#/responses/Issue"
188188
// "404":
189189
// description: the issue does not exist
190+
// "423":
191+
// "$ref": "#/responses/repoArchivedError"
190192

191193
// We want to make <:index> depend on <Form>, i.e. <:index> is the target
192194
target := getParamsIssue(ctx)
@@ -246,6 +248,8 @@ func RemoveIssueDependency(ctx *context.APIContext) {
246248
// "$ref": "#/responses/Issue"
247249
// "404":
248250
// "$ref": "#/responses/notFound"
251+
// "423":
252+
// "$ref": "#/responses/repoArchivedError"
249253

250254
// We want to make <:index> depend on <Form>, i.e. <:index> is the target
251255
target := getParamsIssue(ctx)

routers/api/v1/repo/patch.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ func ApplyDiffPatch(ctx *context.APIContext) {
4747
// "$ref": "#/responses/FileResponse"
4848
// "404":
4949
// "$ref": "#/responses/notFound"
50+
// "423":
51+
// "$ref": "#/responses/repoArchivedError"
5052
apiOpts := web.GetForm(ctx).(*api.ApplyDiffPatchFileOptions)
5153

5254
opts := &files.ApplyDiffPatchOptions{

routers/api/v1/repo/pull.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ func CreatePullRequest(ctx *context.APIContext) {
282282
// "$ref": "#/responses/error"
283283
// "422":
284284
// "$ref": "#/responses/validationError"
285+
// "423":
286+
// "$ref": "#/responses/repoArchivedError"
285287

286288
form := *web.GetForm(ctx).(*api.CreatePullRequestOption)
287289
if form.Head == form.Base {
@@ -741,6 +743,8 @@ func MergePullRequest(ctx *context.APIContext) {
741743
// "$ref": "#/responses/empty"
742744
// "409":
743745
// "$ref": "#/responses/error"
746+
// "423":
747+
// "$ref": "#/responses/repoArchivedError"
744748

745749
form := web.GetForm(ctx).(*forms.MergePullRequestForm)
746750

@@ -1196,6 +1200,8 @@ func CancelScheduledAutoMerge(ctx *context.APIContext) {
11961200
// "$ref": "#/responses/forbidden"
11971201
// "404":
11981202
// "$ref": "#/responses/notFound"
1203+
// "423":
1204+
// "$ref": "#/responses/repoArchivedError"
11991205

12001206
pullIndex := ctx.ParamsInt64(":index")
12011207
pull, err := issues_model.GetPullRequestByIndex(ctx, ctx.Repo.Repository.ID, pullIndex)

0 commit comments

Comments
 (0)