Skip to content

Commit

Permalink
Add attack track controls to gitRegoStore
Browse files Browse the repository at this point in the history
Signed-off-by: YiscahLevySilas1 <[email protected]>
  • Loading branch information
YiscahLevySilas1 committed Aug 10, 2023
1 parent 6350f9d commit bdb6ab5
Show file tree
Hide file tree
Showing 8 changed files with 834 additions and 542 deletions.
2 changes: 2 additions & 0 deletions gitregostore/datastructures.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type GitRegoStore struct {
DefaultConfigInputsLock sync.RWMutex
rulesLock sync.RWMutex
controlsLock sync.RWMutex
attackTrackControlsLock sync.RWMutex
attackTracksLock sync.RWMutex
systemPostureExceptionPoliciesLock sync.RWMutex
controlRelationsLock sync.RWMutex
Expand All @@ -39,6 +40,7 @@ type GitRegoStore struct {
AttackTracks []v1alpha1.AttackTrack
Frameworks []opapolicy.Framework
Controls []opapolicy.Control
AttackTrackControls []opapolicy.Control
Rules []opapolicy.PolicyRule
SystemPostureExceptionPolicies []armotypes.PostureExceptionPolicy
FrequencyPullFromGitMinutes int
Expand Down
22 changes: 22 additions & 0 deletions gitregostore/gitstoremethods.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,28 @@ func (gs *GitRegoStore) GetOPAControls() ([]opapolicy.Control, error) {
return controlsList, nil
}

func (gs *GitRegoStore) GetOPAAttackTrackControls() ([]opapolicy.Control, error) {
gs.attackTrackControlsLock.RLock()
defer gs.attackTrackControlsLock.RUnlock()

if gs.AttackTrackControls == nil {
return nil, fmt.Errorf("no controls found in GitRegoStore")
}

attackTrackControlsList := make([]opapolicy.Control, 0, len(gs.AttackTrackControls))
for _, controlToPin := range gs.AttackTrackControls {
control := controlToPin

if err := gs.fillRulesAndRulesIDsInControl(&control); err != nil {
return nil, err
}

attackTrackControlsList = append(attackTrackControlsList, control)
}

return attackTrackControlsList, nil
}

func (gs *GitRegoStore) GetOPAControlsNamesList() ([]string, error) {
gs.controlsLock.RLock()
defer gs.controlsLock.RUnlock()
Expand Down
10 changes: 10 additions & 0 deletions gitregostore/gitstoremethods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ func gs_tests(t *testing.T, gs *GitRegoStore) {
)
})

t.Run("should retrieve OPA Attack Track controls", func(t *testing.T) {
t.Parallel()

controls, err := gs.GetOPAAttackTrackControls()
assert.NoError(t, err)
assert.NotEmptyf(t, controls,
"failed to get attack track controls %v", err,
)
})

t.Run("should retrieve OPA control by id or name", func(t *testing.T) {
t.Parallel()

Expand Down
19 changes: 19 additions & 0 deletions gitregostore/gitstoreutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ func (gs *GitRegoStore) setAttackTracks(respStr string) error {
return nil
}

// Set controls set the controls list and attackTrackControls in gitRegoStore
func (gs *GitRegoStore) setControls(respStr string) error {
controls := []opapolicy.Control{}
if err := JSONDecoder(respStr).Decode(&controls); err != nil {
Expand All @@ -204,6 +205,24 @@ func (gs *GitRegoStore) setControls(respStr string) error {
defer gs.controlsLock.Unlock()

gs.Controls = controls
gs.setAttackTracksControls()
return nil
}

// GetAttackTracksControls sets controls that are related to attack tracks
func (gs *GitRegoStore) setAttackTracksControls() error {
allAttackTrackControls := []opapolicy.Control{}

for i, control := range gs.Controls {
controlCategories := control.GetAllAttackTrackCategories()
if controlCategories != nil && len(controlCategories) > 0 {

Check failure on line 218 in gitregostore/gitstoreutils.go

View workflow job for this annotation

GitHub Actions / test_pr_checks / Basic-Test

S1009: should omit nil check; len() for []github.com/kubescape/opa-utils/reporthandling.AttackTrackCategories is defined as zero (gosimple)
allAttackTrackControls = append(allAttackTrackControls, gs.Controls[i])
}
}
gs.attackTrackControlsLock.Lock()
defer gs.attackTrackControlsLock.Unlock()
gs.AttackTrackControls = allAttackTrackControls

return nil
}

Expand Down
64 changes: 64 additions & 0 deletions gitregostore/gitstoreutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,67 @@ func TestHasNumbers(t *testing.T) {
}
}
}

func TestSetControls(t *testing.T) {
store := &GitRegoStore{}
// Successful test case
respStr := `[{"name": "control1"}, {"name": "control2"}]`
err := store.setControls(respStr)
if err != nil {
t.Errorf("Error setting controls: %v", err)
}
if len(store.Controls) != 2 {
t.Errorf("Controls not added to store")
}
if len(store.AttackTrackControls) != 0 {
t.Errorf("Attack track controls not added to store")
}

// Error test case
respStr = `invalid JSON`
expectedErr := errors.New("invalid character 'i' looking for beginning of value")
err = store.setControls(respStr)
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("Expected error '%v', but got: %v", expectedErr, err)
}
if len(store.Controls) != 2 {
t.Errorf("Expected 2 controls, but got: %d", len(store.Controls))
}

//
respStr = `[{"name":"TEST","attributes":{"armoBuiltin":true,"controlTypeTags":["security","compliance"],"attackTracks":[{"attackTrack": "container","categories": ["Execution","Initial access"]},{"attackTrack": "network","categories": ["Eavesdropping","Spoofing"]}]},"description":"","remediation":"","rulesNames":["CVE-2022-0185"],"id":"C-0079","long_description":"","test":"","controlID":"C-0079","baseScore":4,"example":""}]`
err = store.setControls(respStr)
if err != nil {
t.Errorf("Error setting controls: %v", err)
}
if len(store.Controls) != 1 {
t.Errorf("Controls not added to store")
}
if len(store.AttackTrackControls) != 1 {
t.Errorf("Attack track controls not added to store")
}
}

func TestSetAttackTracks(t *testing.T) {
store := &GitRegoStore{}
// Successful test case
respStr := `[{"name": "attack_track1"}, {"name": "attack_track2"}]`
err := store.setAttackTracks(respStr)
if err != nil {
t.Errorf("Error setting attack tracks: %v", err)
}
if len(store.AttackTracks) != 2 {
t.Errorf("Attack tracks added to store")
}

// Error test case
respStr = `invalid JSON`
expectedErr := errors.New("invalid character 'i' looking for beginning of value")
err = store.setAttackTracks(respStr)
if err == nil || err.Error() != expectedErr.Error() {
t.Errorf("Expected error '%v', but got: %v", expectedErr, err)
}
if len(store.AttackTracks) != 2 {
t.Errorf("Expected 2 attack tracks, but got: %d", len(store.AttackTracks))
}
}
Loading

0 comments on commit bdb6ab5

Please sign in to comment.