aboutsummaryrefslogtreecommitdiff
path: root/web.go
diff options
context:
space:
mode:
Diffstat (limited to 'web.go')
-rw-r--r--web.go171
1 files changed, 171 insertions, 0 deletions
diff --git a/web.go b/web.go
new file mode 100644
index 0000000..dafb8b1
--- /dev/null
+++ b/web.go
@@ -0,0 +1,171 @@
+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
+ }
+}