vppn/hub/handlers.go
2024-12-12 21:11:17 +01:00

355 lines
7.8 KiB
Go

package hub
import (
"errors"
"log"
"net/http"
"vppn/hub/api"
"vppn/m"
"git.crumpington.com/lib/go/webutil"
"golang.org/x/crypto/bcrypt"
)
func (a *App) _root(s *api.Session, w http.ResponseWriter, r *http.Request) error {
if s.SignedIn {
return a.redirect(w, r, "/admin/config/")
} else {
return a.redirect(w, r, "/sign-in/")
}
}
func (a *App) _signin(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/sign-in.html", w, struct{ Session *api.Session }{s})
}
func (a *App) _signinSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var pwd string
err := webutil.NewFormScanner(r.Form).
Scan("Password", &pwd).
Error()
if err != nil {
return err
}
if err := a.api.Session_SignIn(s, pwd); err != nil {
return err
}
return a.redirect(w, r, "/")
}
func (a *App) _adminSignOut(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/admin-sign-out.html", w, struct{ Session *api.Session }{s})
}
func (a *App) _adminSignOutSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
if err := a.api.Session_Delete(s.SessionID); err != nil {
log.Printf("Failed to delete session cookie %s: %v", s.SessionID, err)
}
a.deleteCookie(w, SESSION_ID_COOKIE_NAME)
return a.redirect(w, r, "/")
}
func (a *App) _adminConfig(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/admin-config.html", w, struct {
Session *api.Session
Config *api.Config
}{
s,
a.api.Config_Get(),
})
}
func (a *App) _adminConfigEdit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/admin-config-edit.html", w, struct {
Session *api.Session
Config *api.Config
}{
s,
a.api.Config_Get(),
})
}
func (a *App) _adminConfigEditSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var (
conf = a.api.Config_Get()
ipStr string
)
err := webutil.NewFormScanner(r.Form).
Scan("HubAddress", &conf.HubAddress).
Scan("VPNNetwork", &ipStr).
Error()
if err != nil {
return err
}
if conf.VPNNetwork, err = stringToIP(ipStr); err != nil {
return err
}
if err := a.api.Config_Update(conf); err != nil {
return err
}
return a.redirect(w, r, "/admin/config/")
}
func (a *App) _adminPasswordEdit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/admin-password-edit.html", w, struct{ Session *api.Session }{s})
}
func (a *App) _adminPasswordSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var (
conf = a.api.Config_Get()
curPwd string
newPwd string
newPwd2 string
)
err := webutil.NewFormScanner(r.Form).
Scan("CurrentPassword", &curPwd).
Scan("NewPassword", &newPwd).
Scan("NewPassword2", &newPwd2).
Error()
if err != nil {
return err
}
if len(newPwd) < 8 {
return errors.New("password is too short")
}
if newPwd != newPwd2 {
return errors.New("passwords don't match")
}
err = bcrypt.CompareHashAndPassword(conf.Password, []byte(curPwd))
if err != nil {
return err
}
hash, err := bcrypt.GenerateFromPassword([]byte(newPwd), bcrypt.DefaultCost)
if err != nil {
return err
}
if err := a.api.Config_UpdatePassword(hash); err != nil {
return err
}
return a.redirect(w, r, "/admin/config/")
}
func (a *App) _adminPeerList(s *api.Session, w http.ResponseWriter, r *http.Request) error {
peers, err := a.api.Peer_List()
if err != nil {
return err
}
return a.render("/admin-peer-list.html", w, struct {
Session *api.Session
Peers []*api.Peer
}{
s,
peers,
})
}
func (a *App) _adminPeerCreate(s *api.Session, w http.ResponseWriter, r *http.Request) error {
return a.render("/admin-peer-create.html", w, struct{ Session *api.Session }{s})
}
func (a *App) _adminPeerCreateSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var ipStr string
args := api.PeerCreateArgs{}
err := webutil.NewFormScanner(r.Form).
Scan("Name", &args.Name).
Scan("PublicIP", &ipStr).
Scan("Port", &args.Port).
Scan("Mediator", &args.Mediator).
Error()
if err != nil {
return err
}
if args.PublicIP, err = stringToIP(ipStr); err != nil {
return err
}
code := a.api.Peer_CreateIntent(args)
return a.redirect(w, r, "/admin/peer/intent-created/?Code=%s", code)
}
func (a *App) _adminPeerIntentCreated(s *api.Session, w http.ResponseWriter, r *http.Request) error {
code := r.FormValue("Code")
if code == "" {
return errors.New("missing Code")
}
return a.render("/admin-peer-intent.html", w, struct {
Session *api.Session
HubAddress string
Code string
}{s, a.api.Config_Get().HubAddress, code})
}
func (a *App) _adminPeerView(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var peerIP byte
err := webutil.NewFormScanner(r.Form).Scan("PeerIP", &peerIP).Error()
if err != nil {
return err
}
peer, err := a.api.Peer_Get(peerIP)
if err != nil {
return err
}
return a.render("/admin-peer-view.html", w, struct {
Session *api.Session
Peer *api.Peer
}{s, peer})
}
func (a *App) _adminPeerEdit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var peerIP byte
err := webutil.NewFormScanner(r.Form).Scan("PeerIP", &peerIP).Error()
if err != nil {
return err
}
peer, err := a.api.Peer_Get(peerIP)
if err != nil {
return err
}
return a.render("/admin-peer-edit.html", w, struct {
Session *api.Session
Peer *api.Peer
}{s, peer})
}
func (a *App) _adminPeerEditSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var (
peerIP byte
ipStr string
)
err := webutil.NewFormScanner(r.Form).Scan("PeerIP", &peerIP).Error()
if err != nil {
return err
}
peer, err := a.api.Peer_Get(peerIP)
if err != nil {
return err
}
err = webutil.NewFormScanner(r.Form).
Scan("Name", &peer.Name).
Scan("PublicIP", &ipStr).
Scan("Port", &peer.Port).
Scan("Mediator", &peer.Mediator).
Error()
if err != nil {
return err
}
if peer.PublicIP, err = stringToIP(ipStr); err != nil {
return err
}
if err = a.api.Peer_Update(peer); err != nil {
return err
}
return a.redirect(w, r, "/admin/peer/view/?PeerIP=%d", peer.PeerIP)
}
func (a *App) _adminPeerDelete(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var peerIP byte
err := webutil.NewFormScanner(r.Form).Scan("PeerIP", &peerIP).Error()
if err != nil {
return err
}
peer, err := a.api.Peer_Get(peerIP)
if err != nil {
return err
}
return a.render("/admin-peer-delete.html", w, struct {
Session *api.Session
Peer *api.Peer
}{s, peer})
}
func (a *App) _adminPeerDeleteSubmit(s *api.Session, w http.ResponseWriter, r *http.Request) error {
var peerIP byte
err := webutil.NewFormScanner(r.Form).Scan("PeerIP", &peerIP).Error()
if err != nil {
return err
}
if err := a.api.Peer_Delete(peerIP); err != nil {
return err
}
return a.redirect(w, r, "/admin/peer/list/")
}
func (a *App) _peerCreate(w http.ResponseWriter, r *http.Request) error {
code := r.FormValue("Code")
conf, err := a.api.Peer_Create(code)
if err != nil {
return err
}
return a.sendJSON(w, conf)
}
func (a *App) _peerFetchState(w http.ResponseWriter, r *http.Request) error {
_, apiKey, ok := r.BasicAuth()
if !ok {
log.Printf("1")
return api.ErrNotAuthorized
}
peer, err := a.api.Peer_GetByAPIKey(apiKey)
if err != nil {
log.Printf("2")
return err
}
peers, err := a.api.Peer_List()
if err != nil {
log.Printf("3")
return err
}
conf := a.api.Config_Get()
state := m.NetworkState{
HubAddress: conf.HubAddress,
Network: conf.VPNNetwork,
PeerIP: peer.PeerIP,
PublicIP: peer.PublicIP,
Port: peer.Port,
}
for _, p := range peers {
state.Peers[p.PeerIP] = &m.Peer{
PeerIP: p.PeerIP,
Version: p.Version,
Name: p.Name,
PublicIP: p.PublicIP,
Port: p.Port,
Mediator: p.Mediator,
EncPubKey: p.EncPubKey,
SignPubKey: p.SignPubKey,
}
}
return a.sendJSON(w, state)
}