website/pkg/controller/block/block.go
Noah 030fadcf8d Block Lists
Implement block lists. They work like friend lists but are unidirectional,
but take effect in both directions (blocker and blockee can not see one
another on the site -- except admin users can always see all users).

* Profile page says 404
* User gallery says 404
* User search page filters out blocked users
* Compose endpoint blocks sending messages to blocked users (except admin)
* Site Gallery filters photos by blocked (and uncertified) users
* Inbox page hides chat list for blocked users (can still read the chat
  history if you have a link to the old thread)
2022-08-14 17:45:55 -07:00

115 lines
2.9 KiB
Go

package block
import (
"net/http"
"strings"
"git.kirsle.net/apps/gosocial/pkg/config"
"git.kirsle.net/apps/gosocial/pkg/models"
"git.kirsle.net/apps/gosocial/pkg/session"
"git.kirsle.net/apps/gosocial/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.ID, 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
}
})
}
// 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, "/")
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 {
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")
})
}