mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-09-04 10:06:24 -07:00
Simplify controling the JSON-compatible output for manage pages
Rather than having to check whether the user is requesting JSON output in each action, it is done automatically
This commit is contained in:
parent
16b9b4a92f
commit
352cb0227f
3 changed files with 48 additions and 35 deletions
|
@ -34,15 +34,30 @@ const (
|
|||
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
|
||||
)
|
||||
|
||||
var (
|
||||
chopPortNumRegex = regexp.MustCompile(`(.+|\w+):(\d+)$`)
|
||||
)
|
||||
|
||||
// Action represents the functions accessed by staff members at /manage?action=<functionname>.
|
||||
type Action struct {
|
||||
Title string `json:"title"`
|
||||
Permissions int `json:"perms"` // 0 = non-staff, 1 => janitor, 2 => moderator, 3 => administrator
|
||||
isJSON bool // if it can sometimes return JSON, this should still be false
|
||||
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 returns an object to be marshalled
|
||||
// into JSON. Otherwise, a string assumed to be valid HTML is returned.
|
||||
Callback func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) `json:"-"`
|
||||
|
@ -53,6 +68,7 @@ var actions = map[string]Action{
|
|||
Title: "Cleanup",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
// TODO: make a proper JSON output for this, possibly /manage?action=cleanup&json=1&confirmed=1
|
||||
outputStr := `<h2 class="manage-header">Cleanup</h2><br />`
|
||||
if request.FormValue("run") == "Run Cleanup" {
|
||||
outputStr += "Removing deleted posts from the database.<hr />"
|
||||
|
@ -294,11 +310,7 @@ var actions = map[string]Action{
|
|||
"dashboard": {
|
||||
Title: "Dashboard",
|
||||
Permissions: JanitorPerms,
|
||||
isJSON: false,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
if wantsJSON {
|
||||
return "", createNoJSONError("dashboard")
|
||||
}
|
||||
dashBuffer := bytes.NewBufferString("")
|
||||
|
||||
if err = serverutil.MinifyTemplate(gctemplates.ManageDashboard,
|
||||
|
@ -313,10 +325,6 @@ var actions = map[string]Action{
|
|||
Title: "Login",
|
||||
Permissions: NoPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
if wantsJSON {
|
||||
return "", createNoJSONError("dashboard")
|
||||
}
|
||||
|
||||
systemCritical := config.GetSystemCriticalConfig()
|
||||
if GetStaffRank(request) > 0 {
|
||||
http.Redirect(writer, request, path.Join(systemCritical.WebRoot, "manage"), http.StatusFound)
|
||||
|
@ -467,7 +475,7 @@ var actions = map[string]Action{
|
|||
}},
|
||||
"staffinfo": {
|
||||
Permissions: NoPerms,
|
||||
isJSON: true,
|
||||
JSONoutput: AlwaysJSON,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
staff, err := getCurrentFullStaff(request)
|
||||
return staff, err
|
||||
|
@ -653,11 +661,6 @@ var actions = map[string]Action{
|
|||
gcsql.ResetBoardSectionArrays()
|
||||
return
|
||||
}},
|
||||
"actions": {
|
||||
Title: "Staff actions",
|
||||
Permissions: JanitorPerms,
|
||||
isJSON: true,
|
||||
},
|
||||
"rebuildfront": {
|
||||
Title: "Rebuild front page",
|
||||
Permissions: AdminPerms,
|
||||
|
@ -670,6 +673,7 @@ var actions = map[string]Action{
|
|||
"rebuildall": {
|
||||
Title: "Rebuild everything",
|
||||
Permissions: AdminPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
gctemplates.InitTemplates()
|
||||
gcsql.ResetBoardSectionArrays()
|
||||
|
@ -728,7 +732,6 @@ var actions = map[string]Action{
|
|||
"rebuildboard": {
|
||||
Title: "Rebuild board",
|
||||
Permissions: AdminPerms,
|
||||
isJSON: true,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
return "Not implemented (yet)", gcutil.ErrNotImplemented
|
||||
// if err = gctemplates.InitTemplates(); err != nil {
|
||||
|
@ -749,6 +752,7 @@ var actions = map[string]Action{
|
|||
"rebuildboards": {
|
||||
Title: "Rebuild boards",
|
||||
Permissions: AdminPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
if err = gctemplates.InitTemplates(); err != nil {
|
||||
return "", err
|
||||
|
@ -799,6 +803,7 @@ var actions = map[string]Action{
|
|||
"recentposts": {
|
||||
Title: "Recent posts",
|
||||
Permissions: JanitorPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
var outputStr string
|
||||
systemCritical := config.GetSystemCriticalConfig()
|
||||
|
@ -844,7 +849,6 @@ var actions = map[string]Action{
|
|||
"postinfo": {
|
||||
Title: "Post info",
|
||||
Permissions: ModPerms,
|
||||
isJSON: true,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
var post gcsql.Post
|
||||
post, err = gcsql.GetSpecificPost(gcutil.HackyStringToInt(request.FormValue("postid")), false)
|
||||
|
@ -858,6 +862,7 @@ var actions = map[string]Action{
|
|||
"staff": {
|
||||
Title: "Staff",
|
||||
Permissions: AdminPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
var outputStr string
|
||||
do := request.FormValue("do")
|
||||
|
|
|
@ -12,14 +12,6 @@ import (
|
|||
"github.com/gochan-org/gochan/pkg/serverutil"
|
||||
)
|
||||
|
||||
func createNoJSONError(action string) *ErrStaffAction {
|
||||
return &ErrStaffAction{
|
||||
ErrorField: "nojson",
|
||||
Action: action,
|
||||
Message: "Requested mod page does not have a JSON output option",
|
||||
}
|
||||
}
|
||||
|
||||
type ErrStaffAction struct {
|
||||
// ErrorField can be used in the frontend for giving more specific info about the error
|
||||
ErrorField string `json:"error"`
|
||||
|
@ -83,10 +75,6 @@ func CallManageFunction(writer http.ResponseWriter, request *http.Request) {
|
|||
}
|
||||
return
|
||||
}
|
||||
if action == "actions" {
|
||||
handler.Callback = getStaffActions
|
||||
wantsJSON = true
|
||||
}
|
||||
if staffRank == NoPerms && handler.Permissions > NoPerms {
|
||||
handler = actions["login"]
|
||||
} else if staffRank < handler.Permissions {
|
||||
|
@ -97,20 +85,30 @@ func CallManageFunction(writer http.ResponseWriter, request *http.Request) {
|
|||
"Rejected request to manage page %s from %s (insufficient permissions)",
|
||||
action, staffName)
|
||||
|
||||
serveError(writer, "permission", action, "You do not have permission to access this page", handler.isJSON || wantsJSON)
|
||||
serveError(writer, "permission", action, "You do not have permission to access this page", wantsJSON || (handler.JSONoutput > NoJSON))
|
||||
return
|
||||
}
|
||||
|
||||
output, err := handler.Callback(writer, request, isRequestingJSON(request))
|
||||
var output interface{}
|
||||
if wantsJSON && handler.JSONoutput == NoJSON {
|
||||
output = nil
|
||||
err = &ErrStaffAction{
|
||||
ErrorField: "nojson",
|
||||
Action: action,
|
||||
Message: "Requested mod page does not have a JSON output option",
|
||||
}
|
||||
} else {
|
||||
output, err = handler.Callback(writer, request, wantsJSON)
|
||||
}
|
||||
if err != nil {
|
||||
staffName, _ := getCurrentStaff(request)
|
||||
// writer.WriteHeader(500)
|
||||
gclog.Printf(gclog.LStaffLog|gclog.LErrorLog,
|
||||
"Error accessing manage page %s by %s: %s", action, staffName, err.Error())
|
||||
serveError(writer, "actionerror", action, err.Error(), wantsJSON || handler.isJSON)
|
||||
serveError(writer, "actionerror", action, err.Error(), wantsJSON || (handler.JSONoutput > NoJSON))
|
||||
return
|
||||
}
|
||||
if handler.isJSON || wantsJSON {
|
||||
if handler.JSONoutput == AlwaysJSON || wantsJSON {
|
||||
writer.Header().Add("Content-Type", "application/json")
|
||||
writer.Header().Add("Cache-Control", "max-age=5, must-revalidate")
|
||||
outputJSON, err := gcutil.MarshalJSON(output, true)
|
||||
|
|
|
@ -93,9 +93,19 @@ func GetStaffRank(request *http.Request) int {
|
|||
return staff.Rank
|
||||
}
|
||||
|
||||
func init() {
|
||||
actions["actions"] = Action{
|
||||
Title: "Staff actions",
|
||||
Permissions: JanitorPerms,
|
||||
JSONoutput: AlwaysJSON,
|
||||
Callback: getStaffActions,
|
||||
}
|
||||
}
|
||||
|
||||
func getStaffActions(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (interface{}, error) {
|
||||
rank := GetStaffRank(request)
|
||||
actionMap := map[string]Action{}
|
||||
|
||||
for id, action := range actions {
|
||||
if rank < action.Permissions || action.Permissions == NoPerms {
|
||||
continue
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue