openvpn-mgt/httpd.go

138 lines
3.0 KiB
Go

package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
_ "git.euclide.org/euclide/openvpn-mgt/statik"
"github.com/rakyll/statik/fs"
)
type jsonInput struct {
Action string `json:"action"`
Params jsonInputParams `json:"params"`
}
type jsonInputParams struct {
Server string `json:"server"`
Session int `json:"session"`
User string `json:"user"`
Pass string `json:"password"`
}
type HttpServer struct {
Port string
ovpn *OpenVpnMgt
}
func parseJsonQuery(r *http.Request) (*jsonInput, error) {
var in jsonInput
body, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
if err = json.Unmarshal(body, &in); err !=
nil {
return nil, err
}
return &in, nil
}
func (h *HttpServer) handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type", "application/javascript")
fmt.Fprintf(w, "\n")
}
func (h *HttpServer) ajaxHandler(w http.ResponseWriter, r *http.Request) {
var err error
var jsonStr []byte
w.Header().Set("Content-type", "application/json")
// add CORS headers
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
w.Header().Set("Access-Control-Allow-Methods", "POST")
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "content-type, accept, origin, user-agent, Accept-Encoding")
// stop here if the method is OPTIONS, to allow CORS to work
if r.Method == "OPTIONS" {
return
}
// stop here if the method is OPTIONS, to allow CORS to work
if r.Method != "POST" {
http.Error(w, "post only", 405)
return
}
req, err := parseJsonQuery(r)
if err != nil {
log.Println(err)
http.Error(w, "Invalid request", 500)
return
}
h.ovpn.Debug(req.Action)
switch req.Action {
case "get-remotes":
jsonStr, err = json.Marshal(h.ovpn)
case "set-remote":
err = h.ovpn.SetRemote(req.Params.Server, req.Params.Session)
jsonStr = []byte("{\"status\": \"ok\"}")
case "auth-user-pass":
err = h.ovpn.AuthUserPass(req.Params.Session, req.Params.User, req.Params.Pass)
jsonStr = []byte("{\"status\": \"ok\"}")
case "get-sessions":
jsonStr, err = json.Marshal(h.ovpn)
case "version":
err, version := h.ovpn.Version()
if err != nil {
break
}
jsonStr, err = json.Marshal(version)
case "stats":
case "restart":
err = h.ovpn.Restart(req.Params.Session)
jsonStr = []byte("{\"status\": \"ok\"}")
case "kill":
err = h.ovpn.Kill(req.Params.Session)
jsonStr = []byte("{\"status\": \"ok\"}")
default:
err = errors.New("Invalid request")
}
if err != nil {
http.Error(w, fmt.Sprintf("Error : %s", err), 500)
return
}
fmt.Fprintf(w, "%s", jsonStr)
return
}
func NewHTTPServer(port, key, cert string, s *OpenVpnMgt) {
h := &HttpServer{
Port: port,
ovpn: s,
}
statikFS, err := fs.New()
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/ajax", h.ajaxHandler)
http.Handle("/", http.FileServer(statikFS))
switch {
case key == "" && cert == "":
log.Fatal(http.ListenAndServeTLS(port, cert, key, nil))
default:
log.Fatal(http.ListenAndServe(port, nil))
}
}