Author | Jakob Wakeling <[email protected]> |
Date | 2023-09-07 10:53:16 |
Commit | d0994fe1eb5d3b189dd5382da841a23a2d54550e |
Parent | edde49188189df2433f5b5562c2bec5c96bbe736 |
Implement user edit page
Diffstat
M | main.go | | | 1 | + |
M | res/res.go | | | 3 | +++ |
A | res/user/edit.html | | | 34 | ++++++++++++++++++++++++++++++++++ |
M | res/user/header.html | | | 1 | + |
M | src/auth.go | | | 4 | ++-- |
M | src/http.go | | | 1 | + |
M | src/repo.go | | | 4 | ---- |
M | src/repo/edit.go | | | 12 | ++++++------ |
M | src/user.go | | | 11 | +++++++++++ |
A | src/user/edit.go | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/user/user.go | | | 3 | +++ |
11 files changed, 133 insertions, 12 deletions
diff --git a/main.go b/main.go index 153a80b..e292e5b 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ func main() { h.Path("/user/login").Methods("GET", "POST").HandlerFunc(user.HandleLogin) h.Path("/user/logout").Methods("GET", "POST").HandlerFunc(goit.HandleUserLogout) h.Path("/user/sessions").Methods("GET", "POST").HandlerFunc(goit.HandleUserSessions) + h.Path("/user/edit").Methods("GET", "POST").HandlerFunc(user.HandleEdit) h.Path("/repo/create").Methods("GET", "POST").HandlerFunc(repo.HandleCreate) h.Path("/repo/delete").Methods("DELETE").HandlerFunc(repo.HandleDelete) h.Path("/admin").Methods("GET").HandlerFunc(goit.HandleAdminIndex) diff --git a/res/res.go b/res/res.go index e5dfd89..b2dde74 100644 --- a/res/res.go +++ b/res/res.go @@ -40,6 +40,9 @@ var UserLogin string //go:embed user/sessions.html var UserSessions string +//go:embed user/edit.html +var UserEdit string + //go:embed repo/header.html var RepoHeader string diff --git a/res/user/edit.html b/res/user/edit.html new file mode 100644 index 0000000..af2bb1b --- /dev/null +++ b/res/user/edit.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<head lang="en-GB">{{template "base/head" .}}</head> +<body> + <header>{{template "user/header" .}}</header><hr> + <main> + <h1>{{.Title}}</h1><hr> + <form action="/user/edit" method="post"> + <table> + <tr> + <td style="text-align: right;"><label for="username">Username</label></td> + <td><input type="text" name="username" value="{{.Form.Name}}" spellcheck="false"></td> + </tr> + <tr> + <td style="text-align: right;"><label for="fullname">Full Name</label></td> + <td><input type="text" name="fullname" value="{{.Form.FullName}}" spellcheck="false"></td> + </tr> + <tr> + <td></td> + <td> + <input type="submit" value="Update"> + <a href="/" style="color: inherit;">Cancel</a> + </td> + </tr> + <tr> + <td></td> + <td style="color: #AA0000">{{.Message}}</td> + </tr> + </table> + </form> + <table> + <tr><td style="text-align: right;"><span>ID:</span></td><td><span>{{.Form.Id}}</span></td></tr> + </table> + </main> +</body> diff --git a/res/user/header.html b/res/user/header.html index 1b86f45..a984290 100644 --- a/res/user/header.html +++ b/res/user/header.html @@ -9,6 +9,7 @@ <tr> <td> <a href="/user/sessions">Sessions</a> + | <a href="/user/edit">Edit</a> </td> </tr> </table> diff --git a/src/auth.go b/src/auth.go index 4cefd53..d78b2c2 100644 --- a/src/auth.go +++ b/src/auth.go @@ -102,7 +102,7 @@ func EndSessionCookie(w http.ResponseWriter) { http.SetCookie(w, &http.Cookie{Name: "session", Path: "/", MaxAge: -1}) } -func AuthCookie(w http.ResponseWriter, r *http.Request, renew bool) (auth bool, uid int64) { +func AuthCookie(w http.ResponseWriter, r *http.Request, renew bool) (bool, int64) { if uid, s := GetSessionCookie(r); s != (Session{}) { if s.Expiry.After(time.Now()) { if renew && time.Until(s.Expiry) < 24*time.Hour { @@ -125,7 +125,7 @@ func AuthCookie(w http.ResponseWriter, r *http.Request, renew bool) (auth bool, return false, -1 } -func AuthCookieAdmin(w http.ResponseWriter, r *http.Request, renew bool) (auth bool, admin bool, uid int64) { +func AuthCookieAdmin(w http.ResponseWriter, r *http.Request, renew bool) (bool, bool, int64) { if ok, uid := AuthCookie(w, r, renew); ok { if user, err := GetUser(uid); err == nil && user.IsAdmin { return true, true, uid diff --git a/src/http.go b/src/http.go index 8955ca3..ebda9e2 100644 --- a/src/http.go +++ b/src/http.go @@ -28,6 +28,7 @@ func init() { template.Must(Tmpl.New("user/header").Parse(res.UserHeader)) template.Must(Tmpl.New("user/login").Parse(res.UserLogin)) template.Must(Tmpl.New("user/sessions").Parse(res.UserSessions)) + template.Must(Tmpl.New("user/edit").Parse(res.UserEdit)) template.Must(Tmpl.New("repo/header").Parse(res.RepoHeader)) template.Must(Tmpl.New("repo/create").Parse(res.RepoCreate)) diff --git a/src/repo.go b/src/repo.go index 6b2b8dc..2662f42 100644 --- a/src/repo.go +++ b/src/repo.go @@ -141,9 +141,5 @@ func UpdateRepo(rid int64, repo Repo) error { return err } - if _, err := db.Exec(""); err != nil { - return err - } - return nil } diff --git a/src/repo/edit.go b/src/repo/edit.go index 7f49c15..53af807 100644 --- a/src/repo/edit.go +++ b/src/repo/edit.go @@ -91,16 +91,16 @@ func HandleEdit(w http.ResponseWriter, r *http.Request) { data.Form.Description = r.FormValue("description") data.Form.IsPrivate = r.FormValue("visibility") == "private" - if data.Name == "" { + if data.Form.Name == "" { data.Message = "Name cannot be empty" - } else if slices.Contains(reserved, data.Name) { - data.Message = "Name \"" + data.Name + "\" is reserved" - } else if exists, err := goit.RepoExists(data.Name); err != nil { + } else if slices.Contains(reserved, data.Form.Name) { + data.Message = "Name \"" + data.Form.Name + "\" is reserved" + } else if exists, err := goit.RepoExists(data.Form.Name); err != nil { log.Println("[/repo/edit]", err.Error()) goit.HttpError(w, http.StatusInternalServerError) return - } else if exists && data.Name != repo.Name { - data.Message = "Name \"" + data.Name + "\" is taken" + } else if exists && data.Form.Name != repo.Name { + data.Message = "Name \"" + data.Form.Name + "\" is taken" } else if err := goit.UpdateRepo(repo.Id, goit.Repo{ Name: data.Form.Name, Description: data.Form.Description, IsPrivate: data.Form.IsPrivate, }); err != nil { diff --git a/src/user.go b/src/user.go index 9e74553..e7688df 100644 --- a/src/user.go +++ b/src/user.go @@ -104,3 +104,14 @@ func UserExists(name string) (bool, error) { return true, nil } } + +func UpdateUser(uid int64, user User) error { + if _, err := db.Exec( + "UPDATE users SET name = ?, name_full = ? WHERE id = ?", + user.Name, user.FullName, uid, + ); err != nil { + return err + } + + return nil +} diff --git a/src/user/edit.go b/src/user/edit.go new file mode 100644 index 0000000..2c22694 --- /dev/null +++ b/src/user/edit.go @@ -0,0 +1,71 @@ +package user + +import ( + "fmt" + "log" + "net/http" + "slices" + + goit "github.com/Jamozed/Goit/src" +) + +func HandleEdit(w http.ResponseWriter, r *http.Request) { + auth, uid := goit.AuthCookie(w, r, true) + if !auth { + goit.HttpError(w, http.StatusUnauthorized) + return + } + + user, err := goit.GetUser(uid) + if err != nil { + log.Println("[/user/edit]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } else if user == nil { + log.Println("[/user/edit]", uid, "is a nonexistent UID") + goit.HttpError(w, http.StatusInternalServerError) + return + } + + data := struct { + Title, Message string + + Form struct{ Id, Name, FullName string } + }{ + Title: "User - Edit", + } + + data.Form.Id = fmt.Sprint(user.Id) + data.Form.Name = user.Name + data.Form.FullName = user.FullName + + if r.Method == http.MethodPost { + data.Form.Name = r.FormValue("username") + data.Form.FullName = r.FormValue("fullname") + + if data.Form.Name == "" { + data.Message = "Username cannot be empty" + } else if slices.Contains(reserved, data.Form.Name) && uid != 0 { + data.Message = "Username \"" + data.Form.Name + "\" is reserved" + } else if exists, err := goit.UserExists(data.Form.Name); err != nil { + log.Println("[/user/edit]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } else if exists && data.Form.Name != user.Name { + data.Message = "Username \"" + data.Form.Name + "\" is taken" + } else if err := goit.UpdateUser(user.Id, goit.User{ + Name: data.Form.Name, FullName: data.Form.FullName, + }); err != nil { + log.Println("[/user/edit]", err.Error()) + goit.HttpError(w, http.StatusInternalServerError) + return + } else { + http.Redirect(w, r, "/user/edit", http.StatusFound) + return + } + } + + if err := goit.Tmpl.ExecuteTemplate(w, "user/edit", data); err != nil { + log.Println("[/user/edit]", err.Error()) + } +} diff --git a/src/user/user.go b/src/user/user.go new file mode 100644 index 0000000..b41a851 --- /dev/null +++ b/src/user/user.go @@ -0,0 +1,3 @@ +package user + +var reserved []string = []string{"admin", "repo", "static", "user"}