website/pkg/controller/block/block.go
Noah Petherbridge 666d3105b7 Privacy Improvements and Notification Fixes
* On user profile pages and gallery: the total photo count for the user
  will only include photos that the viewer can actually see (taking into
  account friendship and private grants), so that users won't harass
  each other to see the additional photos that aren't visible to them.
* On the member directory search: the photo counts will only show public
  photos on their page for now, and may be fewer than the number of
  photos the current user could actually see.
* Blocklist: you can now manually add a user by username to your block
  list. So if somebody blocked you on the site and you want to block
  them back, there is a way to do this.
* Friends: you can now directly unfriend someone from their profile
  page by clicking on the "Friends" button. You get a confirmation
  popup before the remove friend action goes through.
* Bugfix: when viewing a user's gallery, you were able to see their
  Friends-only photos if they granted you their Private photo access,
  even if you were not their friend.
* Bugfix: when uploading a new private photo, instead of notifying
  everybody you granted access to your privates it will only notify
  if they are also on your friend list.
2023-08-14 18:50:34 -07:00

146 lines
3.9 KiB
Go

package block
import (
"fmt"
"net/http"
"strings"
"code.nonshy.com/nonshy/website/pkg/config"
"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"
)
// Blocked list.
func Blocked() http.HandlerFunc {
tmpl := templates.Must("account/block_list.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
currentUser, err := session.CurrentUser(r)
if err != nil {
session.FlashError(w, r, "Unexpected error: could not get currentUser.")
templates.Redirect(w, "/")
return
}
// Get our blocklist.
pager := &models.Pagination{
PerPage: config.PageSizeBlockList,
Sort: "updated_at desc",
}
pager.ParsePage(r)
blocked, err := models.PaginateBlockList(currentUser, pager)
if err != nil {
session.FlashError(w, r, "Couldn't paginate block list: %s", err)
templates.Redirect(w, "/")
return
}
var vars = map[string]interface{}{
"BlockedUsers": blocked,
"Pager": pager,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}
// AddUser to manually add someone to your block list.
func AddUser() http.HandlerFunc {
tmpl := templates.Must("account/block_list_add.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if err := tmpl.Execute(w, r, nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}
// BlockUser controller.
func BlockUser() http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// POST only.
if r.Method != http.MethodPost {
session.FlashError(w, r, "Unacceptable Request Method")
templates.Redirect(w, "/")
return
}
// Form fields
var (
username = strings.ToLower(r.PostFormValue("username"))
unblock = r.PostFormValue("unblock") == "true"
)
// Get the current user.
currentUser, err := session.CurrentUser(r)
if err != nil {
session.FlashError(w, r, "Couldn't get CurrentUser: %s", err)
templates.Redirect(w, "/")
return
}
// Get the target user.
user, err := models.FindUser(username)
if err != nil {
session.FlashError(w, r, "User Not Found")
templates.Redirect(w, "/users/blocklist/add")
return
}
// Unblocking?
if unblock {
if err := models.UnblockUser(currentUser.ID, user.ID); err != nil {
session.FlashError(w, r, "Couldn't unblock this user: %s.", err)
} else {
session.Flash(w, r, "You have removed %s from your block list.", user.Username)
}
templates.Redirect(w, "/users/blocked")
return
}
// Can't block yourself.
if currentUser.ID == user.ID {
session.FlashError(w, r, "You can't block yourself!")
templates.Redirect(w, "/u/"+username)
return
}
// Can't block admins.
if user.IsAdmin {
// For curiosity's sake, log a report.
fb := &models.Feedback{
Intent: "report",
Subject: "A user tried to block an admin",
Message: fmt.Sprintf(
"A user has tried to block an admin user account!\n\n"+
"* Username: %s\n* Tried to block: %s",
currentUser.Username,
user.Username,
),
UserID: currentUser.ID,
TableName: "users",
TableID: currentUser.ID,
}
if err := models.CreateFeedback(fb); err != nil {
log.Error("Could not log feedback for user %s trying to block admin %s: %s", currentUser.Username, user.Username, err)
}
session.FlashError(w, r, "You can not block site administrators.")
templates.Redirect(w, "/u/"+username)
return
}
// Block the target user.
if err := models.AddBlock(currentUser.ID, user.ID); err != nil {
session.FlashError(w, r, "Couldn't block this user: %s.", err)
} else {
session.Flash(w, r, "You have added %s to your block list.", user.Username)
}
templates.Redirect(w, "/users/blocked")
})
}