1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-04 22:36:23 -07:00
gochan/pkg/manage/actions.go

111 lines
3.6 KiB
Go

package manage
import (
"net/http"
"path"
"github.com/gochan-org/gochan/pkg/config"
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/gochan-org/gochan/pkg/server"
"github.com/rs/zerolog"
"github.com/uptrace/bunrouter"
)
const (
// NoPerms allows anyone to access this Action
NoPerms = iota
// JanitorPerms allows anyone with at least a janitor-level account to access this Action
JanitorPerms
// ModPerms allows anyone with at least a moderator-level account to access this Action
ModPerms
// AdminPerms allows only the site administrator to view this Action
AdminPerms
)
const (
// NoJSON actions will return an error if JSON is requested by the user
NoJSON = iota
// OptionalJSON actions have an optional JSON output if requested
OptionalJSON
// AlwaysJSON actions always return JSON whether or not it is requested
AlwaysJSON
)
type CallbackFunction func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv *zerolog.Event, errEv *zerolog.Event) (output any, err error)
// Action represents the functions accessed by staff members at /manage/<functionname>.
type Action struct {
// the string used when the user requests /manage/<ID>
ID string `json:"id"`
// The text shown in the staff menu and the window title
Title string `json:"title"`
// Permissions represent who can access the page. 0 for anyone,
// 1 requires the user to have a janitor, mod, or admin account. 2 requires mod or admin,
// and 3 is only accessible by admins
Permissions int `json:"perms"`
// JSONoutput sets what the action can output. If it is 0, it will throw an error if
// JSON is requested. If it is 1, it can output JSON if requested, and if 2, it always
// outputs JSON whether it is requested or not
JSONoutput int `json:"jsonOutput"` // if it can sometimes return JSON, this should still be false
// Callback executes the staff page. if wantsJSON is true, it should return an object
// to be marshalled into JSON. Otherwise, a string assumed to be valid HTML is returned.
//
// IMPORTANT: the writer parameter should only be written to if absolutely necessary (for example,
// if a redirect wouldn't work in handler.go) and even then, it should be done sparingly
Callback CallbackFunction `json:"-"`
}
var actions []Action
func RegisterManagePage(id string, title string, permissions int, jsonOutput int, callback CallbackFunction) {
action := Action{
ID: id,
Title: title,
Permissions: permissions,
JSONoutput: jsonOutput,
Callback: callback,
}
actions = append(actions, action)
server.GetRouter().WithGroup(config.WebPath("/manage"), func(g *bunrouter.Group) {
groupPath := bunrouter.CleanPath(path.Join("/", id))
g.GET(groupPath, setupManageFunction(&action))
g.POST(groupPath, setupManageFunction(&action))
})
}
func getAvailableActions(rank int, noJSON bool) []Action {
var available []Action
for _, action := range actions {
if (rank < action.Permissions || action.Permissions == NoPerms) ||
(noJSON && action.JSONoutput == AlwaysJSON) {
continue
}
available = append(available, action)
}
return available
}
func getPageTitle(actionID string, staff *gcsql.Staff) string {
notLoggedIn := staff == nil || staff.Rank == 0
var useAction Action
for _, action := range actions {
if action.ID == actionID {
useAction = action
break
}
}
if notLoggedIn && useAction.Permissions > NoPerms {
return loginTitle
}
return useAction.Title
}
func getStaffActions(_ http.ResponseWriter, _ *http.Request, staff *gcsql.Staff, _ bool, _ *zerolog.Event, _ *zerolog.Event) (any, error) {
availableActions := getAvailableActions(staff.Rank, false)
return availableActions, nil
}