1 package rulesengine
2
3 import (
4 "context"
5 "fmt"
6 )
7
8 func (reng RulesEngine) ReadRulesForBanner(ctx context.Context, bannerName string) ([]Rule, error) {
9 ruleSegments, err := reng.ds.ReadRulesForBanner(ctx, bannerName)
10 if err != nil {
11 return []Rule{}, fmt.Errorf("error when calling ReadRulesForBanner: %s", err)
12 }
13 return assembleRules(ruleSegments), nil
14 }
15
16 func (reng RulesEngine) ReadRulesForAllBanners(ctx context.Context) ([]ReadBannerRule, error) {
17 bannerRules, err := reng.ds.ReadRulesForAllBanners(ctx)
18 if err != nil {
19 return nil, err
20 }
21
22 return assembleGetBannerRule(bannerRules)
23 }
24
25 func assembleGetBannerRule(bannerSegments []RuleSegment) ([]ReadBannerRule, error) {
26 var res []ReadBannerRule
27 for _, segment := range bannerSegments {
28
29
30 if segment.Banner.BannerID == "" || segment.Banner.BannerName == "" {
31 return res, fmt.Errorf("error in assembeGetBannerRule: Banner was nil")
32 }
33 res = appendBannerSegment(res, segment)
34 }
35
36 return res, nil
37 }
38
39 func appendBannerSegment(rules []ReadBannerRule, segment RuleSegment) []ReadBannerRule {
40 for idx, rule := range rules {
41 if rule.Command.ID != segment.Command.ID {
42 continue
43 }
44
45 rules[idx].Banners = appendPrivToBannerOverlay(rule.Banners, segment.Banner, segment.Privilege)
46
47 return rules
48 }
49
50 rules = append(rules, ReadBannerRule{
51 Command: segment.Command,
52 Banners: []BannerPrivOverrides{{
53 Banner: segment.Banner,
54 Privileges: []Privilege{
55 segment.Privilege,
56 },
57 }},
58 })
59
60 return rules
61 }
62
63 func appendPrivToBannerOverlay(overrides []BannerPrivOverrides, banner Banner, privilege Privilege) []BannerPrivOverrides {
64 for idx, override := range overrides {
65 if override.Banner.BannerID == banner.BannerID {
66 overrides[idx].Privileges = append(override.Privileges, privilege)
67 return overrides
68 }
69 }
70
71 overrides = append(overrides, BannerPrivOverrides{
72 Banner: banner,
73 Privileges: []Privilege{privilege},
74 })
75 return overrides
76 }
77
78 func (reng RulesEngine) DeletePrivilegeFromBannerRule(ctx context.Context, bannerName, commandName, privilegeName string) (DeleteResult, error) {
79 return reng.ds.DeletePrivilegeFromBannerRule(ctx, bannerName, commandName, privilegeName)
80 }
81
82
83
84 func (reng RulesEngine) ReadAllRulesForCommand(ctx context.Context, commandName string) (RuleWithOverrides, error) {
85
86 ruleSegment, err := reng.ds.ReadDefaultRulesForCommand(ctx, commandName)
87 if err != nil {
88 return RuleWithOverrides{}, fmt.Errorf("error finding default rules: %s", err)
89 }
90 defaultRules := assembleRules(ruleSegment)
91
92
93
94
95
96 res := RuleWithOverrides{}
97 if len(defaultRules) != 0 {
98
99 res.Command = defaultRules[0].Command
100 res.Default.Privileges = defaultRules[0].Privileges
101 }
102
103 allBannerRules, err := reng.ReadBannerRulesForCommand(ctx, commandName)
104 if err != nil {
105 return res, fmt.Errorf("error finding banner rules: %s", err)
106 }
107 for _, banner := range allBannerRules.Banners {
108 for _, priv := range banner.Privileges {
109 res.Banners = appendPrivToBannerOverlay(res.Banners, banner.Banner, priv)
110 }
111 res.Command = allBannerRules.Command
112 }
113
114 if len(res.Banners) == 0 {
115
116 res.Banners = []BannerPrivOverrides{}
117 }
118 if len(res.Banners) == 0 && len(res.Default.Privileges) == 0 {
119 return RuleWithOverrides{}, nil
120 }
121 return res, nil
122 }
123
124 func (reng RulesEngine) AddBannerRules(ctx context.Context, bannerName string, rules WriteRules) (AddRuleResult, error) {
125 parts := splitPostRulesToBannerSegment(bannerName, rules)
126 return reng.ds.AddBannerRules(ctx, parts)
127 }
128
129 func splitPostRulesToBannerSegment(bannerName string, rules []WriteRule) []RuleSegment {
130 var parts []RuleSegment
131
132 banner := Banner{BannerName: bannerName}
133
134 for _, rule := range rules {
135 command := Command{Name: rule.Command}
136 for _, privilege := range rule.Privileges {
137 privilege := Privilege{Name: privilege}
138
139 parts = append(parts, RuleSegment{
140 Banner: banner,
141 Command: command,
142 Privilege: privilege,
143 })
144 }
145 }
146
147 return parts
148 }
149
150 func (reng RulesEngine) ReadBannerRulesForCommand(ctx context.Context, commandName string) (ReadBannerRule, error) {
151 parts, err := reng.ds.ReadBannerRulesForCommand(ctx, commandName)
152 if err != nil {
153 return ReadBannerRule{}, fmt.Errorf("error querying for rules: %w", err)
154 }
155
156 if len(parts) == 0 {
157 return ReadBannerRule{}, nil
158 }
159
160 rules, err := assembleGetBannerRule(parts)
161 if err != nil {
162 return ReadBannerRule{}, err
163 }
164
165 if len(rules) != 1 {
166 return ReadBannerRule{}, fmt.Errorf("storage returned unexpected number of rules")
167 }
168
169 return rules[0], nil
170 }
171
172 func (reng RulesEngine) ReadBannerRulesForCommandAndBanner(ctx context.Context, bannerName string, commandName string) (Rule, error) {
173 parts, err := reng.ds.ReadBannerRulesForCommandAndBanner(ctx, bannerName, commandName)
174 if err != nil {
175 return Rule{}, fmt.Errorf("error querying for rules: %w", err)
176 }
177
178 if len(parts) == 0 {
179 return Rule{}, nil
180 }
181
182 rules := assembleRules(parts)
183
184 if len(rules) != 1 {
185 return Rule{}, fmt.Errorf("storage returned unexpected number of rules")
186 }
187
188 return rules[0], nil
189 }
190
View as plain text