website/pkg/controller/account/search.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

110 lines
2.5 KiB
Go

package account
import (
"net/http"
"strconv"
"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"
)
// Search controller.
func Search() http.HandlerFunc {
tmpl := templates.Must("account/search.html")
// Whitelist for ordering options.
var sortWhitelist = []string{
"last_login_at desc",
"created_at desc",
"username",
"lower(name)",
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Search filters.
var (
isCertified = r.FormValue("certified")
username = r.FormValue("username") // email or username
gender = r.FormValue("gender")
orientation = r.FormValue("orientation")
maritalStatus = r.FormValue("marital_status")
sort = r.FormValue("sort")
sortOK bool
ageMin int
ageMax int
)
ageMin, _ = strconv.Atoi(r.FormValue("age_min"))
ageMax, _ = strconv.Atoi(r.FormValue("age_max"))
if ageMin > ageMax {
ageMin, ageMax = ageMax, ageMin
}
// Get current user.
currentUser, err := session.CurrentUser(r)
if err != nil {
session.FlashError(w, r, "Couldn't get current user!")
templates.Redirect(w, "/")
return
}
// Sort options.
for _, v := range sortWhitelist {
if sort == v {
sortOK = true
break
}
}
if !sortOK {
sort = "last_login_at desc"
}
// Default
if isCertified == "" {
isCertified = "true"
}
pager := &models.Pagination{
PerPage: config.PageSizeMemberSearch,
Sort: sort,
}
pager.ParsePage(r)
users, err := models.SearchUsers(currentUser.ID, &models.UserSearch{
EmailOrUsername: username,
Gender: gender,
Orientation: orientation,
MaritalStatus: maritalStatus,
Certified: isCertified == "true",
AgeMin: ageMin,
AgeMax: ageMax,
}, pager)
if err != nil {
session.FlashError(w, r, "Couldn't search users: %s", err)
}
var vars = map[string]interface{}{
"Users": users,
"Pager": pager,
"Enum": config.ProfileEnums,
// Search filter values.
"Certified": isCertified,
"Gender": gender,
"Orientation": orientation,
"MaritalStatus": maritalStatus,
"EmailOrUsername": username,
"AgeMin": ageMin,
"AgeMax": ageMax,
"Sort": sort,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}