mirror of
https://github.com/harness/drone.git
synced 2025-05-06 21:52:03 +08:00
[WIP] Move from space_owner
to repo_admin
for protection rules (#745)
This commit is contained in:
parent
e0df722ce3
commit
b0e519b571
@ -57,15 +57,16 @@ func CheckRepo(
|
|||||||
return Check(ctx, authorizer, session, scope, resource, permission)
|
return Check(ctx, authorizer, session, scope, resource, permission)
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsSpaceAdmin(
|
func IsRepoOwner(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
authorizer authz.Authorizer,
|
authorizer authz.Authorizer,
|
||||||
session *auth.Session,
|
session *auth.Session,
|
||||||
repo *types.Repository,
|
repo *types.Repository,
|
||||||
) (bool, error) {
|
) (bool, error) {
|
||||||
err := CheckRepo(ctx, authorizer, session, repo, enum.PermissionSpaceCreate, false)
|
// for now we use repoedit as permission to verify if someone is a SpaceOwner and hence a RepoOwner.
|
||||||
|
err := CheckRepo(ctx, authorizer, session, repo, enum.PermissionRepoEdit, false)
|
||||||
if err != nil && !errors.Is(err, ErrNotAuthorized) {
|
if err != nil && !errors.Is(err, ErrNotAuthorized) {
|
||||||
return false, fmt.Errorf("failed to check access to find if the user is space admin: %w", err)
|
return false, fmt.Errorf("failed to check access user access: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err == nil, nil
|
return err == nil, nil
|
||||||
|
@ -98,9 +98,9 @@ func (c *Controller) checkProtectionRules(
|
|||||||
refUpdates changedRefs,
|
refUpdates changedRefs,
|
||||||
output *githook.Output,
|
output *githook.Output,
|
||||||
) error {
|
) error {
|
||||||
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, repo)
|
isRepoOwner, err := apiauth.IsRepoOwner(ctx, c.authorizer, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to determine if user is repo owner: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
protectionRules, err := c.protectionManager.ForRepository(ctx, repo.ID)
|
protectionRules, err := c.protectionManager.ForRepository(ctx, repo.ID)
|
||||||
@ -117,12 +117,12 @@ func (c *Controller) checkProtectionRules(
|
|||||||
}
|
}
|
||||||
|
|
||||||
violations, err := protectionRules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
violations, err := protectionRules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
RefAction: refAction,
|
RefAction: refAction,
|
||||||
RefType: refType,
|
RefType: refType,
|
||||||
RefNames: names,
|
RefNames: names,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errCheckAction = fmt.Errorf("failed to verify protection rules for git push: %w", err)
|
errCheckAction = fmt.Errorf("failed to verify protection rules for git push: %w", err)
|
||||||
|
@ -129,9 +129,9 @@ func (c *Controller) Merge(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, targetRepo)
|
isRepoOwner, err := apiauth.IsRepoOwner(ctx, c.authorizer, session, targetRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to determine if the user is space admin: %w", err)
|
return nil, nil, fmt.Errorf("failed to determine if user is repo owner: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkResults, err := c.checkStore.ListResults(ctx, targetRepo.ID, pr.SourceSHA)
|
checkResults, err := c.checkStore.ListResults(ctx, targetRepo.ID, pr.SourceSHA)
|
||||||
@ -152,7 +152,7 @@ func (c *Controller) Merge(
|
|||||||
|
|
||||||
ruleOut, violations, err := protectionRules.MergeVerify(ctx, protection.MergeVerifyInput{
|
ruleOut, violations, err := protectionRules.MergeVerify(ctx, protection.MergeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
TargetRepo: targetRepo,
|
TargetRepo: targetRepo,
|
||||||
SourceRepo: sourceRepo,
|
SourceRepo: sourceRepo,
|
||||||
PullReq: pr,
|
PullReq: pr,
|
||||||
|
@ -62,7 +62,7 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
return types.CommitFilesResponse{}, nil, err
|
return types.CommitFilesResponse{}, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rules, isSpaceOwner, err := c.fetchRules(ctx, session, repo)
|
rules, isRepoOwner, err := c.fetchRules(ctx, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, nil, err
|
return types.CommitFilesResponse{}, nil, err
|
||||||
}
|
}
|
||||||
@ -78,12 +78,12 @@ func (c *Controller) CommitFiles(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
RefAction: refAction,
|
RefAction: refAction,
|
||||||
RefType: protection.RefTypeBranch,
|
RefType: protection.RefTypeBranch,
|
||||||
RefNames: []string{branchName},
|
RefNames: []string{branchName},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.CommitFilesResponse{}, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
return types.CommitFilesResponse{}, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
|
@ -130,9 +130,9 @@ func (c *Controller) fetchRules(
|
|||||||
session *auth.Session,
|
session *auth.Session,
|
||||||
repo *types.Repository,
|
repo *types.Repository,
|
||||||
) (protection.Protection, bool, error) {
|
) (protection.Protection, bool, error) {
|
||||||
isSpaceOwner, err := apiauth.IsSpaceAdmin(ctx, c.authorizer, session, repo)
|
isRepoOwner, err := apiauth.IsRepoOwner(ctx, c.authorizer, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, fmt.Errorf("failed to determine space ownership: %w", err)
|
return nil, false, fmt.Errorf("failed to determine if user is repo owner: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
protectionRules, err := c.protectionManager.ForRepository(ctx, repo.ID)
|
protectionRules, err := c.protectionManager.ForRepository(ctx, repo.ID)
|
||||||
@ -140,5 +140,5 @@ func (c *Controller) fetchRules(
|
|||||||
return nil, false, fmt.Errorf("failed to fetch protection rules for the repository: %w", err)
|
return nil, false, fmt.Errorf("failed to fetch protection rules for the repository: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return protectionRules, isSpaceOwner, nil
|
return protectionRules, isRepoOwner, nil
|
||||||
}
|
}
|
||||||
|
@ -51,18 +51,18 @@ func (c *Controller) CreateBranch(ctx context.Context,
|
|||||||
in.Target = repo.DefaultBranch
|
in.Target = repo.DefaultBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
rules, isSpaceOwner, err := c.fetchRules(ctx, session, repo)
|
rules, isRepoOwner, err := c.fetchRules(ctx, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
RefAction: protection.RefActionCreate,
|
RefAction: protection.RefActionCreate,
|
||||||
RefType: protection.RefTypeBranch,
|
RefType: protection.RefTypeBranch,
|
||||||
RefNames: []string{in.Name},
|
RefNames: []string{in.Name},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
return nil, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
|
@ -55,18 +55,18 @@ func (c *Controller) CreateCommitTag(ctx context.Context,
|
|||||||
in.Target = repo.DefaultBranch
|
in.Target = repo.DefaultBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
rules, isSpaceOwner, err := c.fetchRules(ctx, session, repo)
|
rules, isRepoOwner, err := c.fetchRules(ctx, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
RefAction: protection.RefActionCreate,
|
RefAction: protection.RefActionCreate,
|
||||||
RefType: protection.RefTypeTag,
|
RefType: protection.RefTypeTag,
|
||||||
RefNames: []string{in.Name},
|
RefNames: []string{in.Name},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
return nil, nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
|
@ -46,18 +46,18 @@ func (c *Controller) DeleteBranch(ctx context.Context,
|
|||||||
return nil, usererror.ErrDefaultBranchCantBeDeleted
|
return nil, usererror.ErrDefaultBranchCantBeDeleted
|
||||||
}
|
}
|
||||||
|
|
||||||
rules, isSpaceOwner, err := c.fetchRules(ctx, session, repo)
|
rules, isRepoOwner, err := c.fetchRules(ctx, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
RefAction: protection.RefActionDelete,
|
RefAction: protection.RefActionDelete,
|
||||||
RefType: protection.RefTypeBranch,
|
RefType: protection.RefTypeBranch,
|
||||||
RefNames: []string{branchName},
|
RefNames: []string{branchName},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
return nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
|
@ -37,18 +37,18 @@ func (c *Controller) DeleteTag(ctx context.Context,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rules, isSpaceOwner, err := c.fetchRules(ctx, session, repo)
|
rules, isRepoOwner, err := c.fetchRules(ctx, session, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
violations, err := rules.RefChangeVerify(ctx, protection.RefChangeVerifyInput{
|
||||||
Actor: &session.Principal,
|
Actor: &session.Principal,
|
||||||
IsSpaceOwner: isSpaceOwner,
|
IsRepoOwner: isRepoOwner,
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
RefAction: protection.RefActionDelete,
|
RefAction: protection.RefActionDelete,
|
||||||
RefType: protection.RefTypeTag,
|
RefType: protection.RefTypeTag,
|
||||||
RefNames: []string{tagName},
|
RefNames: []string{tagName},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
return nil, fmt.Errorf("failed to verify protection rules: %w", err)
|
||||||
|
@ -19,8 +19,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type DefBypass struct {
|
type DefBypass struct {
|
||||||
UserIDs []int64 `json:"user_ids,omitempty"`
|
UserIDs []int64 `json:"user_ids,omitempty"`
|
||||||
SpaceOwners bool `json:"space_owners,omitempty"`
|
RepoOwners bool `json:"repo_owners,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v DefBypass) Sanitize() error {
|
func (v DefBypass) Sanitize() error {
|
||||||
|
@ -42,7 +42,7 @@ func (v *Branch) MergeVerify(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
in MergeVerifyInput,
|
in MergeVerifyInput,
|
||||||
) (MergeVerifyOutput, []types.RuleViolations, error) {
|
) (MergeVerifyOutput, []types.RuleViolations, error) {
|
||||||
if v.isBypassed(in.Actor, in.IsSpaceOwner) {
|
if v.isBypassed(in.Actor, in.IsRepoOwner) {
|
||||||
return MergeVerifyOutput{}, nil, nil
|
return MergeVerifyOutput{}, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ func (v *Branch) RefChangeVerify(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
in RefChangeVerifyInput,
|
in RefChangeVerifyInput,
|
||||||
) ([]types.RuleViolations, error) {
|
) ([]types.RuleViolations, error) {
|
||||||
if v.isBypassed(in.Actor, in.IsSpaceOwner) || in.RefType != RefTypeBranch || len(in.RefNames) == 0 {
|
if v.isBypassed(in.Actor, in.IsRepoOwner) || in.RefType != RefTypeBranch || len(in.RefNames) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,9 +76,9 @@ func (v *Branch) Sanitize() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Branch) isBypassed(actor *types.Principal, isSpaceOwner bool) bool {
|
func (v *Branch) isBypassed(actor *types.Principal, isRepoOwner bool) bool {
|
||||||
return actor != nil &&
|
return actor != nil &&
|
||||||
(actor.Admin ||
|
(actor.Admin ||
|
||||||
v.Bypass.SpaceOwners && isSpaceOwner ||
|
v.Bypass.RepoOwners && isRepoOwner ||
|
||||||
slices.Contains(v.Bypass.UserIDs, actor.ID))
|
slices.Contains(v.Bypass.UserIDs, actor.ID))
|
||||||
}
|
}
|
||||||
|
@ -33,39 +33,39 @@ func TestBranch_isBypass(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "empty",
|
name: "empty",
|
||||||
bypass: DefBypass{UserIDs: nil, SpaceOwners: false},
|
bypass: DefBypass{UserIDs: nil, RepoOwners: false},
|
||||||
actor: user,
|
actor: user,
|
||||||
exp: false,
|
exp: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "admin",
|
name: "admin",
|
||||||
bypass: DefBypass{UserIDs: nil, SpaceOwners: false},
|
bypass: DefBypass{UserIDs: nil, RepoOwners: false},
|
||||||
actor: admin,
|
actor: admin,
|
||||||
exp: true,
|
exp: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "space-owners-false",
|
name: "repo-owners-false",
|
||||||
bypass: DefBypass{UserIDs: nil, SpaceOwners: false},
|
bypass: DefBypass{UserIDs: nil, RepoOwners: false},
|
||||||
actor: user,
|
actor: user,
|
||||||
owner: true,
|
owner: true,
|
||||||
exp: false,
|
exp: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "space-owners-true",
|
name: "repo-owners-true",
|
||||||
bypass: DefBypass{UserIDs: nil, SpaceOwners: true},
|
bypass: DefBypass{UserIDs: nil, RepoOwners: true},
|
||||||
actor: user,
|
actor: user,
|
||||||
owner: true,
|
owner: true,
|
||||||
exp: true,
|
exp: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "selected-false",
|
name: "selected-false",
|
||||||
bypass: DefBypass{UserIDs: []int64{1, 66}, SpaceOwners: false},
|
bypass: DefBypass{UserIDs: []int64{1, 66}, RepoOwners: false},
|
||||||
actor: user,
|
actor: user,
|
||||||
exp: false,
|
exp: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "selected-true",
|
name: "selected-true",
|
||||||
bypass: DefBypass{UserIDs: []int64{1, 42, 66}, SpaceOwners: false},
|
bypass: DefBypass{UserIDs: []int64{1, 42, 66}, RepoOwners: false},
|
||||||
actor: user,
|
actor: user,
|
||||||
exp: true,
|
exp: true,
|
||||||
},
|
},
|
||||||
|
@ -26,12 +26,12 @@ type (
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefChangeVerifyInput struct {
|
RefChangeVerifyInput struct {
|
||||||
Actor *types.Principal
|
Actor *types.Principal
|
||||||
IsSpaceOwner bool
|
IsRepoOwner bool
|
||||||
Repo *types.Repository
|
Repo *types.Repository
|
||||||
RefAction RefAction
|
RefAction RefAction
|
||||||
RefType RefType
|
RefType RefType
|
||||||
RefNames []string
|
RefNames []string
|
||||||
}
|
}
|
||||||
|
|
||||||
RefType int
|
RefType int
|
||||||
|
@ -33,7 +33,7 @@ type (
|
|||||||
|
|
||||||
MergeVerifyInput struct {
|
MergeVerifyInput struct {
|
||||||
Actor *types.Principal
|
Actor *types.Principal
|
||||||
IsSpaceOwner bool
|
IsRepoOwner bool
|
||||||
Membership *types.Membership
|
Membership *types.Membership
|
||||||
TargetRepo *types.Repository
|
TargetRepo *types.Repository
|
||||||
SourceRepo *types.Repository
|
SourceRepo *types.Repository
|
||||||
|
@ -152,8 +152,7 @@ const BranchProtectionForm = (props: {
|
|||||||
const excludeArr = excludeList?.map((arr: string) => ['exclude', arr])
|
const excludeArr = excludeList?.map((arr: string) => ['exclude', arr])
|
||||||
const finalArray = [...includeArr, ...excludeArr]
|
const finalArray = [...includeArr, ...excludeArr]
|
||||||
const idsArray = (rule?.definition as ProtectionBranch)?.bypass?.user_ids
|
const idsArray = (rule?.definition as ProtectionBranch)?.bypass?.user_ids
|
||||||
const filteredArray = users?.filter(user => idsArray?.includes(user.id as number))
|
const bypassList = users?.filter(user => idsArray?.includes(user.id as number))?.map(user => `${user.id} ${user.display_name}`)
|
||||||
const resultArray = filteredArray?.map(user => `${user.id} ${user.display_name}`)
|
|
||||||
return {
|
return {
|
||||||
name: rule?.uid,
|
name: rule?.uid,
|
||||||
desc: rule.description,
|
desc: rule.description,
|
||||||
@ -161,8 +160,8 @@ const BranchProtectionForm = (props: {
|
|||||||
target: '',
|
target: '',
|
||||||
targetDefault: (rule?.pattern as ProtectionPattern)?.default,
|
targetDefault: (rule?.pattern as ProtectionPattern)?.default,
|
||||||
targetList: finalArray,
|
targetList: finalArray,
|
||||||
allProjectOwners: (rule.definition as ProtectionBranch)?.bypass?.space_owners,
|
allRepoOwners: (rule.definition as ProtectionBranch)?.bypass?.repo_owners,
|
||||||
projectOwners: resultArray,
|
bypassList: bypassList,
|
||||||
requireMinReviewers: minReviewerCheck,
|
requireMinReviewers: minReviewerCheck,
|
||||||
minReviewers: minReviewerCheck
|
minReviewers: minReviewerCheck
|
||||||
? (rule.definition as ProtectionBranch)?.pullreq?.approvals?.require_minimum_count
|
? (rule.definition as ProtectionBranch)?.pullreq?.approvals?.require_minimum_count
|
||||||
@ -202,7 +201,7 @@ const BranchProtectionForm = (props: {
|
|||||||
const excludeArray =
|
const excludeArray =
|
||||||
formData?.targetList?.filter(([type]) => type === 'exclude').map(([, value]) => value) ?? []
|
formData?.targetList?.filter(([type]) => type === 'exclude').map(([, value]) => value) ?? []
|
||||||
|
|
||||||
const intArray = formData?.projectOwners?.map(item => parseInt(item.split(' ')[0]))
|
const bypassList = formData?.bypassList?.map(item => parseInt(item.split(' ')[0]))
|
||||||
const payload: OpenapiRule = {
|
const payload: OpenapiRule = {
|
||||||
uid: formData.name,
|
uid: formData.name,
|
||||||
type: 'branch',
|
type: 'branch',
|
||||||
@ -215,8 +214,8 @@ const BranchProtectionForm = (props: {
|
|||||||
},
|
},
|
||||||
definition: {
|
definition: {
|
||||||
bypass: {
|
bypass: {
|
||||||
user_ids: intArray,
|
user_ids: bypassList,
|
||||||
space_owners: formData.allProjectOwners
|
repo_owners: formData.allRepoOwners
|
||||||
},
|
},
|
||||||
pullreq: {
|
pullreq: {
|
||||||
approvals: {
|
approvals: {
|
||||||
@ -253,7 +252,7 @@ const BranchProtectionForm = (props: {
|
|||||||
}}>
|
}}>
|
||||||
{formik => {
|
{formik => {
|
||||||
const targetList = formik.values.targetList
|
const targetList = formik.values.targetList
|
||||||
const bypassList = formik.values.projectOwners
|
const bypassList = formik.values.bypassList
|
||||||
const minReviewers = formik.values.requireMinReviewers
|
const minReviewers = formik.values.requireMinReviewers
|
||||||
const statusChecks = formik.values.statusChecks
|
const statusChecks = formik.values.statusChecks
|
||||||
const limitMergeStrats = formik.values.limitMergeStrategies
|
const limitMergeStrats = formik.values.limitMergeStrategies
|
||||||
@ -394,22 +393,26 @@ const BranchProtectionForm = (props: {
|
|||||||
<Text className={css.headingSize} padding={{ bottom: 'medium' }} font={{ variation: FontVariation.H4 }}>
|
<Text className={css.headingSize} padding={{ bottom: 'medium' }} font={{ variation: FontVariation.H4 }}>
|
||||||
{getString('branchProtection.bypassList')}
|
{getString('branchProtection.bypassList')}
|
||||||
</Text>
|
</Text>
|
||||||
<FormInput.CheckBox label={getString('branchProtection.allProjectOwners')} name={'allProjectOwners'} />
|
<FormInput.CheckBox label={getString('branchProtection.allRepoOwners')} name={'allRepoOwners'} />
|
||||||
<FormInput.Select
|
<FormInput.Select
|
||||||
items={userOptions}
|
items={userOptions}
|
||||||
onQueryChange={setSearchTerm}
|
onQueryChange={setSearchTerm}
|
||||||
className={css.widthContainer}
|
className={css.widthContainer}
|
||||||
onChange={item => {
|
onChange={item => {
|
||||||
bypassList?.push(item.value as string)
|
const id = item.value?.toString().split(' ')[0]
|
||||||
const uniqueArr = Array.from(new Set(bypassList))
|
const displayName = item.label
|
||||||
formik.setFieldValue('projectOwners', uniqueArr)
|
const bypassEntry = `${id} ${displayName}`
|
||||||
|
|
||||||
// formik.values.projectOwners.push(item.value as number)
|
bypassList?.push(bypassEntry)
|
||||||
|
const uniqueArr = Array.from(new Set(bypassList))
|
||||||
|
formik.setFieldValue('bypassList', uniqueArr)
|
||||||
}}
|
}}
|
||||||
name={'projectOwners'}></FormInput.Select>
|
name={'bypassList'}></FormInput.Select>
|
||||||
<Container className={cx(css.widthContainer, css.bypassContainer)}>
|
<Container className={cx(css.widthContainer, css.bypassContainer)}>
|
||||||
{bypassList?.map((owner, idx) => {
|
{bypassList?.map((owner, idx) => {
|
||||||
const name = owner.split(' ')[1]
|
const nameIdx = owner.indexOf(" ") + 1
|
||||||
|
const name = owner.substring(nameIdx)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout.Horizontal key={`${name}-${idx}`} flex={{ align: 'center-center' }} padding={'small'}>
|
<Layout.Horizontal key={`${name}-${idx}`} flex={{ align: 'center-center' }} padding={'small'}>
|
||||||
<Avatar hoverCard={false} size="small" name={name.toString()} />
|
<Avatar hoverCard={false} size="small" name={name.toString()} />
|
||||||
@ -423,7 +426,7 @@ const BranchProtectionForm = (props: {
|
|||||||
const filteredData = bypassList.filter(
|
const filteredData = bypassList.filter(
|
||||||
item => !(item[0] === owner[0] && item[1] === owner[1])
|
item => !(item[0] === owner[0] && item[1] === owner[1])
|
||||||
)
|
)
|
||||||
formik.setFieldValue('projectOwners', filteredData)
|
formik.setFieldValue('bypassList', filteredData)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Layout.Horizontal>
|
</Layout.Horizontal>
|
||||||
@ -444,7 +447,7 @@ const BranchProtectionForm = (props: {
|
|||||||
<Layout.Horizontal spacing="small">
|
<Layout.Horizontal spacing="small">
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
text={editMode ? getString('branchProtection.editRule') : getString('branchProtection.createRule')}
|
text={editMode ? getString('branchProtection.saveRule') : getString('branchProtection.createRule')}
|
||||||
variation={ButtonVariation.PRIMARY}
|
variation={ButtonVariation.PRIMARY}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
/>
|
/>
|
||||||
|
@ -44,7 +44,7 @@ export interface StringsMap {
|
|||||||
branchDoesNotHaveFile: string
|
branchDoesNotHaveFile: string
|
||||||
branchName: string
|
branchName: string
|
||||||
branchNotFound: string
|
branchNotFound: string
|
||||||
'branchProtection.allProjectOwners': string
|
'branchProtection.allRepoOwners': string
|
||||||
'branchProtection.autoDeleteText': string
|
'branchProtection.autoDeleteText': string
|
||||||
'branchProtection.autoDeleteTitle': string
|
'branchProtection.autoDeleteTitle': string
|
||||||
'branchProtection.blockBranchCreation': string
|
'branchProtection.blockBranchCreation': string
|
||||||
@ -86,6 +86,7 @@ export interface StringsMap {
|
|||||||
'branchProtection.ruleDeleted': string
|
'branchProtection.ruleDeleted': string
|
||||||
'branchProtection.ruleEmpty': string
|
'branchProtection.ruleEmpty': string
|
||||||
'branchProtection.ruleUpdated': string
|
'branchProtection.ruleUpdated': string
|
||||||
|
'branchProtection.saveRule': string
|
||||||
'branchProtection.statusCheck': string
|
'branchProtection.statusCheck': string
|
||||||
'branchProtection.targetBranches': string
|
'branchProtection.targetBranches': string
|
||||||
'branchProtection.targetPlaceholder': string
|
'branchProtection.targetPlaceholder': string
|
||||||
|
@ -859,7 +859,7 @@ branchProtection:
|
|||||||
defaultBranch: Default branch
|
defaultBranch: Default branch
|
||||||
bypassList: Bypass List
|
bypassList: Bypass List
|
||||||
newBranchProtectionRule: New Branch Protection Rule
|
newBranchProtectionRule: New Branch Protection Rule
|
||||||
allProjectOwners: All project owners
|
allRepoOwners: Allow users with edit permission on the repository to bypass
|
||||||
protectionSelectAll: 'Protections: Select all that apply'
|
protectionSelectAll: 'Protections: Select all that apply'
|
||||||
requireMinReviewersTitle: Require a minimum number of reviewers
|
requireMinReviewersTitle: Require a minimum number of reviewers
|
||||||
requireMinReviewersContent: Require approval on pull requests from a minimum number of reviewers
|
requireMinReviewersContent: Require approval on pull requests from a minimum number of reviewers
|
||||||
@ -883,6 +883,7 @@ branchProtection:
|
|||||||
blockBranchDeletion: Block branch deletion
|
blockBranchDeletion: Block branch deletion
|
||||||
blockBranchDeletionText: Only allow users with bypass permission to delete matching branches
|
blockBranchDeletionText: Only allow users with bypass permission to delete matching branches
|
||||||
editRule: Edit Rule
|
editRule: Edit Rule
|
||||||
|
saveRule: Save Rule
|
||||||
deleteRule: Delete Rule
|
deleteRule: Delete Rule
|
||||||
ruleDeleted: Rule Deleted
|
ruleDeleted: Rule Deleted
|
||||||
ruleEmpty: There are no rules in your repo. Click the button below to create a rule.
|
ruleEmpty: There are no rules in your repo. Click the button below to create a rule.
|
||||||
|
@ -470,7 +470,7 @@ export interface ProtectionDefApprovals {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ProtectionDefBypass {
|
export interface ProtectionDefBypass {
|
||||||
space_owners?: boolean
|
repo_owners?: boolean
|
||||||
user_ids?: number[]
|
user_ids?: number[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7557,7 +7557,7 @@ components:
|
|||||||
type: object
|
type: object
|
||||||
ProtectionDefBypass:
|
ProtectionDefBypass:
|
||||||
properties:
|
properties:
|
||||||
space_owners:
|
repo_owners:
|
||||||
type: boolean
|
type: boolean
|
||||||
user_ids:
|
user_ids:
|
||||||
items:
|
items:
|
||||||
|
@ -208,8 +208,8 @@ export const rulesFormInitialPayload = {
|
|||||||
target: '',
|
target: '',
|
||||||
targetDefault: true,
|
targetDefault: true,
|
||||||
targetList: [] as string[][],
|
targetList: [] as string[][],
|
||||||
allProjectOwners: false,
|
allRepoOwners: false,
|
||||||
projectOwners: [] as string[],
|
bypassList: [] as string[],
|
||||||
requireMinReviewers: false,
|
requireMinReviewers: false,
|
||||||
minReviewers: '',
|
minReviewers: '',
|
||||||
requireCodeOwner: false,
|
requireCodeOwner: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user