Initial commit
This commit is contained in:
commit
c578b91c2d
46 files changed
+3241
No files matched your search
@@ -0,0 +1,164 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"uPortal/internal/auth"
|
||||
"uPortal/internal/user"
|
||||
)
|
||||
|
||||
// HandleProfile shows the current user's own profile.
|
||||
func (s *WebService) HandleProfile(w http.ResponseWriter, r *http.Request) {
|
||||
data, ok := s.basicViewData(w, r, "Profile")
|
||||
if !ok {
|
||||
http.Redirect(w, r, "/signin", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
full, err := s.users.GetUserById(r.Context(), data.User.Id)
|
||||
if err != nil {
|
||||
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
data.User = full
|
||||
|
||||
s.render(w, r, "profile/view.html", data)
|
||||
}
|
||||
|
||||
// HandleProfileEdit renders the edit form on GET and applies changes on POST.
|
||||
func (s *WebService) HandleProfileEdit(w http.ResponseWriter, r *http.Request) {
|
||||
data, ok := s.basicViewData(w, r, "Edit Profile")
|
||||
if !ok {
|
||||
http.Redirect(w, r, "/signin", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
s.render(w, r, "profile/edit.html", data)
|
||||
|
||||
case http.MethodPost:
|
||||
if err := r.ParseMultipartForm(32 << 20); err != nil {
|
||||
data.Error = "Could not parse form"
|
||||
s.render(w, r, "profile/edit.html", data)
|
||||
return
|
||||
}
|
||||
if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil {
|
||||
data.Error = "Invalid form, please try again"
|
||||
s.render(w, r, "profile/edit.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
// Display name: UpdateUser writes the displayname column via the user row.
|
||||
displayName := r.FormValue("display_name")
|
||||
if displayName != "" {
|
||||
data.User.DisplayName = &displayName
|
||||
if err := s.users.UpdateUser(r.Context(), data.User); err != nil {
|
||||
data.Error = "Could not save display name"
|
||||
s.render(w, r, "profile/edit.html", data)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Avatar: upload a JPG/PNG <= 256x256 (validated by the user package).
|
||||
if _, _, err := r.FormFile("avatar"); err == nil {
|
||||
bytes, _, err := user.ExtractUploadedImageBytes(r, "avatar")
|
||||
if err != nil {
|
||||
data.Error = "Invalid avatar image: " + err.Error()
|
||||
s.render(w, r, "profile/edit.html", data)
|
||||
return
|
||||
}
|
||||
if err := s.users.CreateAvatar(r.Context(), data.User.Id, bytes); err != nil {
|
||||
data.Error = "Could not save avatar"
|
||||
s.render(w, r, "profile/edit.html", data)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/profile", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleProfilePassword renders the password change form on GET and
|
||||
// applies the new password on POST.
|
||||
func (s *WebService) HandleProfilePassword(w http.ResponseWriter, r *http.Request) {
|
||||
data, ok := s.basicViewData(w, r, "Change Password")
|
||||
if !ok {
|
||||
http.Redirect(w, r, "/signin", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
|
||||
case http.MethodPost:
|
||||
if err := r.ParseForm(); err != nil {
|
||||
data.Error = "Could not parse form"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
if err := auth.ValidateCsrf(r, CsrfCookieName, CsrfFieldName); err != nil {
|
||||
data.Error = "Invalid form token"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
oldPassword := r.FormValue("old_password")
|
||||
newPassword := r.FormValue("new_password")
|
||||
confirmPassword := r.FormValue("confirm_password")
|
||||
|
||||
if !auth.CheckPasswordHash(oldPassword, data.User.Password) {
|
||||
data.Error = "Current password is incorrect"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
if len(newPassword) < 6 {
|
||||
data.Error = "New password must be at least 6 characters"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
if newPassword != confirmPassword {
|
||||
data.Error = "New passwords do not match"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := auth.HashPassword(newPassword)
|
||||
if err != nil {
|
||||
data.Error = "Could not hash password"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
data.User.Password = hashedPassword
|
||||
if err := s.users.UpdateUser(r.Context(), data.User); err != nil {
|
||||
data.Error = "Could not update password"
|
||||
s.render(w, r, "profile/password.html", data)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/profile", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleAvatar serves a stored avatar image by user id.
|
||||
func (s *WebService) HandleAvatar(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64)
|
||||
if err != nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := s.users.GetAvatar(r.Context(), id)
|
||||
if err != nil || len(data) == 0 {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", http.DetectContentType(data))
|
||||
w.Write(data)
|
||||
}
|
||||
Reference in new issue
Block a user