-
Notifications
You must be signed in to change notification settings - Fork 5
/
whitelist.go
142 lines (126 loc) · 2.89 KB
/
whitelist.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"log"
"net"
"os"
"strings"
"time"
)
type Whitelist struct {
List map[string]string // key = alecpinson123456, value = 123.123.123.123/32
}
func (*Whitelist) init() {
// load config
c.load()
// connect to redis database
if !r.connect(c.Redis) {
os.Exit(1)
}
// enable ttl check on whitelisted ips
go w.ttl()
// initialize authentication
go h.init(c.Auth)
// update resources on startup
w.updateResources()
// initialize http
h.start()
}
func (w *Whitelist) add(u *User) bool {
w.List = r.getWhitelist()
if w.inRange(u.ip, c.IPWhiteList) {
return false
}
ret := r.addGroups(u.key, u.groups)
if !ret {
return ret
}
if w.List[u.key] != u.cidr {
// need to update list
if w.List[u.key] == "" {
log.Println("whitelist.add(): no current whitelist for '" + u.key + "' was found, adding ip " + u.ip)
} else {
log.Println("whitelist.add(): updating whitelist for '" + u.key + "' from " + w.List[u.key] + " to " + u.ip)
}
ret = r.addIp(u.key, u.cidr)
if !ret {
return ret
}
r.apiCalled(u.key)
go w.updateResources()
return true
} else {
// ip already whitelisted ... renew redis expiry time though
log.Println("whitelist.add(): no changes required for '" + u.key + "', ip already set to " + u.ip)
if r.canCallApi(u.key) {
r.apiCalled(u.key)
go w.updateResources()
}
return r.setIpExpiry(u.key)
}
}
func (w *Whitelist) delete(u *User) bool {
ret := r.deleteIp(u.key)
if !ret {
return ret
}
w.updateResources()
log.Println("whitelist.delete(): whitelisting for '" + u.key + "' removed.")
return true
}
// trigger removal of ips due to ttl
func (*Whitelist) ttl() {
// run every hour, might need increasing in future
for range time.Tick(time.Hour * 1) {
w.updateResources()
}
}
func (*Whitelist) updateResources() bool {
if c.Auth.TenantId == "notreal-not-real-not-notreal" {
return false
}
w.List = r.getWhitelist()
for _, fd := range a.FrontDoor {
fd.update()
}
for _, st := range a.StorageAccount {
st.update()
}
for _, kv := range a.KeyVault {
kv.update()
}
for _, pg := range a.PostgresServer {
pg.update()
}
for _, rc := range a.RedisCache {
rc.update()
}
for _, cd := range a.CosmosDb {
cd.update()
}
return true
}
func (*Whitelist) inRange(ip string, whitelist []string) bool {
netIp := net.ParseIP(strings.Split(ip, "/")[0])
for _, v := range whitelist {
if strings.Contains(v, "/") {
// cidr, parse it
_, subnet, _ := net.ParseCIDR(v)
if subnet.Contains(netIp) {
// ip has already been whitelisted
if c.Debug {
log.Printf("whitelist.inRange: IPAddress value %v overlaps with already whitelisted value %v", ip, v)
}
return true
}
} else {
// single ip
if v == ip {
// ip has already been whitelisted
if c.Debug {
log.Printf("whitelist.inRange: IPAddress value %v overlaps with already whitelisted value %v", ip, v)
}
}
}
}
return false
}