-
Notifications
You must be signed in to change notification settings - Fork 348
/
protection_manager.go
71 lines (62 loc) · 2.18 KB
/
protection_manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package branch
import (
"context"
"errors"
"time"
"github.com/gobwas/glob"
"github.com/treeverse/lakefs/pkg/cache"
"github.com/treeverse/lakefs/pkg/graveler"
"github.com/treeverse/lakefs/pkg/graveler/settings"
)
const ProtectionSettingKey = "protected_branches"
const (
matcherCacheSize = 100_000
matcherCacheExpiry = 1 * time.Hour
matcherCacheJitter = 1 * time.Minute
)
type ProtectionManager struct {
settingManager *settings.Manager
matchers cache.Cache
}
func NewProtectionManager(settingManager *settings.Manager) *ProtectionManager {
return &ProtectionManager{settingManager: settingManager, matchers: cache.NewCache(matcherCacheSize, matcherCacheExpiry, cache.NewJitterFn(matcherCacheJitter))}
}
func (m *ProtectionManager) GetRules(ctx context.Context, repository *graveler.RepositoryRecord) (*graveler.BranchProtectionRules, *string, error) {
rulesMsg := &graveler.BranchProtectionRules{}
checksum, err := m.settingManager.GetLatest(ctx, repository, ProtectionSettingKey, rulesMsg)
if err != nil {
return nil, nil, err
}
return rulesMsg, checksum, nil
}
func (m *ProtectionManager) SetRules(ctx context.Context, repository *graveler.RepositoryRecord, rules *graveler.BranchProtectionRules, lastKnownChecksum *string) error {
return m.settingManager.Save(ctx, repository, ProtectionSettingKey, rules, lastKnownChecksum)
}
func (m *ProtectionManager) IsBlocked(ctx context.Context, repository *graveler.RepositoryRecord, branchID graveler.BranchID, action graveler.BranchProtectionBlockedAction) (bool, error) {
rules := &graveler.BranchProtectionRules{}
err := m.settingManager.Get(ctx, repository, ProtectionSettingKey, rules)
if errors.Is(err, graveler.ErrNotFound) {
return false, nil
}
if err != nil {
return false, err
}
for pattern, blockedActions := range rules.BranchPatternToBlockedActions {
pattern := pattern
matcher, err := m.matchers.GetOrSet(pattern, func() (v interface{}, err error) {
return glob.Compile(pattern)
})
if err != nil {
return false, err
}
if !matcher.(glob.Glob).Match(string(branchID)) {
continue
}
for _, c := range blockedActions.GetValue() {
if c == action {
return true, nil
}
}
}
return false, nil
}