package forum import ( "fmt" "net/http" "strconv" "strings" "code.nonshy.com/nonshy/website/pkg/config" "code.nonshy.com/nonshy/website/pkg/models" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/templates" ) // AddEdit page. func AddEdit() http.HandlerFunc { tmpl := templates.Must("forum/add_edit.html") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Are we editing a forum or creating a new one? var editID uint64 if editStr := r.FormValue("id"); editStr != "" { if i, err := strconv.Atoi(editStr); err == nil { editID = uint64(i) } else { session.FlashError(w, r, "Edit parameter: id was not an integer") templates.Redirect(w, "/forum/admin") return } } // Get the current user. currentUser, err := session.CurrentUser(r) if err != nil { session.FlashError(w, r, "Couldn't get current user: %s", err) templates.Redirect(w, "/") return } // If editing, look up the existing forum. var forum *models.Forum if editID > 0 { if found, err := models.GetForum(editID); err != nil { session.FlashError(w, r, "Couldn't get forum: %s", err) templates.Redirect(w, "/forum/admin") return } else { // Do we have permission? if found.OwnerID != currentUser.ID && !currentUser.IsAdmin { templates.ForbiddenPage(w, r) return } forum = found } } // Saving? if r.Method == http.MethodPost { var ( title = strings.TrimSpace(r.PostFormValue("title")) fragment = strings.TrimSpace(strings.ToLower(r.PostFormValue("fragment"))) description = strings.TrimSpace(r.PostFormValue("description")) category = strings.TrimSpace(r.PostFormValue("category")) isExplicit = r.PostFormValue("explicit") == "true" isPrivileged = r.PostFormValue("privileged") == "true" isPermitPhotos = r.PostFormValue("permit_photos") == "true" isInnerCircle = r.PostFormValue("inner_circle") == "true" ) // Sanity check admin-only settings. if !currentUser.IsAdmin { isPrivileged = false isPermitPhotos = false } // Were we editing an existing forum? if forum != nil { diffs := []models.FieldDiff{ models.NewFieldDiff("Title", forum.Title, title), models.NewFieldDiff("Description", forum.Description, description), models.NewFieldDiff("Category", forum.Category, category), models.NewFieldDiff("Explicit", forum.Explicit, isExplicit), models.NewFieldDiff("Privileged", forum.Privileged, isPrivileged), models.NewFieldDiff("PermitPhotos", forum.PermitPhotos, isPermitPhotos), models.NewFieldDiff("InnerCircle", forum.InnerCircle, isInnerCircle), } forum.Title = title forum.Description = description forum.Category = category forum.Explicit = isExplicit forum.Privileged = isPrivileged forum.PermitPhotos = isPermitPhotos forum.InnerCircle = isInnerCircle // Save it. if err := forum.Save(); err == nil { session.Flash(w, r, "Forum has been updated!") templates.Redirect(w, "/forum/admin") // Log the change. models.LogUpdated(currentUser, nil, "forums", forum.ID, "Updated the forum's settings.", diffs) return } else { session.FlashError(w, r, "Error saving the forum: %s", err) } } else { // Validate the fragment. Front-end enforces the pattern so this // is just a sanity check. if m := FragmentRegexp.FindStringSubmatch(fragment); m == nil { session.FlashError(w, r, "The fragment format is invalid.") templates.Redirect(w, "/forum/admin") return } // Ensure the fragment is unique. if _, err := models.ForumByFragment(fragment); err == nil { session.FlashError(w, r, "The forum fragment is already in use.") } else { // Create the forum. forum = &models.Forum{ Owner: *currentUser, Category: category, Fragment: fragment, Title: title, Description: description, Explicit: isExplicit, Privileged: isPrivileged, PermitPhotos: isPermitPhotos, InnerCircle: isInnerCircle, } if err := models.CreateForum(forum); err == nil { session.Flash(w, r, "The forum has been created!") templates.Redirect(w, "/forum/admin") // Log the change. models.LogCreated(currentUser, "forums", forum.ID, fmt.Sprintf( "Created a new forum.\n\n"+ "* Category: %s\n"+ "* Title: %s\n"+ "* Fragment: %s\n"+ "* Description: %s\n"+ "* Explicit: %v\n"+ "* Privileged: %v\n"+ "* Photos: %v\n"+ "* Inner Circle: %v", forum.Category, forum.Title, forum.Fragment, forum.Description, forum.Explicit, forum.Privileged, forum.PermitPhotos, forum.InnerCircle, )) return } else { session.FlashError(w, r, "Error creating the forum: %s", err) } } } } _ = editID var vars = map[string]interface{}{ "EditID": editID, "EditForum": forum, "Categories": config.ForumCategories, } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) }