6
6
package repo
7
7
8
8
import (
9
+ "net/http"
10
+ "strings"
11
+
12
+ "code.gitea.io/gitea/models"
13
+ "code.gitea.io/gitea/modules/auth"
14
+ "code.gitea.io/gitea/modules/base"
9
15
"code.gitea.io/gitea/modules/context"
10
16
"code.gitea.io/gitea/modules/git"
11
17
"code.gitea.io/gitea/routers/api/v1/convert"
@@ -46,23 +52,30 @@ func GetBranch(ctx *context.APIContext) {
46
52
ctx .NotFound ()
47
53
return
48
54
}
49
- branch , err := ctx .Repo .Repository .GetBranch (ctx .Repo .BranchName )
55
+ branchName := ctx .Repo .BranchName
56
+ branch , err := ctx .Repo .Repository .GetBranch (branchName )
50
57
if err != nil {
51
58
if git .IsErrBranchNotExist (err ) {
52
59
ctx .NotFound (err )
53
60
} else {
54
- ctx .Error (500 , "GetBranch" , err )
61
+ ctx .Error (http . StatusInternalServerError , "GetBranch" , err )
55
62
}
56
63
return
57
64
}
58
65
66
+ protected , err := ctx .Repo .Repository .IsProtectedBranch (branchName , ctx .Repo .Owner )
67
+ if err != nil {
68
+ ctx .Error (http .StatusInternalServerError , "IsProtectedBranch" , err )
69
+ return
70
+ }
71
+
59
72
c , err := branch .GetCommit ()
60
73
if err != nil {
61
- ctx .Error (500 , "GetCommit" , err )
74
+ ctx .Error (http . StatusInternalServerError , "GetCommit" , err )
62
75
return
63
76
}
64
77
65
- ctx .JSON (200 , convert .ToBranch (ctx .Repo .Repository , branch , c ))
78
+ ctx .JSON (http . StatusOK , convert .ToBranch (ctx .Repo .Repository , branch , c , protected ))
66
79
}
67
80
68
81
// ListBranches list all the branches of a repository
@@ -88,19 +101,204 @@ func ListBranches(ctx *context.APIContext) {
88
101
// "$ref": "#/responses/BranchList"
89
102
branches , err := ctx .Repo .Repository .GetBranches ()
90
103
if err != nil {
91
- ctx .Error (500 , "GetBranches" , err )
104
+ ctx .Error (http . StatusInternalServerError , "GetBranches" , err )
92
105
return
93
106
}
94
107
95
108
apiBranches := make ([]* api.Branch , len (branches ))
96
109
for i := range branches {
97
110
c , err := branches [i ].GetCommit ()
98
111
if err != nil {
99
- ctx .Error (500 , "GetCommit" , err )
112
+ ctx .Error (http .StatusInternalServerError , "GetCommit" , err )
113
+ return
114
+ }
115
+
116
+ protected , err := ctx .Repo .Repository .IsProtectedBranch (branches [i ].Name , ctx .Repo .Owner )
117
+ if err != nil {
118
+ ctx .Error (http .StatusInternalServerError , "IsProtectedBranch" , err )
119
+ return
120
+ }
121
+
122
+ apiBranches [i ] = convert .ToBranch (ctx .Repo .Repository , branches [i ], c , protected )
123
+ }
124
+
125
+ ctx .JSON (http .StatusOK , & apiBranches )
126
+ }
127
+
128
+ // GetProtectedBranchBy getting protected branch by ID/Name
129
+ func GetProtectedBranchBy (ctx * context.APIContext ) {
130
+ // swagger:operation GET /repos/{owner}/{repo}/branches/{branch}/protection repository repoGetBranchProtection
131
+ // ---
132
+ // summary: Retrieve a specific branch protection from a repository
133
+ // produces:
134
+ // - application/json
135
+ // parameters:
136
+ // - name: owner
137
+ // in: path
138
+ // description: owner of the repo
139
+ // type: string
140
+ // required: true
141
+ // - name: repo
142
+ // in: path
143
+ // description: name of the repo
144
+ // type: string
145
+ // required: true
146
+ // - name: branch
147
+ // in: path
148
+ // description: branch to get
149
+ // type: string
150
+ // required: true
151
+ // responses:
152
+ // "200":
153
+ // "$ref": "#/responses/Branch"
154
+ protectBranch , err := models .GetProtectedBranchBy (ctx .Repo .Repository .ID , ctx .Params (":branch" ))
155
+ if err != nil {
156
+ if ! git .IsErrBranchNotExist (err ) {
157
+ ctx .Error (http .StatusInternalServerError , "GetProtectedBranchBy" , err )
100
158
return
101
159
}
102
- apiBranches [i ] = convert .ToBranch (ctx .Repo .Repository , branches [i ], c )
103
160
}
161
+ ctx .JSON (http .StatusOK , protectBranch )
162
+ }
104
163
105
- ctx .JSON (200 , & apiBranches )
164
+ // UpdateProtectBranch saves branch protection options of repository.
165
+ // If ID is 0, it creates a new record. Otherwise, updates existing record.
166
+ // This function also performs check if whitelist user and team's IDs have been changed
167
+ // to avoid unnecessary whitelist delete and regenerate.
168
+ func UpdateProtectBranch (ctx * context.APIContext , f auth.ProtectBranchForm ) {
169
+ // swagger:operation PUT /repos/{owner}/{repo}/branches/{branch}/protection repository repoUpdateProtectBranch
170
+ // ---
171
+ // summary: Update branch protection of a repository
172
+ // produces:
173
+ // - application/json
174
+ // parameters:
175
+ // - name: owner
176
+ // in: path
177
+ // description: owner of the repo
178
+ // type: string
179
+ // required: true
180
+ // - name: repo
181
+ // in: path
182
+ // description: name of the repo
183
+ // type: string
184
+ // required: true
185
+ // - name: branch
186
+ // in: path
187
+ // description: branch to update
188
+ // type: string
189
+ // required: true
190
+ // - name: body
191
+ // in: body
192
+ // required: true
193
+ // schema:
194
+ // "$ref": "#/definitions/ProtectBranchForm"
195
+ // responses:
196
+ // "200":
197
+ // "$ref": "#/responses/Branch"
198
+ branch := ctx .Params (":branch" )
199
+ protectBranch , err := models .GetProtectedBranchBy (ctx .Repo .Repository .ID , branch )
200
+ if err != nil {
201
+ if ! git .IsErrBranchNotExist (err ) {
202
+ ctx .Error (http .StatusInternalServerError , "GetProtectedBranchBy" , err )
203
+ return
204
+ }
205
+ }
206
+
207
+ if f .Protected {
208
+ if protectBranch == nil {
209
+ protectBranch = & models.ProtectedBranch {
210
+ RepoID : ctx .Repo .Repository .ID ,
211
+ BranchName : branch ,
212
+ }
213
+ }
214
+
215
+ var whitelistUsers , whitelistTeams , mergeWhitelistUsers , mergeWhitelistTeams , approvalsWhitelistUsers , approvalsWhitelistTeams []int64
216
+ protectBranch .EnableWhitelist = f .EnableWhitelist
217
+ if strings .TrimSpace (f .WhitelistUsers ) != "" {
218
+ whitelistUsers , _ = base .StringsToInt64s (strings .Split (f .WhitelistUsers , "," ))
219
+ }
220
+ if strings .TrimSpace (f .WhitelistTeams ) != "" {
221
+ whitelistTeams , _ = base .StringsToInt64s (strings .Split (f .WhitelistTeams , "," ))
222
+ }
223
+ protectBranch .EnableMergeWhitelist = f .EnableMergeWhitelist
224
+ if strings .TrimSpace (f .MergeWhitelistUsers ) != "" {
225
+ mergeWhitelistUsers , _ = base .StringsToInt64s (strings .Split (f .MergeWhitelistUsers , "," ))
226
+ }
227
+ if strings .TrimSpace (f .MergeWhitelistTeams ) != "" {
228
+ mergeWhitelistTeams , _ = base .StringsToInt64s (strings .Split (f .MergeWhitelistTeams , "," ))
229
+ }
230
+ protectBranch .RequiredApprovals = f .RequiredApprovals
231
+ if strings .TrimSpace (f .ApprovalsWhitelistUsers ) != "" {
232
+ approvalsWhitelistUsers , _ = base .StringsToInt64s (strings .Split (f .ApprovalsWhitelistUsers , "," ))
233
+ }
234
+ if strings .TrimSpace (f .ApprovalsWhitelistTeams ) != "" {
235
+ approvalsWhitelistTeams , _ = base .StringsToInt64s (strings .Split (f .ApprovalsWhitelistTeams , "," ))
236
+ }
237
+ if err = models .UpdateProtectBranch (ctx .Repo .Repository , protectBranch , models.WhitelistOptions {
238
+ UserIDs : whitelistUsers ,
239
+ TeamIDs : whitelistTeams ,
240
+ MergeUserIDs : mergeWhitelistUsers ,
241
+ MergeTeamIDs : mergeWhitelistTeams ,
242
+ ApprovalsUserIDs : approvalsWhitelistUsers ,
243
+ ApprovalsTeamIDs : approvalsWhitelistTeams ,
244
+ }); err != nil {
245
+ ctx .Error (http .StatusInternalServerError , "UpdateProtectBranch" , err )
246
+ return
247
+ }
248
+ } else if protectBranch != nil {
249
+ if err := ctx .Repo .Repository .DeleteProtectedBranch (protectBranch .ID ); err != nil {
250
+ ctx .Error (http .StatusInternalServerError , "DeleteProtectedBranch" , err )
251
+ return
252
+ }
253
+ }
254
+ ctx .JSON (http .StatusOK , protectBranch )
255
+ }
256
+
257
+ // DeleteProtectedBranch removes ProtectedBranch relation between the user and repository.
258
+ func DeleteProtectedBranch (ctx * context.APIContext ) {
259
+ // swagger:operation DELETE /repos/{owner}/{repo}/branches/{branch}/protection repository repoDeleteProtectedBranch
260
+ // ---
261
+ // summary: Remove branch protection from a repository
262
+ // produces:
263
+ // - application/json
264
+ // parameters:
265
+ // - name: owner
266
+ // in: path
267
+ // description: owner of the repo
268
+ // type: string
269
+ // required: true
270
+ // - name: repo
271
+ // in: path
272
+ // description: name of the repo
273
+ // type: string
274
+ // required: true
275
+ // - name: branch
276
+ // in: path
277
+ // description: branch to remove protection
278
+ // type: string
279
+ // required: true
280
+ // responses:
281
+ // "204":
282
+ // "$ref": "#/responses/empty"
283
+ branchName := ctx .Params (":branch" )
284
+ protected , err := ctx .Repo .Repository .IsProtectedBranch (branchName , ctx .Repo .Owner )
285
+ if err != nil {
286
+ ctx .Error (http .StatusInternalServerError , "IsProtectedBranch" , err )
287
+ return
288
+ }
289
+ if ! protected {
290
+ ctx .Status (http .StatusNoContent )
291
+ return
292
+ }
293
+ protectBranch , err := models .GetProtectedBranchBy (ctx .Repo .Repository .ID , branchName )
294
+ if err != nil {
295
+ if ! git .IsErrBranchNotExist (err ) {
296
+ ctx .Error (http .StatusInternalServerError , "GetProtectedBranchBy" , err )
297
+ return
298
+ }
299
+ }
300
+ if err = ctx .Repo .Repository .DeleteProtectedBranch (protectBranch .ID ); err != nil {
301
+ ctx .Error (http .StatusInternalServerError , "DeleteProtectedBranch" , err )
302
+ }
303
+ ctx .Status (http .StatusNoContent )
106
304
}
0 commit comments