11package models
22
33import (
4+ "encoding/json"
45 "fmt"
56 "sync"
7+
8+ "github.com/gomodule/redigo/redis"
69)
710
811// IAttackStore captures all methods related to storing and retrieving attack details
@@ -26,6 +29,108 @@ type IAttackStore interface {
2629
2730var mu sync.RWMutex
2831
32+ // Redis stores all Attack/Report information in a redis database
33+ type Redis struct {
34+ connFn func () redis.Conn
35+ }
36+
37+ func NewRedis (f func () redis.Conn ) Redis {
38+ return Redis {
39+ f ,
40+ }
41+ }
42+
43+ func (r Redis ) Add (attack AttackDetails ) error {
44+ conn := r .connFn ()
45+ defer conn .Close ()
46+
47+ v , err := json .Marshal (attack )
48+ if err != nil {
49+ return err
50+ }
51+ _ , err = conn .Do ("SET" , attack .ID , v )
52+ if err != nil {
53+ return err
54+ }
55+ return nil
56+ }
57+
58+ func (r Redis ) GetAll (filterParams FilterParams ) []AttackDetails {
59+ attacks := make ([]AttackDetails , 0 )
60+
61+ filters := createFilterChain (filterParams )
62+ conn := r .connFn ()
63+ defer conn .Close ()
64+
65+ res , err := conn .Do ("KEYS" , "*" )
66+ if err != nil {
67+ return nil
68+ }
69+ attackIDs , ok := res .([]interface {})
70+ if ! ok {
71+ return nil
72+ }
73+
74+ for _ , attackID := range attackIDs {
75+ var attack AttackDetails
76+
77+ res , err := conn .Do ("GET" , attackID )
78+ if err != nil {
79+ return nil
80+ }
81+
82+ err = json .Unmarshal (res .([]byte ), & attack )
83+ if err != nil {
84+ return nil
85+ }
86+ for _ , filter := range filters {
87+ if ! filter (attack ) {
88+ goto skip
89+ }
90+ }
91+ attacks = append (attacks , attack )
92+ skip:
93+ }
94+
95+ return attacks
96+ }
97+
98+ func (r Redis ) GetByID (id string ) (AttackDetails , error ) {
99+ var attack AttackDetails
100+ conn := r .connFn ()
101+ defer conn .Close ()
102+
103+ res , err := conn .Do ("GET" , id )
104+ if err != nil {
105+ return attack , err
106+ }
107+
108+ err = json .Unmarshal (res .([]byte ), & attack )
109+ if err != nil {
110+ return attack , err
111+ }
112+
113+ return attack , err
114+ }
115+
116+ func (r Redis ) Update (id string , attack AttackDetails ) error {
117+ if attack .ID != id {
118+ return fmt .Errorf ("update ID %s and attack ID %s do not match" , id , attack .ID )
119+ }
120+ return r .Add (attack )
121+ }
122+
123+ func (r Redis ) Delete (id string ) error {
124+ conn := r .connFn ()
125+ defer conn .Close ()
126+
127+ _ , err := conn .Do ("DEL" , id )
128+ if err != nil {
129+ return err
130+ }
131+ return nil
132+ }
133+
29134// TaskMap is a map of attack ID's to their AttackDetails
30135type TaskMap map [string ]AttackDetails
31136
0 commit comments