package forum import ( "fmt" "net/http" "strconv" "code.nonshy.com/nonshy/website/pkg/log" "code.nonshy.com/nonshy/website/pkg/models" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/templates" ) // ManageModerators controller (/forum/admin/moderators) to appoint moderators to your (user) forum. func ManageModerators() http.HandlerFunc { // Reuse the upload page but with an EditPhoto variable. tmpl := templates.Must("forum/moderators.html") return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ( intent = r.FormValue("intent") stringID = r.FormValue("forum_id") ) // Parse forum_id query parameter. var forumID uint64 if stringID != "" { if i, err := strconv.Atoi(stringID); err == nil { forumID = uint64(i) } else { session.FlashError(w, r, "Edit parameter: forum_id was not an integer") templates.Redirect(w, "/forum/admin") return } } // Redirect URLs var ( next = fmt.Sprintf("%s?forum_id=%d", r.URL.Path, forumID) nextFinished = fmt.Sprintf("/forum/admin/edit?id=%d", forumID) ) // Load the current user. currentUser, err := session.CurrentUser(r) if err != nil { session.FlashError(w, r, "Unexpected error: could not get currentUser.") templates.Redirect(w, "/") return } // Are we adding/removing a user as moderator? var ( username = r.FormValue("to") user *models.User ) if username != "" { if found, err := models.FindUser(username); err != nil { templates.NotFoundPage(w, r) return } else { user = found } } // Look up the forum by its fragment. forum, err := models.GetForum(forumID) if err != nil { templates.NotFoundPage(w, r) return } // User must be the owner of this forum, or a privileged admin. if !forum.CanEdit(currentUser) { templates.ForbiddenPage(w, r) return } // The forum owner can not add themself. if user != nil && forum.OwnerID == user.ID { session.FlashError(w, r, "You can not add the forum owner to its moderators list.") templates.Redirect(w, next) return } // POSTing? if r.Method == http.MethodPost { switch intent { case "submit": // Confirmed adding a moderator. if _, err := forum.AddModerator(user); err != nil { session.FlashError(w, r, "Error adding the moderator: %s", err) templates.Redirect(w, next) return } // Create a notification for this. notif := &models.Notification{ UserID: user.ID, AboutUser: *currentUser, Type: models.NotificationForumModerator, TableName: "forums", TableID: forum.ID, Link: fmt.Sprintf("/f/%s", forum.Fragment), } if err := models.CreateNotification(notif); err != nil { log.Error("Couldn't create PrivatePhoto notification: %s", err) } session.Flash(w, r, "%s has been added to the moderators list!", user.Username) templates.Redirect(w, nextFinished) return case "confirm-remove": // Confirm removing a moderator. if _, err := forum.RemoveModerator(user); err != nil { session.FlashError(w, r, "Error removing the moderator: %s", err) templates.Redirect(w, next) return } // Revoke any past notifications they had about being added as moderator. if err := models.RemoveSpecificNotification(user.ID, models.NotificationForumModerator, "forums", forum.ID); err != nil { log.Error("Couldn't revoke the forum moderator notification: %s", err) } session.Flash(w, r, "%s has been removed from the moderators list.", user.Username) templates.Redirect(w, nextFinished) return } } var vars = map[string]interface{}{ "Forum": forum, "User": user, "IsRemoving": intent == "remove", } if err := tmpl.Execute(w, r, vars); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } }) }