pronounss/backend/routes/v2/admin/user_action.go

79 lines
2.6 KiB
Go

package admin
import (
"net/http"
"codeberg.org/pronounscc/pronouns.cc/backend/server"
"github.com/aarondl/opt/omit"
"github.com/go-chi/render"
"github.com/google/uuid"
)
const MaxReasonLength = 2048
type UserActionRequest struct {
Type string `json:"type"` // `ignore`, `warn`, `suspend`
ReportID omit.Val[int64] `json:"report_id"` // The report ID associated with this action, only required if type is ignore. Will close this report.
Reason string `json:"reason"` // The reason for the action. Always logged for moderators, only shown to user for `warn` and `suspend`
Clear struct { // Profile fields to clear
DisplayName bool `json:"display_name"`
Bio bool `json:"bio"`
Links bool `json:"links"`
Names []int `json:"names"` // Indexes of names to clear
Pronouns []int `json:"pronouns"` // Indexes of pronouns to clear
Fields []int `json:"fields"` // Indexes of fields to clear
CustomPreferences []uuid.UUID `json:"custom_preferences"` // Custom preference IDs to clear
// TODO: remove flags, maybe?
} `json:"clear"`
}
const (
ActionTypeIgnore = "ignore"
ActionTypeWarn = "warn"
ActionTypeSuspend = "suspend"
)
func (req UserActionRequest) Validate() (errs []server.ModelParseError) {
switch req.Type {
case ActionTypeIgnore, ActionTypeWarn, ActionTypeSuspend:
default:
errs = append(errs,
server.NewModelParseErrorWithValues("type", "", []any{ActionTypeIgnore, ActionTypeSuspend, ActionTypeWarn}, req.Type))
}
if req.Type != ActionTypeIgnore && req.Reason == "" {
errs = append(errs, server.NewModelParseError("reason", "reason cannot be empty if type is not ignore"))
}
if req.Type == ActionTypeIgnore && req.ReportID.IsUnset() {
errs = append(errs, server.NewModelParseError("report_id", "report_id cannot be empty if type is ignore"))
}
if req.Type == ActionTypeIgnore &&
(req.Clear.DisplayName || req.Clear.Bio || req.Clear.Links ||
len(req.Clear.Names) != 0 || len(req.Clear.Pronouns) != 0 ||
len(req.Clear.Fields) != 0 || len(req.Clear.CustomPreferences) != 0) {
errs = append(errs, server.NewModelParseError("clear", "clear cannot be set if report is being ignored"))
}
return errs
}
func (s *Server) UserAction(w http.ResponseWriter, r *http.Request) (err error) {
ctx := r.Context()
claims, _ := server.ClaimsFromContext(ctx)
req, err := server.Decode[UserActionRequest](r)
if err != nil {
return err
}
// validate input
if errs := req.Validate(); len(errs) != 0 {
return server.NewV2Error(server.ErrBadRequest, "", errs...)
}
render.JSON(w, r, claims)
return nil
}