initial commit
This commit is contained in:
323
HttpServer.go
Normal file
323
HttpServer.go
Normal file
@@ -0,0 +1,323 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
type HttpServer struct {
|
||||
_server *http.Server
|
||||
_database *Database
|
||||
_oauth *OAuth2
|
||||
_renderer *Renderer
|
||||
_dnsclient *DnsUpdate
|
||||
_ipAddresses map[string][]string
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
type GuiSetting struct {
|
||||
FilterString *string
|
||||
}
|
||||
|
||||
func getIP(r *http.Request) (string, error) {
|
||||
var host string
|
||||
forwarded := r.Header.Get("X-FORWARDED-FOR")
|
||||
if forwarded != "" {
|
||||
host = forwarded
|
||||
} else {
|
||||
host = r.RemoteAddr
|
||||
}
|
||||
|
||||
host,_ , err := net.SplitHostPort(host)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return host, nil
|
||||
}
|
||||
|
||||
func (h *HttpServer) doaction(w http.ResponseWriter, r *http.Request, params *AdminPageParams){
|
||||
if action := r.URL.Query().Get("action"); action != "" {
|
||||
|
||||
switch action {
|
||||
case "update":
|
||||
host := r.URL.Query().Get("host")
|
||||
ip := r.URL.Query().Get("ip")
|
||||
|
||||
if !h._database.ExistHost(host) {
|
||||
params.Alerts = append(params.Alerts, Alert{Type:"error", Message: fmt.Sprintf("host %s does not exist", host)})
|
||||
break
|
||||
}
|
||||
err := h._dnsclient.Update(host, ip)
|
||||
if err != nil {
|
||||
params.Alerts = append(params.Alerts, Alert{Type:"error", Message: err.Error()})
|
||||
} else {
|
||||
params.Alerts = append(params.Alerts, Alert{Type:"success", Message: "successfully updated host"})
|
||||
}
|
||||
break
|
||||
|
||||
case "delete":
|
||||
host := r.URL.Query().Get("host")
|
||||
log.Info("deleting host " + host)
|
||||
h._database.DeleteHost(host)
|
||||
h._dnsclient.Remove(host)
|
||||
delete(h._ipAddresses, host)
|
||||
break
|
||||
|
||||
case "externalresolve":
|
||||
host := r.URL.Query().Get("host")
|
||||
ips, err := h._dnsclient.ExternalResolve(host)
|
||||
if err != nil {
|
||||
params.Alerts = append(params.Alerts, Alert{
|
||||
Type: "error",
|
||||
Message: fmt.Sprintf("host %s could not be resolved", host),
|
||||
})
|
||||
} else {
|
||||
params.Alerts = append(params.Alerts, Alert{
|
||||
Type: "success",
|
||||
Message: fmt.Sprintf("host %s resolved to following addresses:\n %s", host, fmt.Sprint(ips)),
|
||||
})
|
||||
}
|
||||
case "resolve":
|
||||
host := r.URL.Query().Get("host")
|
||||
ipAddresses, err := h._dnsclient.Resolve(host)
|
||||
if err == nil && len(ipAddresses) > 0 {
|
||||
params.Alerts = append(params.Alerts, Alert{
|
||||
Type: "success",
|
||||
Message: fmt.Sprintf("host %s resolved to following addresses:\n %s", host, fmt.Sprint(ipAddresses)),
|
||||
})
|
||||
h._ipAddresses[host] = ipAddresses
|
||||
} else {
|
||||
params.Alerts = append(params.Alerts, Alert{
|
||||
Type: "error",
|
||||
Message: fmt.Sprintf("host %s could not be resolved", host),
|
||||
})
|
||||
delete(h._ipAddresses, host)
|
||||
}
|
||||
|
||||
|
||||
case "add":
|
||||
host := r.URL.Query().Get("host")
|
||||
_, err := h._database.CreateHost(host)
|
||||
if err == nil {
|
||||
params.Alerts = append(params.Alerts, Alert{
|
||||
Type: "success",
|
||||
Message: fmt.Sprintf("created host %s", host),
|
||||
})
|
||||
} else {
|
||||
params.Alerts = append(params.Alerts, Alert{
|
||||
Type: "error",
|
||||
Message: fmt.Sprintf("could not create host %s.\n reason: %s", host, err.Error()),
|
||||
})
|
||||
}
|
||||
break
|
||||
|
||||
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HttpServer) doguisetting(w http.ResponseWriter, r *http.Request) *GuiSetting{
|
||||
settings := new(GuiSetting)
|
||||
settings.FilterString = nil
|
||||
|
||||
if setting := r.URL.Query().Get("setting"); setting != "" {
|
||||
|
||||
switch setting {
|
||||
case "filter":
|
||||
host := r.URL.Query().Get("host")
|
||||
settings.FilterString = &host
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
return settings
|
||||
}
|
||||
|
||||
|
||||
func (h *HttpServer) adminPage(w http.ResponseWriter, r *http.Request) {
|
||||
token, ok := h._oauth.checkOAuth(w, r, true)
|
||||
if !ok { return }
|
||||
|
||||
params := new(AdminPageParams)
|
||||
params.Alerts = make([]Alert, 0)
|
||||
params.Hosts = make(map[string]string)
|
||||
params.IpAddresses = h._ipAddresses
|
||||
|
||||
|
||||
h.doaction(w,r, params)
|
||||
settings := h.doguisetting(w,r)
|
||||
claims, _ := h._oauth.GetClaims(w, token)
|
||||
|
||||
|
||||
params.Email = claims.Email
|
||||
params.Profile = claims.Profile
|
||||
|
||||
if settings.FilterString != nil {
|
||||
params.Hosts = h._database.GetExistingHosts(*settings.FilterString)
|
||||
params.Alerts = append(
|
||||
params.Alerts,
|
||||
Alert{
|
||||
Type: "info",
|
||||
Message: fmt.Sprintf("returned %d hosts", len(params.Hosts)),
|
||||
})
|
||||
} else {
|
||||
params.Hosts = h._database.GetExistingHosts("")
|
||||
}
|
||||
|
||||
h._renderer.RenderAdminPage(w, params)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
func (h *HttpServer) registerHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if _, ok := h._oauth.checkOAuth(w, r, false); ok {
|
||||
return
|
||||
}
|
||||
|
||||
host := r.URL.Query().Get("host")
|
||||
|
||||
clientip, err := getIP(r)
|
||||
if err != nil { log.Fatal(err) }
|
||||
|
||||
if h._database.IsBannedHost(clientip) {
|
||||
h._database.IncrementBanHost(clientip)
|
||||
log.Error("host ", clientip, " is banned!")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
if h._database.ExistHost(host) {
|
||||
h._database.IncrementBanHost(clientip)
|
||||
w.WriteHeader(http.StatusNotAcceptable)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := h._database.CreateHost(host)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ret := map[string]string {
|
||||
"host": host,
|
||||
"token": token,
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(ret)
|
||||
}
|
||||
|
||||
func (h *HttpServer) updateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
hosts := r.URL.Query()["host"]
|
||||
tokens := r.URL.Query()["token"]
|
||||
myips := r.URL.Query()["myip"]
|
||||
var myip string
|
||||
|
||||
clientip, err := getIP(r)
|
||||
|
||||
if h._database.IsBannedHost(clientip) {
|
||||
h._database.IncrementBanHost(clientip)
|
||||
log.Error("host ", clientip, " is banned!")
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if len(hosts) == 0 {
|
||||
h._database.IncrementBanHost(clientip)
|
||||
w.WriteHeader(http.StatusNotAcceptable)
|
||||
return
|
||||
}
|
||||
|
||||
if len(tokens) == 0 {
|
||||
h._database.IncrementBanHost(clientip)
|
||||
w.WriteHeader(http.StatusNotAcceptable)
|
||||
return
|
||||
}
|
||||
|
||||
if len(myips) == 0 {
|
||||
myip = clientip
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
myip = myips[0]
|
||||
}
|
||||
|
||||
host := hosts[0]
|
||||
token := tokens[0]
|
||||
|
||||
if !h._database.Authorize(host, token) {
|
||||
h._database.IncrementBanHost(clientip)
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("authorization successful.")
|
||||
log.Info("will update host ", host, " ip ", myip)
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *HttpServer) Listen() {
|
||||
h._server.ListenAndServe()
|
||||
}
|
||||
|
||||
func CreateHttpServer(config *Config) *HttpServer {
|
||||
|
||||
var httpserver *HttpServer
|
||||
var err error
|
||||
|
||||
httpserver = new(HttpServer)
|
||||
|
||||
r := mux.NewRouter()
|
||||
|
||||
httpserver._ipAddresses = make(map[string][]string)
|
||||
|
||||
httpserver._renderer, err = CreateRenderer(config)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
httpserver._database, err = CreateDatabase(config)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
httpserver._oauth, err = CreateOAuth2(config)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
httpserver._dnsclient = NewTestInstance()
|
||||
|
||||
httpserver._server = &http.Server{
|
||||
Addr: config.Addr,
|
||||
Handler: r,
|
||||
}
|
||||
|
||||
r.HandleFunc("/register", httpserver.registerHandler)
|
||||
r.HandleFunc("/update", httpserver.updateHandler)
|
||||
r.HandleFunc("/admin", httpserver.adminPage)
|
||||
|
||||
return httpserver
|
||||
}
|
||||
Reference in New Issue
Block a user