171 lines
3.6 KiB
Go
171 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"html/template"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/gorilla/sessions"
|
|
|
|
"git.deuxfleurs.fr/Deuxfleurs/easybridge/mxlib"
|
|
)
|
|
|
|
const SESSION_NAME = "easybridge_session"
|
|
|
|
var sessionsStore sessions.Store = nil
|
|
|
|
func StartWeb() {
|
|
session_key := make([]byte, 32)
|
|
n, err := rand.Read(session_key)
|
|
if err != nil || n != 32 {
|
|
log.Fatal(err)
|
|
}
|
|
sessionsStore = sessions.NewCookieStore(session_key)
|
|
|
|
r := mux.NewRouter()
|
|
r.HandleFunc("/", handleHome)
|
|
r.HandleFunc("/logout", handleLogout)
|
|
|
|
staticfiles := http.FileServer(http.Dir("static"))
|
|
r.Handle("/static/{file:.*}", http.StripPrefix("/static/", staticfiles))
|
|
|
|
log.Printf("Starting web UI HTTP server on %s", config.WebBindAddr)
|
|
go func() {
|
|
err = http.ListenAndServe(config.WebBindAddr, logRequest(r))
|
|
if err != nil {
|
|
log.Fatal("Cannot start http server: ", err)
|
|
}
|
|
}()
|
|
}
|
|
|
|
func logRequest(handler http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
|
|
handler.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// ----
|
|
|
|
type LoginInfo struct {
|
|
MxId string
|
|
}
|
|
|
|
func checkLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
|
|
var login_info *LoginInfo
|
|
|
|
session, err := sessionsStore.Get(r, SESSION_NAME)
|
|
if err == nil {
|
|
mxid, ok := session.Values["login_mxid"]
|
|
if ok {
|
|
login_info = &LoginInfo{
|
|
MxId: mxid.(string),
|
|
}
|
|
}
|
|
}
|
|
|
|
if login_info == nil {
|
|
login_info = handleLogin(w, r)
|
|
}
|
|
|
|
return login_info
|
|
}
|
|
|
|
// ----
|
|
|
|
type HomeData struct {
|
|
Login *LoginInfo
|
|
Accounts map[string]*Account
|
|
}
|
|
|
|
func handleHome(w http.ResponseWriter, r *http.Request) {
|
|
templateHome := template.Must(template.ParseFiles("templates/layout.html", "templates/home.html"))
|
|
|
|
login := checkLogin(w, r)
|
|
if login == nil {
|
|
return
|
|
}
|
|
|
|
accountsLock.Lock()
|
|
defer accountsLock.Unlock()
|
|
templateHome.Execute(w, &HomeData{
|
|
Login: login,
|
|
Accounts: registeredAccounts[login.MxId],
|
|
})
|
|
}
|
|
|
|
func handleLogout(w http.ResponseWriter, r *http.Request) {
|
|
session, err := sessionsStore.Get(r, SESSION_NAME)
|
|
if err != nil {
|
|
session, _ = sessionsStore.New(r, SESSION_NAME)
|
|
}
|
|
|
|
delete(session.Values, "login_mxid")
|
|
|
|
err = session.Save(r, w)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
http.Redirect(w, r, "/", http.StatusFound)
|
|
}
|
|
|
|
type LoginFormData struct {
|
|
Username string
|
|
WrongPass bool
|
|
ErrorMessage string
|
|
MatrixDomain string
|
|
}
|
|
|
|
func handleLogin(w http.ResponseWriter, r *http.Request) *LoginInfo {
|
|
templateLogin := template.Must(template.ParseFiles("templates/layout.html", "templates/login.html"))
|
|
|
|
data := &LoginFormData{
|
|
MatrixDomain: config.MatrixDomain,
|
|
}
|
|
|
|
if r.Method == "GET" {
|
|
templateLogin.Execute(w, data)
|
|
return nil
|
|
} else if r.Method == "POST" {
|
|
r.ParseForm()
|
|
|
|
username := strings.Join(r.Form["username"], "")
|
|
password := strings.Join(r.Form["password"], "")
|
|
|
|
cli := mxlib.NewClient(config.Server, "")
|
|
mxid, err := cli.PasswordLogin(username, password, "EZBRIDGE", "Easybridge")
|
|
|
|
if err != nil {
|
|
data.Username = username
|
|
data.ErrorMessage = err.Error()
|
|
templateLogin.Execute(w, data)
|
|
return nil
|
|
}
|
|
|
|
// Successfully logged in, save it to session
|
|
session, err := sessionsStore.Get(r, SESSION_NAME)
|
|
if err != nil {
|
|
session, _ = sessionsStore.New(r, SESSION_NAME)
|
|
}
|
|
|
|
session.Values["login_mxid"] = mxid
|
|
|
|
err = session.Save(r, w)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return nil
|
|
}
|
|
|
|
return &LoginInfo{
|
|
MxId: mxid,
|
|
}
|
|
} else {
|
|
http.Error(w, "Unsupported method", http.StatusBadRequest)
|
|
return nil
|
|
}
|
|
}
|