Add auth-managed proxy UI improvements
This commit is contained in:
@ -28,19 +28,34 @@ func Run(cfg Config) error {
|
||||
db := noodle.NewDatabase(cfg.DataPath)
|
||||
defer db.Close()
|
||||
|
||||
auth, err := web.NewAuth(db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := auth.EnsureDefaultUser(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.RunTest {
|
||||
runTestSequence(db)
|
||||
}
|
||||
|
||||
go systemCheck(db, noodleChannel)
|
||||
go expirationCheck(db, noodleChannel)
|
||||
go proxify(noodleChannel)
|
||||
go proxify(db, noodleChannel)
|
||||
|
||||
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(web.StaticFiles()))))
|
||||
http.HandleFunc("/", web.HandleMain(db, &noodleChannel))
|
||||
http.HandleFunc("/add", web.HandleAdd(db, &noodleChannel))
|
||||
http.HandleFunc("/toggle", web.HandleToggle(db, &noodleChannel))
|
||||
http.HandleFunc("/delete", web.HandleDelete(db, &noodleChannel))
|
||||
http.HandleFunc("/login", auth.HandleLogin())
|
||||
http.HandleFunc("/logout", auth.HandleLogout())
|
||||
http.HandleFunc("/", auth.RequireAuth(web.HandleMain(db, &noodleChannel, auth)))
|
||||
http.HandleFunc("/users", auth.RequireAuth(web.HandleUsers(auth, db)))
|
||||
http.HandleFunc("/users/add", auth.RequireAdmin(web.HandleAddUser(auth, db)))
|
||||
http.HandleFunc("/users/role", auth.RequireAdmin(web.HandleSetUserRole(auth, db)))
|
||||
http.HandleFunc("/users/password", auth.RequireAuth(web.HandleChangePassword(auth, db)))
|
||||
http.HandleFunc("/users/delete", auth.RequireAuth(web.HandleDeleteUser(auth, db)))
|
||||
http.HandleFunc("/add", auth.RequireAuth(web.HandleAdd(db, &noodleChannel, auth)))
|
||||
http.HandleFunc("/toggle", auth.RequireAuth(web.HandleToggle(db, &noodleChannel)))
|
||||
http.HandleFunc("/delete", auth.RequireAuth(web.HandleDelete(db, &noodleChannel)))
|
||||
|
||||
log.Printf("Server starting on %s", listenAddr)
|
||||
return http.ListenAndServe(listenAddr, nil)
|
||||
@ -56,7 +71,7 @@ func systemCheck(db *noodle.Database, noodleChannel chan noodle.Noodle) {
|
||||
}
|
||||
}
|
||||
|
||||
func proxify(noodleChannel chan noodle.Noodle) {
|
||||
func proxify(db *noodle.Database, noodleChannel chan noodle.Noodle) {
|
||||
noodleMap := make(map[string]managedProxy)
|
||||
for {
|
||||
item := <-noodleChannel
|
||||
@ -65,6 +80,9 @@ func proxify(noodleChannel chan noodle.Noodle) {
|
||||
proxy, err := newProxy(item)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
if _, updateErr := db.SetIsUp(item.Id, false); updateErr != nil {
|
||||
log.Print(updateErr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
noodleMap[item.Id] = proxy
|
||||
@ -408,15 +426,73 @@ func (p *udpNoodleProxy) Close() error {
|
||||
return conn.Close()
|
||||
}
|
||||
|
||||
func allowSource(allowedIP string, addr net.Addr) bool {
|
||||
if allowedIP == "" || allowedIP == "All" {
|
||||
func allowSource(allowedIPs string, addr net.Addr) bool {
|
||||
if allowedIPs == "" || strings.EqualFold(strings.TrimSpace(allowedIPs), "All") {
|
||||
return true
|
||||
}
|
||||
host, _, err := net.SplitHostPort(addr.String())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return host == allowedIP
|
||||
hostIP := normalizeIP(net.ParseIP(host))
|
||||
if hostIP == nil {
|
||||
return false
|
||||
}
|
||||
for _, item := range strings.Split(allowedIPs, ",") {
|
||||
entry := strings.TrimSpace(item)
|
||||
if strings.Contains(entry, "/") {
|
||||
_, network, err := net.ParseCIDR(entry)
|
||||
if err == nil && networkContainsIP(network, hostIP) {
|
||||
return true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
entryIP := normalizeIP(net.ParseIP(entry))
|
||||
if entryIP != nil && entryIP.Equal(hostIP) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func normalizeIP(ip net.IP) net.IP {
|
||||
if ip == nil {
|
||||
return nil
|
||||
}
|
||||
if v4 := ip.To4(); v4 != nil {
|
||||
return v4
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
func networkContainsIP(network *net.IPNet, ip net.IP) bool {
|
||||
if network == nil || ip == nil {
|
||||
return false
|
||||
}
|
||||
if network.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
|
||||
networkIP := normalizeIP(network.IP)
|
||||
normalizedIP := normalizeIP(ip)
|
||||
if networkIP == nil || normalizedIP == nil {
|
||||
return false
|
||||
}
|
||||
if len(networkIP) != len(normalizedIP) {
|
||||
return false
|
||||
}
|
||||
|
||||
mask := network.Mask
|
||||
if len(mask) != len(normalizedIP) {
|
||||
return false
|
||||
}
|
||||
for i := range normalizedIP {
|
||||
if normalizedIP[i]&mask[i] != networkIP[i]&mask[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func closeWrite(conn net.Conn) {
|
||||
@ -440,42 +516,9 @@ func expirationCheck(db *noodle.Database, noodleChannel chan noodle.Noodle) {
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
noodles := db.GetAll()
|
||||
for _, item := range noodles {
|
||||
if !item.IsUp {
|
||||
continue
|
||||
}
|
||||
if item.Expiration <= 0 {
|
||||
if item.IsUp {
|
||||
item.IsUp = false
|
||||
noodleChannel <- item
|
||||
}
|
||||
if err := db.Delete(item.Id); err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
item.Expiration -= time.Second
|
||||
if item.Expiration <= 0 {
|
||||
item.Expiration = 0
|
||||
if err := db.Update(item); err != nil {
|
||||
log.Print(err)
|
||||
continue
|
||||
}
|
||||
if item.IsUp {
|
||||
item.IsUp = false
|
||||
noodleChannel <- item
|
||||
}
|
||||
if err := db.Delete(item.Id); err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if err := db.Update(item); err != nil {
|
||||
log.Print(err)
|
||||
}
|
||||
stopped := db.TickExpirations()
|
||||
for _, item := range stopped {
|
||||
noodleChannel <- item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user