mirror of
https://github.com/harness/drone.git
synced 2025-05-01 21:21:11 +00:00
146 lines
3.3 KiB
Go
146 lines
3.3 KiB
Go
// Copyright 2023 Harness, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package protection
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/harness/gitness/app/store"
|
|
"github.com/harness/gitness/types"
|
|
)
|
|
|
|
type (
|
|
Sanitizer interface {
|
|
// Sanitize validates if the definition is valid and automatically corrects minor issues.
|
|
Sanitize() error
|
|
}
|
|
|
|
Protection interface {
|
|
MergeVerifier
|
|
RefChangeVerifier
|
|
|
|
UserIDs() ([]int64, error)
|
|
}
|
|
|
|
Definition interface {
|
|
Sanitizer
|
|
Protection
|
|
}
|
|
|
|
// DefinitionGenerator is the function that creates blank rules.
|
|
DefinitionGenerator func() Definition
|
|
|
|
// Manager is used to enforce protection rules.
|
|
Manager struct {
|
|
defGenMap map[types.RuleType]DefinitionGenerator
|
|
ruleStore store.RuleStore
|
|
}
|
|
)
|
|
|
|
var (
|
|
ErrUnrecognizedType = errors.New("unrecognized protection type")
|
|
ErrAlreadyRegistered = errors.New("protection type already registered")
|
|
ErrPatternEmpty = errors.New("name pattern can't be empty")
|
|
ErrInvalidGlobstarPattern = errors.New("invalid globstar pattern")
|
|
)
|
|
|
|
func IsCritical(violations []types.RuleViolations) bool {
|
|
for i := range violations {
|
|
if violations[i].IsCritical() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IsBypassed(violations []types.RuleViolations) bool {
|
|
for i := range violations {
|
|
if violations[i].IsBypassed() {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// NewManager creates new protection Manager.
|
|
func NewManager(ruleStore store.RuleStore) *Manager {
|
|
return &Manager{
|
|
defGenMap: make(map[types.RuleType]DefinitionGenerator),
|
|
ruleStore: ruleStore,
|
|
}
|
|
}
|
|
|
|
// Register registers new types.RuleType.
|
|
func (m *Manager) Register(ruleType types.RuleType, gen DefinitionGenerator) error {
|
|
_, ok := m.defGenMap[ruleType]
|
|
if ok {
|
|
return ErrAlreadyRegistered
|
|
}
|
|
|
|
m.defGenMap[ruleType] = gen
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *Manager) FromJSON(ruleType types.RuleType, message json.RawMessage, strict bool) (Protection, error) {
|
|
gen := m.defGenMap[ruleType]
|
|
if gen == nil {
|
|
return nil, ErrUnrecognizedType
|
|
}
|
|
|
|
decoder := json.NewDecoder(bytes.NewReader(message))
|
|
|
|
if strict {
|
|
decoder.DisallowUnknownFields()
|
|
}
|
|
|
|
r := gen()
|
|
|
|
if err := decoder.Decode(&r); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := r.Sanitize(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
func (m *Manager) SanitizeJSON(ruleType types.RuleType, message json.RawMessage) (json.RawMessage, error) {
|
|
r, err := m.FromJSON(ruleType, message, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ToJSON(r)
|
|
}
|
|
|
|
func (m *Manager) ForRepository(ctx context.Context, repoID int64) (Protection, error) {
|
|
ruleInfos, err := m.ruleStore.ListAllRepoRules(ctx, repoID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to list rules for repository: %w", err)
|
|
}
|
|
|
|
return ruleSet{
|
|
rules: ruleInfos,
|
|
manager: m,
|
|
}, nil
|
|
}
|