Skip to content
This repository was archived by the owner on Apr 27, 2026. It is now read-only.

Commit 6f86ab3

Browse files
author
Aaron Meihm
authored
Merge pull request #9 from mozilla-services/ajvb/dump-reputation
Endpoint to dump reputation entires
2 parents 0b92138 + 6e9d4f2 commit 6f86ab3

5 files changed

Lines changed: 94 additions & 0 deletions

File tree

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,23 @@ error will be logged.
131131
]
132132
```
133133

134+
#### GET /dump
135+
136+
Returns all reputation entries.
137+
138+
**Note: This makes use of the [KEYS](https://redis.io/commands/keys) redis command, which is known to be very slow. Use with care.**
139+
140+
##### Response body
141+
142+
```json
143+
[
144+
{"ip": "10.0.0.1", "reputation": 75, "reviewed": false, "lastupdated": "2018-04-23T18:25:43.511Z"},
145+
{"ip": "10.0.0.2", "reputation": 50, "reviewed": false, "lastupdated": "2018-04-23T18:31:27.457Z"},
146+
{"ip": "10.0.20.2", "reputation": 25, "reviewed": false, "lastupdated": "2018-04-23T17:22:42.230Z"},
147+
]
148+
```
149+
150+
134151
#### GET /\_\_heartbeat\_\_
135152

136153
Service heartbeat endpoint.

http.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ func newRouter() *mux.Router {
5656
r.HandleFunc("/{ip:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}}", auth(httpDeleteReputation)).Methods("DELETE")
5757
r.HandleFunc("/violations/{ip:(?:[0-9]{1,3}\\.){3}[0-9]{1,3}}", auth(httpPutViolation)).Methods("PUT")
5858
r.HandleFunc("/violations", auth(httpPutViolations)).Methods("PUT")
59+
r.HandleFunc("/dump", auth(httpGetAllReputation)).Methods("GET")
5960

6061
return r
6162
}
@@ -88,6 +89,27 @@ func httpGetViolations(w http.ResponseWriter, r *http.Request) {
8889
w.Write(buf)
8990
}
9091

92+
func httpGetAllReputation(w http.ResponseWriter, r *http.Request) {
93+
allRep, err := repDump()
94+
if err != nil {
95+
if err == redis.Nil {
96+
w.WriteHeader(http.StatusNotFound)
97+
return
98+
}
99+
log.Warnf(err.Error())
100+
w.WriteHeader(http.StatusInternalServerError)
101+
return
102+
}
103+
buf, err := json.Marshal(allRep)
104+
if err != nil {
105+
log.Warnf(err.Error())
106+
w.WriteHeader(http.StatusInternalServerError)
107+
return
108+
}
109+
w.Header().Set("Content-Type", "application/json")
110+
w.Write(buf)
111+
}
112+
91113
func httpGetReputation(w http.ResponseWriter, r *http.Request) {
92114
ipstr := mux.Vars(r)["ip"]
93115
if net.ParseIP(ipstr) == nil {

http_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,35 @@ func TestHandlers(t *testing.T) {
110110
h.ServeHTTP(recorder, req)
111111
assert.Equal(t, http.StatusBadRequest, recorder.Code)
112112

113+
// dump reputation
114+
recorder = httptest.NewRecorder()
115+
req = httptest.NewRequest("GET", "/dump", nil)
116+
h.ServeHTTP(recorder, req)
117+
assert.Equal(t, http.StatusOK, recorder.Code)
118+
res = recorder.Result()
119+
assert.Equal(t, "application/json", res.Header.Get("Content-Type"))
120+
buf, err = ioutil.ReadAll(res.Body)
121+
assert.Nil(t, err)
122+
var reputations []Reputation
123+
err = json.Unmarshal(buf, &reputations)
124+
assert.Nil(t, err)
125+
assert.Equal(t, 3, len(reputations))
126+
c := 0
127+
for _, rep := range reputations {
128+
if rep.IP == "192.168.2.20" {
129+
c += 1
130+
assert.Equal(t, "192.168.2.20", rep.IP)
131+
assert.Equal(t, 25, rep.Reputation)
132+
}
133+
if rep.IP == "192.168.0.1" {
134+
c += 1
135+
assert.Equal(t, "192.168.0.1", rep.IP)
136+
assert.Equal(t, 50, rep.Reputation)
137+
}
138+
assert.Equal(t, false, rep.Reviewed)
139+
}
140+
assert.Equal(t, 2, c)
141+
113142
// delete entry
114143
recorder = httptest.NewRecorder()
115144
req = httptest.NewRequest("DELETE", "/192.168.2.20", nil)

redis.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ type redisLink struct {
1313
readClients []*redis.Client
1414
}
1515

16+
func (r *redisLink) keys(pattern string) *redis.StringSliceCmd {
17+
return r.master.Keys(pattern)
18+
}
19+
1620
func (r *redisLink) del(k ...string) *redis.IntCmd {
1721
return r.master.Del(k...)
1822
}

score.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,25 @@ func repDelete(ipstr string) (err error) {
126126
_, err = sruntime.redis.del(ipstr).Result()
127127
return
128128
}
129+
130+
func repDump() (ret []Reputation, err error) {
131+
keys, err := sruntime.redis.keys("*").Result()
132+
if err != nil {
133+
return
134+
}
135+
136+
for _, ip := range keys {
137+
buf, err := sruntime.redis.get(ip)
138+
if err != nil {
139+
return ret, err
140+
}
141+
reputation := Reputation{}
142+
err = json.Unmarshal(buf, &reputation)
143+
if err != nil {
144+
return ret, err
145+
}
146+
ret = append(ret, reputation)
147+
}
148+
149+
return
150+
}

0 commit comments

Comments
 (0)