package main import ( "fmt" "github.com/gorilla/csrf" "html/template" "log" "net/http" "strings" ) type views struct { templates map[string]*template.Template } func Views() *views { templates := map[string]*template.Template{ "index": template.Must(template.ParseFiles("templates/layout/base.html", "templates/index.html")), "change_password": template.Must(template.ParseFiles("templates/layout/base.html", "templates/changepw.html")), "change_ssh": template.Must(template.ParseFiles("templates/layout/base.html", "templates/change_ssh.html")), } return &views{templates} } func (v *views) Index() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { if _, ok := req.Context().Value("user").(*User); ok { err := v.templates["index"].ExecuteTemplate(w, "base", NewPageCtx(req)) if err != nil { log.Println("ERROR", err) } } else { // no user fmt.Fprintf(w, "No user found :/") } }) } func (v *views) ChangePassword(what string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { pageCtx := NewPageCtx(req) if req.Method == "GET" { pageCtx["Pwtype"] = what err := v.templates["change_password"].ExecuteTemplate(w, "base", pageCtx) if err != nil { log.Println("ERROR", err) } } else if req.Method == "POST" { // Parse Post err := req.ParseForm() if err != nil { log.Println("ERROR", err) redirectSameFlash(w, req, err.Error(), "error") return } new_password := req.PostFormValue("new_password") new_password_again := req.PostFormValue("new_password_again") if new_password != new_password_again { redirectSameFlash(w, req, "Passwords did not match", "error") return } err = validatePassword(new_password) if err != nil { redirectSameFlash(w, req, err.Error(), "error") return } // check if password is on the bad list if IsPasswordCompromised(new_password) { redirectSameFlash(w, req, "The password specified is considered compromised", "error") return } // check that password is not already in use for other suffix username := pageCtx["User"].(*User).UserName err = CheckDuplicatePw(username, new_password) if err != nil { redirectSameFlash(w, req, err.Error(), "error") return } // save that password err = ChangeKerberosPw(strings.ToUpper(what), username, new_password) if err != nil { redirectSameFlash(w, req, err.Error(), "error") return } redirectSameFlash(w, req, fmt.Sprintf("Password %s successfully updated", what), "success") } }) } type PageCtx map[string]interface{} func NewPageCtx(req *http.Request) PageCtx { flash_msg := req.Context().Value("flash") flash_class := req.Context().Value("flash_class") user, _ := req.Context().Value("user").(*User) return PageCtx{ "Flash": flash_msg, "FlashClass": flash_class, "User": user, "CsrfField": csrf.TemplateField(req), } } func (v *views) ChangeSSHKeys() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { if user, ok := req.Context().Value("user").(*User); ok { if req.Method == "GET" { ssh_keys, err := pwman.LdapInfo.GetSSHKeys(user.UserName) if err != nil { log.Println("ERROR", err) ssh_keys = []SSHPubKey{} } pageCtx := NewPageCtx(req) pageCtx["SSHKeys"] = ssh_keys err = v.templates["change_ssh"].ExecuteTemplate(w, "base", pageCtx) if err != nil { log.Println("ERROR", err) } } else if req.Method == "POST" { err := req.ParseForm() if err != nil { log.Println("ERROR", err) redirectSame(w, req) return } delete_sshkey := req.PostFormValue("sshkey") if req.PostFormValue("delete") != "" && delete_sshkey != "" { log.Println("INFO", "Delete request for", delete_sshkey) err = pwman.LdapInfo.DeleteSSHKey(user.UserName, delete_sshkey) if err != nil { log.Println("ERROR", err) SetFlashMessage(w, err.Error(), "error") } else { SetFlashMessage(w, "Deleted ssh key", "warning") } redirectSame(w, req) return } if req.PostFormValue("add_key") != "" { keys := strings.Split(req.PostFormValue("ssh_keys"), "\n") err = pwman.LdapInfo.AddSSHKey(user.UserName, keys) if err != nil { log.Println("ERROR", err) SetFlashMessage(w, err.Error(), "error") } else { SetFlashMessage(w, "Successfully added ssh key", "success") } redirectSame(w, req) return } log.Println("ERROR", "Bad post view state") redirectSame(w, req) } } }) } func redirectSameFlash(w http.ResponseWriter, req *http.Request, message, flash_class string) { SetFlashMessage(w, message, flash_class) http.Redirect(w, req, req.URL.Path, 302) } func redirectSame(w http.ResponseWriter, req *http.Request) { http.Redirect(w, req, req.URL.Path, 302) }