Skip to content

Commit 5e0302a

Browse files
add API branch protection endpoint
1 parent d672206 commit 5e0302a

File tree

8 files changed

+1070
-28
lines changed

8 files changed

+1070
-28
lines changed

models/user.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,16 @@ func GetMaileableUsersByIDs(ids []int64) ([]*User, error) {
13221322
Find(&ous)
13231323
}
13241324

1325+
// GetUsernamesByIDs returns usernames for all resolved users from a list of Ids.
1326+
func GetUsernamesByIDs(ids []int64) ([]string, error) {
1327+
ous, err := GetUsersByIDs(ids)
1328+
unames := make([]string, 0, len(ous))
1329+
for _, u := range ous {
1330+
unames = append(unames, u.Name)
1331+
}
1332+
return unames, err
1333+
}
1334+
13251335
// GetUsersByIDs returns all resolved users from a list of Ids.
13261336
func GetUsersByIDs(ids []int64) ([]*User, error) {
13271337
ous := make([]*User, 0, len(ids))

modules/convert/convert.go

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,76 @@ func ToEmail(email *models.EmailAddress) *api.Email {
3030
}
3131

3232
// ToBranch convert a git.Commit and git.Branch to an api.Branch
33-
func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *models.User) *api.Branch {
33+
func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit, bp *models.ProtectedBranch, user *models.User, isRepoAdmin bool) *api.Branch {
3434
if bp == nil {
3535
return &api.Branch{
36-
Name: b.Name,
37-
Commit: ToCommit(repo, c),
38-
Protected: false,
39-
RequiredApprovals: 0,
40-
EnableStatusCheck: false,
41-
StatusCheckContexts: []string{},
42-
UserCanPush: true,
43-
UserCanMerge: true,
36+
Name: b.Name,
37+
Commit: ToCommit(repo, c),
38+
Protected: false,
39+
RequiredApprovals: 0,
40+
EnableStatusCheck: false,
41+
StatusCheckContexts: []string{},
42+
UserCanPush: true,
43+
UserCanMerge: true,
44+
EffectiveBranchProtectionName: "",
45+
EffectiveBRanchProtectionID: 0,
4446
}
4547
}
48+
branchProtectionName := ""
49+
var branchProtectionID int64
50+
if isRepoAdmin {
51+
branchProtectionName = bp.BranchName
52+
branchProtectionID = bp.ID
53+
}
54+
4655
return &api.Branch{
47-
Name: b.Name,
48-
Commit: ToCommit(repo, c),
49-
Protected: true,
50-
RequiredApprovals: bp.RequiredApprovals,
51-
EnableStatusCheck: bp.EnableStatusCheck,
52-
StatusCheckContexts: bp.StatusCheckContexts,
53-
UserCanPush: bp.CanUserPush(user.ID),
54-
UserCanMerge: bp.CanUserMerge(user.ID),
56+
Name: b.Name,
57+
Commit: ToCommit(repo, c),
58+
Protected: true,
59+
RequiredApprovals: bp.RequiredApprovals,
60+
EnableStatusCheck: bp.EnableStatusCheck,
61+
StatusCheckContexts: bp.StatusCheckContexts,
62+
UserCanPush: bp.CanUserPush(user.ID),
63+
UserCanMerge: bp.CanUserMerge(user.ID),
64+
EffectiveBranchProtectionName: branchProtectionName,
65+
EffectiveBRanchProtectionID: branchProtectionID,
66+
}
67+
}
68+
69+
// ToBranchProtection convert a ProtectedBranch to api.BranchProtection
70+
func ToBranchProtection(bp *models.ProtectedBranch) *api.BranchProtection {
71+
pushWhitelistUsernames, err := models.GetUsernamesByIDs(bp.WhitelistUserIDs)
72+
if err != nil {
73+
log.Error("GetUsernamesByIDs (WhitelistUserIDs): %v", err)
74+
}
75+
mergeWhitelistUsernames, err := models.GetUsernamesByIDs(bp.MergeWhitelistUserIDs)
76+
if err != nil {
77+
log.Error("GetUsernamesByIDs (MergeWhitelistUserIDs): %v", err)
78+
}
79+
approvalsWhitelistUsernames, err := models.GetUsernamesByIDs(bp.ApprovalsWhitelistUserIDs)
80+
if err != nil {
81+
log.Error("GetUsernamesByIDs (ApprovalsWhitelistUserIDs): %v", err)
82+
}
83+
84+
return &api.BranchProtection{
85+
ID: bp.ID,
86+
BranchName: bp.BranchName,
87+
EnablePush: bp.CanPush,
88+
EnablePushWhitelist: bp.EnableWhitelist,
89+
PushWhitelistUsernames: pushWhitelistUsernames,
90+
PushWhitelistTeamIDs: bp.WhitelistTeamIDs,
91+
PushWhitelistDeployKeys: bp.WhitelistDeployKeys,
92+
EnableMergeWhitelist: bp.EnableMergeWhitelist,
93+
MergeWhitelistUsernames: mergeWhitelistUsernames,
94+
MergeWhitelistTeamIDs: bp.MergeWhitelistTeamIDs,
95+
EnableStatusCheck: bp.EnableStatusCheck,
96+
StatusCheckContexts: bp.StatusCheckContexts,
97+
RequiredApprovals: bp.RequiredApprovals,
98+
EnableApprovalsWhitelist: bp.EnableApprovalsWhitelist,
99+
ApprovalsWhitelistUsernames: approvalsWhitelistUsernames,
100+
ApprovalsWhitelistTeamIDs: bp.ApprovalsWhitelistTeamIDs,
101+
Created: bp.CreatedUnix.AsTime(),
102+
Updated: bp.UpdatedUnix.AsTime(),
55103
}
56104
}
57105

modules/structs/repo_branch.go

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,81 @@
44

55
package structs
66

7+
import (
8+
"time"
9+
)
10+
711
// Branch represents a repository branch
812
type Branch struct {
9-
Name string `json:"name"`
10-
Commit *PayloadCommit `json:"commit"`
11-
Protected bool `json:"protected"`
12-
RequiredApprovals int64 `json:"required_approvals"`
13-
EnableStatusCheck bool `json:"enable_status_check"`
14-
StatusCheckContexts []string `json:"status_check_contexts"`
15-
UserCanPush bool `json:"user_can_push"`
16-
UserCanMerge bool `json:"user_can_merge"`
13+
Name string `json:"name"`
14+
Commit *PayloadCommit `json:"commit"`
15+
Protected bool `json:"protected"`
16+
RequiredApprovals int64 `json:"required_approvals"`
17+
EnableStatusCheck bool `json:"enable_status_check"`
18+
StatusCheckContexts []string `json:"status_check_contexts"`
19+
UserCanPush bool `json:"user_can_push"`
20+
UserCanMerge bool `json:"user_can_merge"`
21+
EffectiveBranchProtectionName string `json:"effective_branch_protection_name"`
22+
EffectiveBRanchProtectionID int64 `json:"effective_branch_protection_id"`
23+
}
24+
25+
// BranchProtection represents a branch protection for a repository
26+
type BranchProtection struct {
27+
ID int64 `json:"id"`
28+
BranchName string `json:"branch_name"`
29+
EnablePush bool `json:"enable_push"`
30+
EnablePushWhitelist bool `json:"enable_push_whitelist"`
31+
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
32+
PushWhitelistTeamIDs []int64 `json:"push_whitelist_team_ids"`
33+
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
34+
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
35+
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
36+
MergeWhitelistTeamIDs []int64 `json:"merge_whitelist_ids"`
37+
EnableStatusCheck bool `json:"enable_status_check"`
38+
StatusCheckContexts []string `json:"status_check_contexts"`
39+
RequiredApprovals int64 `json:"required_approvals"`
40+
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
41+
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
42+
ApprovalsWhitelistTeamIDs []int64 `json:"approvals_whitelist_team_ids"`
43+
// swagger:strfmt date-time
44+
Created time.Time `json:"created_at"`
45+
// swagger:strfmt date-time
46+
Updated time.Time `json:"updated_at"`
47+
}
48+
49+
// CreateBranchProtectionOption options for creating a branch protection
50+
type CreateBranchProtectionOption struct {
51+
BranchName string `json:"branch_name"`
52+
EnablePush bool `json:"enable_push"`
53+
EnablePushWhitelist bool `json:"enable_push_whitelist"`
54+
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
55+
PushWhitelistTeamIDs []int64 `json:"push_whitelist_team_ids"`
56+
PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"`
57+
EnableMergeWhitelist bool `json:"enable_merge_whitelist"`
58+
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
59+
MergeWhitelistTeamIDs []int64 `json:"merge_whitelist_team_ids"`
60+
EnableStatusCheck bool `json:"enable_status_check"`
61+
StatusCheckContexts []string `json:"status_check_contexts"`
62+
RequiredApprovals int64 `json:"required_approvals"`
63+
EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"`
64+
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
65+
ApprovalsWhitelistTeamIDs []int64 `json:"approvals_whitelist_team_ids"`
66+
}
67+
68+
// EditBranchProtectionOption options for editing a branch protection
69+
type EditBranchProtectionOption struct {
70+
EnablePush *bool `json:"enable_push"`
71+
EnablePushWhitelist *bool `json:"enable_push_whitelist"`
72+
PushWhitelistUsernames []string `json:"push_whitelist_usernames"`
73+
PushWhitelistTeamIDs []int64 `json:"push_whitelist_team_ids"`
74+
PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"`
75+
EnableMergeWhitelist *bool `json:"enable_merge_whitelist"`
76+
MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"`
77+
MergeWhitelistTeamIDs []int64 `json:"merge_whitelist_team_ids"`
78+
EnableStatusCheck *bool `json:"enable_status_check"`
79+
StatusCheckContexts []string `json:"status_check_contexts"`
80+
RequiredApprovals *int64 `json:"required_approvals"`
81+
EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"`
82+
ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"`
83+
ApprovalsWhitelistTeamIDs []int64 `json:"approvals_whitelist_team_ids"`
1784
}

routers/api/v1/api.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,15 @@ func RegisterRoutes(m *macaron.Macaron) {
639639
m.Get("", repo.ListBranches)
640640
m.Get("/*", context.RepoRefByType(context.RepoRefBranch), repo.GetBranch)
641641
}, reqRepoReader(models.UnitTypeCode))
642+
m.Group("/branch_protections", func() {
643+
m.Get("", repo.ListBranchProtections)
644+
m.Post("", bind(api.CreateBranchProtectionOption{}), repo.CreateBranchProtection)
645+
m.Group("/:id", func() {
646+
m.Get("", repo.GetBranchProtection)
647+
m.Put("", bind(api.EditBranchProtectionOption{}), repo.EditBranchProtection)
648+
m.Delete("", repo.DeleteBranchProtection)
649+
})
650+
}, reqToken(), reqAdmin())
642651
m.Group("/tags", func() {
643652
m.Get("", repo.ListTags)
644653
}, reqRepoReader(models.UnitTypeCode), context.ReferencesGitRepo(true))

0 commit comments

Comments
 (0)