package app import ( "crypto/rand" "encoding/hex" "encoding/json" "net/http" "time" "go.etcd.io/bbolt" "golang.org/x/crypto/bcrypt" ) func (a *App) index(rw http.ResponseWriter, req *http.Request) { s := a.getSession(req) if s == nil { http.Redirect(rw, req, "/login", 302) return } tokens := []string{} prefix := "http://example.com" a.db.View(func(tx *bbolt.Tx) error { b := tx.Bucket([]byte("users")) if b == nil { return nil } uRaw := b.Get([]byte(s.Username)) if uRaw == nil { return nil } u := User{} json.Unmarshal(uRaw, &u) tokens = u.Tokens config := tx.Bucket([]byte("config")) if config != nil { prefix = string(config.Get([]byte("prefix"))) } return nil }) a.ExecuteTemplate(rw, "index.tmpl", struct { Page Page Session *Session UploadTokens []string Prefix string }{ Page: a.getPage(req), Session: s, UploadTokens: tokens, Prefix: prefix, }) } func (a *App) login(rw http.ResponseWriter, req *http.Request) { if req.Method == "POST" { u := a.getUser(req.FormValue("user"), req.FormValue("pass")) if u != nil { session := make([]byte, 32) rand.Read(session) http.SetCookie(rw, &http.Cookie{ Name: "session", Expires: time.Now().Add(time.Hour * 24 * 7), Value: hex.EncodeToString(session), }) s := &Session{ ID: hex.EncodeToString(session), Username: req.FormValue("user"), TempAdmin: u.Auths.Has("tempadmin"), } a.saveSession(s) http.Redirect(rw, req, "/", 302) return } } a.ExecuteTemplate(rw, "login.tmpl", struct { Page Page }{ Page: a.getPage(req), }) } func (a *App) logout(rw http.ResponseWriter, req *http.Request) { s := a.getSession(req) if s != nil { a.deleteSession(s) } http.Redirect(rw, req, "/login", 302) return } func (a *App) generateToken(rw http.ResponseWriter, req *http.Request) { s := a.getSession(req) if s == nil || !s.Auths.Has(AUTH_UPLOAD) { http.Redirect(rw, req, "/", 302) return } tokenRaw := make([]byte, 16) _, err := rand.Read(tokenRaw) if err != nil { rw.WriteHeader(500) return } token := hex.EncodeToString(tokenRaw) a.db.Update(func(tx *bbolt.Tx) error { ub, err := tx.CreateBucketIfNotExists([]byte("users")) if err != nil { return err } uRaw := ub.Get([]byte(s.Username)) if uRaw == nil { return nil } u := User{} err = json.Unmarshal(uRaw, &u) if err != nil { return err } u.Tokens = append(u.Tokens, token) buf, err := json.Marshal(u) if err != nil { return err } err = ub.Put([]byte(s.Username), buf) if err != nil { return err } b, err := tx.CreateBucketIfNotExists([]byte("tokens")) if err != nil { return err } return b.Put([]byte(token), []byte(s.Username)) }) http.Redirect(rw, req, "/", 302) } func (a *App) changePassword(rw http.ResponseWriter, req *http.Request) { s := a.getSession(req) if s == nil { http.Redirect(rw, req, "/", 302) return } if req.Method == "POST" { req.ParseForm() password := req.FormValue("pass") a.db.Update(func(tx *bbolt.Tx) error { users, err := tx.CreateBucketIfNotExists([]byte("users")) if err != nil { return err } u := User{} raw := users.Get([]byte(s.Username)) if raw != nil { json.Unmarshal(raw, &u) } if password != "" { u.Pass, _ = bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) } raw, _ = json.Marshal(u) users.Put([]byte(s.Username), raw) return nil }) http.Redirect(rw, req, "/", 302) } a.ExecuteTemplate(rw, "password.tmpl", struct { Page Page Session *Session }{ Page: a.getPage(req), Session: s, }) }