website/pkg/controller/account/inner_circle.go
2023-10-14 11:37:01 -07:00

168 lines
4.5 KiB
Go

package account
import (
"fmt"
"net/http"
"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"
)
// InnerCircle is the landing page for inner circle members only.
func InnerCircle() http.HandlerFunc {
tmpl := templates.Must("account/inner_circle.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
currentUser, err := session.CurrentUser(r)
if err != nil || !currentUser.IsInnerCircle() {
templates.NotFoundPage(w, r)
return
}
var vars = map[string]interface{}{
"InnerCircleMinimumPublicPhotos": config.InnerCircleMinimumPublicPhotos,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}
// InviteCircle is the landing page to invite a user into the circle.
func InviteCircle() http.HandlerFunc {
tmpl := templates.Must("account/invite_circle.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
currentUser, err := session.CurrentUser(r)
if err != nil || !currentUser.IsInnerCircle() {
templates.NotFoundPage(w, r)
return
}
// Invite whom?
username := r.FormValue("to")
user, err := models.FindUser(username)
if err != nil {
templates.NotFoundPage(w, r)
return
}
if currentUser.ID == user.ID && currentUser.InnerCircle {
session.FlashError(w, r, "You are already part of the inner circle.")
templates.Redirect(w, "/inner-circle")
return
}
// Any blocking?
if models.IsBlocking(currentUser.ID, user.ID) && !currentUser.IsAdmin {
session.FlashError(w, r, "You are blocked from inviting this user to the circle.")
templates.Redirect(w, "/inner-circle")
return
}
// POSTing?
if r.Method == http.MethodPost {
var (
confirm = r.FormValue("intent") == "confirm"
)
if !confirm {
templates.Redirect(w, "/u/"+username)
return
}
// Add them!
if err := models.AddToInnerCircle(user); err != nil {
session.FlashError(w, r, "Couldn't add to the inner circle: %s", err)
}
log.Info("InnerCircle: %s adds %s to the inner circle", currentUser.Username, user.Username)
session.Flash(w, r, "%s has been added to the inner circle!", user.Username)
templates.Redirect(w, "/photo/u/"+user.Username)
return
}
var vars = map[string]interface{}{
"User": user,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}
// RemoveCircle is the admin-only page to remove a member from the circle.
func RemoveCircle() http.HandlerFunc {
tmpl := templates.Must("account/remove_circle.html")
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
currentUser, err := session.CurrentUser(r)
if err != nil || !currentUser.IsInnerCircle() {
templates.NotFoundPage(w, r)
return
}
// Remove whom?
username := r.FormValue("to")
user, err := models.FindUser(username)
if err != nil {
templates.NotFoundPage(w, r)
return
}
// POSTing?
if r.Method == http.MethodPost {
var (
confirm = r.FormValue("intent") == "confirm"
)
if !confirm {
templates.Redirect(w, "/u/"+username)
return
}
// Admin (with the correct scope): remove them now.
if currentUser.HasAdminScope(config.ScopeCircleModerator) {
if err := models.RemoveFromInnerCircle(user); err != nil {
session.FlashError(w, r, "Couldn't remove from the inner circle: %s", err)
}
session.Flash(w, r, "%s has been removed from the inner circle!", user.Username)
} else {
// Non-admin user: request removal only.
fb := &models.Feedback{
Intent: "report.circle",
Subject: "Inner Circle Removal Request",
TableName: "users",
TableID: user.ID,
Message: fmt.Sprintf(
"An inner circle member has flagged that **%s** no longer qualifies to be a part of the inner circle and should be removed.",
user.Username,
),
}
if err := models.CreateFeedback(fb); err != nil {
session.FlashError(w, r, "Couldn't create admin notification: %s", err)
} else {
session.Flash(w, r, "A request to remove %s from the inner circle has been sent to the site admin.", user.Username)
}
}
templates.Redirect(w, "/u/"+user.Username)
return
}
var vars = map[string]interface{}{
"User": user,
}
if err := tmpl.Execute(w, r, vars); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
})
}