mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-09-04 10:06:24 -07:00
Turn staff action map into an array for more control over ordering
This commit is contained in:
parent
c4e4b775ba
commit
9fb5ebbd0b
7 changed files with 116 additions and 77 deletions
|
@ -11,10 +11,7 @@ const notAStaff = {
|
|||
Rank: 0
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {StaffActionMap}
|
||||
*/
|
||||
export let staffActions = {};
|
||||
export let staffActions = [];
|
||||
export let staffInfo = notAStaff;
|
||||
|
||||
/**
|
||||
|
@ -95,18 +92,26 @@ export function banSelectedPost() {
|
|||
* A helper function for creating a menu item
|
||||
* @param {StaffAction} action
|
||||
*/
|
||||
function menuItem(action, id = "") {
|
||||
if(id == "") {
|
||||
function menuItem(action, isCategory = false) {
|
||||
if(isCategory) {
|
||||
return $("<div/>").append($("<b/>").text(action));
|
||||
} else {
|
||||
return $("<div/>").append(
|
||||
$("<a/>").prop({
|
||||
href: `${webroot}manage?action=${id}`
|
||||
href: `${webroot}manage?action=${action.id}`
|
||||
}).text(action.title)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getAction(id) {
|
||||
for (const action of staffActions) {
|
||||
if(action.id == id) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {StaffAction} action
|
||||
* @param {number} perms
|
||||
|
@ -130,27 +135,29 @@ export function createStaffMenu(rank = staffInfo.Rank) {
|
|||
id: "staffmenu",
|
||||
class: "dropdown-menu"
|
||||
});
|
||||
let actions = Object.keys(staffActions);
|
||||
let adminActions = actions.filter(val => filterAction(staffActions[val], 3));
|
||||
let modActions = actions.filter(val => filterAction(staffActions[val], 2));
|
||||
let janitorActions = actions.filter(val => filterAction(staffActions[val], 1));
|
||||
let adminActions = staffActions.filter(val => filterAction(val, 3));
|
||||
let modActions = staffActions.filter(val => filterAction(val, 2));
|
||||
let janitorActions = staffActions.filter(val => filterAction(val, 1));
|
||||
|
||||
$staffMenu.append(
|
||||
menuItem(getAction("logout")),
|
||||
menuItem(getAction("dashboard")));
|
||||
|
||||
$staffMenu.append(menuItem(staffActions["logout"], "logout"), menuItem(staffActions["dashboard"], "dashboard"))
|
||||
$staffMenu.append(menuItem("Janitorial"));
|
||||
for(const actionID of janitorActions) {
|
||||
$staffMenu.append(menuItem(staffActions[actionID], actionID));
|
||||
$staffMenu.append(menuItem("Janitorial", true));
|
||||
for(const action of janitorActions) {
|
||||
$staffMenu.append(menuItem(action));
|
||||
}
|
||||
if(rank < 2) return $staffMenu;
|
||||
|
||||
$staffMenu.append(menuItem("Moderation"));
|
||||
for(const actionID of modActions) {
|
||||
$staffMenu.append(menuItem(staffActions[actionID], actionID));
|
||||
$staffMenu.append(menuItem("Moderation", true));
|
||||
for(const action of modActions) {
|
||||
$staffMenu.append(menuItem(action));
|
||||
}
|
||||
if(rank < 3) return $staffMenu;
|
||||
|
||||
$staffMenu.append(menuItem("Administration"));
|
||||
for(const actionID of adminActions) {
|
||||
$staffMenu.append(menuItem(staffActions[actionID], actionID));
|
||||
$staffMenu.append(menuItem("Administration", true));
|
||||
for(const action of adminActions) {
|
||||
$staffMenu.append(menuItem(action));
|
||||
}
|
||||
$staffBtn = new TopBarButton("Staff", () => {
|
||||
let exists = $(document).find($staffMenu).length > 0;
|
||||
|
|
9
frontend/types/gochan.d.ts
vendored
9
frontend/types/gochan.d.ts
vendored
|
@ -132,14 +132,9 @@ interface StaffAction {
|
|||
}
|
||||
|
||||
/**
|
||||
* The result of requestiong /manage?action=actions
|
||||
* The result of requesting /manage?action=actions
|
||||
*/
|
||||
interface StaffActionMap {
|
||||
/**
|
||||
* The "id" of the action. Retreived by requesting /manage?action=<id>
|
||||
*/
|
||||
[id:string]: StaffAction;
|
||||
}
|
||||
declare var staffActions: StaffAction[];
|
||||
|
||||
/**
|
||||
* The menu shown when the Staff button on the top bar is clicked
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -49,22 +49,31 @@ var (
|
|||
|
||||
// Action represents the functions accessed by staff members at /manage?action=<functionname>.
|
||||
type Action struct {
|
||||
// the string used when the user requests /manage?action=<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 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:"-"`
|
||||
}
|
||||
|
||||
var actions = map[string]Action{
|
||||
"cleanup": {
|
||||
// var actions = map[string]Action{
|
||||
var actions = []Action{
|
||||
{
|
||||
ID: "cleanup",
|
||||
Title: "Cleanup",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -95,7 +104,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return outputStr, nil
|
||||
}},
|
||||
"config": {
|
||||
{
|
||||
ID: "config",
|
||||
Title: "Configuration",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -307,7 +317,8 @@ var actions = map[string]Action{
|
|||
errStr := "web-based configuration tool has been temporarily disabled"
|
||||
return errStr, errors.New(errStr)
|
||||
}},
|
||||
"dashboard": {
|
||||
{
|
||||
ID: "dashboard",
|
||||
Title: "Dashboard",
|
||||
Permissions: JanitorPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -321,7 +332,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return dashBuffer.String(), nil
|
||||
}},
|
||||
"login": {
|
||||
{
|
||||
ID: "login",
|
||||
Title: "Login",
|
||||
Permissions: NoPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -350,7 +362,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return
|
||||
}},
|
||||
"logout": {
|
||||
{
|
||||
ID: "logout",
|
||||
Title: "Logout",
|
||||
Permissions: JanitorPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -360,7 +373,8 @@ var actions = map[string]Action{
|
|||
http.SetCookie(writer, cookie)
|
||||
return "Logged out successfully", nil
|
||||
}},
|
||||
"announcements": {
|
||||
{
|
||||
ID: "announcements",
|
||||
Title: "Announcements",
|
||||
Permissions: JanitorPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -384,7 +398,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return outputStr, nil
|
||||
}},
|
||||
"bans": {
|
||||
{
|
||||
ID: "bans",
|
||||
Title: "Bans",
|
||||
Permissions: ModPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) { //TODO whatever this does idk man
|
||||
|
@ -473,14 +488,16 @@ var actions = map[string]Action{
|
|||
outputStr += manageBansBuffer.String()
|
||||
return outputStr, nil
|
||||
}},
|
||||
"staffinfo": {
|
||||
{
|
||||
ID: "staffinfo",
|
||||
Permissions: NoPerms,
|
||||
JSONoutput: AlwaysJSON,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
staff, err := getCurrentFullStaff(request)
|
||||
return staff, err
|
||||
}},
|
||||
"boards": {
|
||||
{
|
||||
ID: "boards",
|
||||
Title: "Boards",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -661,7 +678,8 @@ var actions = map[string]Action{
|
|||
gcsql.ResetBoardSectionArrays()
|
||||
return
|
||||
}},
|
||||
"rebuildfront": {
|
||||
{
|
||||
ID: "rebuildfront",
|
||||
Title: "Rebuild front page",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -670,7 +688,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return "Built front page successfully", building.BuildFrontPage()
|
||||
}},
|
||||
"rebuildall": {
|
||||
{
|
||||
ID: "rebuildall",
|
||||
Title: "Rebuild everything",
|
||||
Permissions: AdminPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
|
@ -729,7 +748,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return buildStr, nil
|
||||
}},
|
||||
"rebuildboard": {
|
||||
{
|
||||
ID: "rebuildboard",
|
||||
Title: "Rebuild board",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -749,7 +769,8 @@ var actions = map[string]Action{
|
|||
// Message: fmt.Sprintf("/%s/ is not a board"),
|
||||
// }
|
||||
}},
|
||||
"rebuildboards": {
|
||||
{
|
||||
ID: "rebuildboards",
|
||||
Title: "Rebuild boards",
|
||||
Permissions: AdminPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
|
@ -765,7 +786,8 @@ var actions = map[string]Action{
|
|||
}
|
||||
return "Boards built successfully", building.BuildBoards(false)
|
||||
}},
|
||||
"reparsehtml": {
|
||||
{
|
||||
ID: "reparsehtml",
|
||||
Title: "Reparse HTML",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -800,7 +822,8 @@ var actions = map[string]Action{
|
|||
outputStr += "Done building boards<hr />"
|
||||
return outputStr, nil
|
||||
}},
|
||||
"recentposts": {
|
||||
{
|
||||
ID: "recentposts",
|
||||
Title: "Recent posts",
|
||||
Permissions: JanitorPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
|
@ -846,7 +869,8 @@ var actions = map[string]Action{
|
|||
outputStr += "</table>"
|
||||
return
|
||||
}},
|
||||
"postinfo": {
|
||||
{
|
||||
ID: "postinfo",
|
||||
Title: "Post info",
|
||||
Permissions: ModPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
@ -859,7 +883,8 @@ var actions = map[string]Action{
|
|||
jsonStr, _ := gcutil.MarshalJSON(post, false)
|
||||
return jsonStr, nil
|
||||
}},
|
||||
"staff": {
|
||||
{
|
||||
ID: "staff",
|
||||
Title: "Staff",
|
||||
Permissions: AdminPerms,
|
||||
JSONoutput: OptionalJSON,
|
||||
|
@ -916,7 +941,8 @@ var actions = map[string]Action{
|
|||
outputStr += staffBuffer.String()
|
||||
return outputStr, nil
|
||||
}},
|
||||
"tempposts": {
|
||||
{
|
||||
ID: "tempposts",
|
||||
Title: "Temporary posts lists",
|
||||
Permissions: AdminPerms,
|
||||
Callback: func(writer http.ResponseWriter, request *http.Request, wantsJSON bool) (output interface{}, err error) {
|
||||
|
|
|
@ -54,66 +54,63 @@ func CallManageFunction(writer http.ResponseWriter, request *http.Request) {
|
|||
return
|
||||
}
|
||||
wantsJSON := isRequestingJSON(request)
|
||||
action := request.FormValue("action")
|
||||
actionID := request.FormValue("action")
|
||||
staffRank := GetStaffRank(request)
|
||||
var managePageBuffer bytes.Buffer
|
||||
|
||||
if action == "" {
|
||||
if actionID == "" {
|
||||
if staffRank == NoPerms {
|
||||
action = "login"
|
||||
actionID = "login"
|
||||
} else {
|
||||
action = "dashboard"
|
||||
actionID = "dashboard"
|
||||
}
|
||||
}
|
||||
|
||||
handler, ok := actions[action]
|
||||
if !ok {
|
||||
var managePageBuffer bytes.Buffer
|
||||
action := getAction(actionID, staffRank)
|
||||
if action == nil {
|
||||
if wantsJSON {
|
||||
serveError(writer, "notfound", action, "action not found", wantsJSON)
|
||||
serveError(writer, "notfound", actionID, "action not found", wantsJSON)
|
||||
} else {
|
||||
serverutil.ServeNotFound(writer, request)
|
||||
}
|
||||
return
|
||||
}
|
||||
if staffRank == NoPerms && handler.Permissions > NoPerms {
|
||||
handler = actions["login"]
|
||||
} else if staffRank < handler.Permissions {
|
||||
|
||||
if staffRank < action.Permissions {
|
||||
writer.WriteHeader(403)
|
||||
staffName, _ := getCurrentStaff(request)
|
||||
|
||||
gclog.Printf(gclog.LStaffLog,
|
||||
"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", wantsJSON || (handler.JSONoutput > NoJSON))
|
||||
actionID, staffName)
|
||||
serveError(writer, "permission", actionID, "You do not have permission to access this page", wantsJSON || (action.JSONoutput > NoJSON))
|
||||
return
|
||||
}
|
||||
|
||||
var output interface{}
|
||||
if wantsJSON && handler.JSONoutput == NoJSON {
|
||||
if wantsJSON && action.JSONoutput == NoJSON {
|
||||
output = nil
|
||||
err = &ErrStaffAction{
|
||||
ErrorField: "nojson",
|
||||
Action: action,
|
||||
Action: actionID,
|
||||
Message: "Requested mod page does not have a JSON output option",
|
||||
}
|
||||
} else {
|
||||
output, err = handler.Callback(writer, request, wantsJSON)
|
||||
output, err = action.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.JSONoutput > NoJSON))
|
||||
"Error accessing manage page %s by %s: %s", actionID, staffName, err.Error())
|
||||
serveError(writer, "actionerror", actionID, err.Error(), wantsJSON || (action.JSONoutput > NoJSON))
|
||||
return
|
||||
}
|
||||
if handler.JSONoutput == AlwaysJSON || wantsJSON {
|
||||
if action.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)
|
||||
if err != nil {
|
||||
serveError(writer, "error", action, err.Error(), true)
|
||||
serveError(writer, "error", actionID, err.Error(), true)
|
||||
return
|
||||
}
|
||||
serverutil.MinifyWriter(writer, []byte(outputJSON), "application/json")
|
||||
|
|
|
@ -93,24 +93,38 @@ func GetStaffRank(request *http.Request) int {
|
|||
return staff.Rank
|
||||
}
|
||||
|
||||
// returns the action by its ID, or nil if it doesn't exist
|
||||
func getAction(id string, rank int) *Action {
|
||||
for a, _ := range actions {
|
||||
if rank == NoPerms && actions[a].Permissions > NoPerms {
|
||||
id = "login"
|
||||
}
|
||||
if actions[a].ID == id {
|
||||
return &actions[a]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
actions["actions"] = Action{
|
||||
actions = append(actions, Action{
|
||||
ID: "actions",
|
||||
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{}
|
||||
actionArr := []Action{}
|
||||
|
||||
for id, action := range actions {
|
||||
for _, action := range actions {
|
||||
if rank < action.Permissions || action.Permissions == NoPerms {
|
||||
continue
|
||||
}
|
||||
actionMap[id] = action
|
||||
actionArr = append(actionArr, action)
|
||||
}
|
||||
return actionMap, nil
|
||||
return actionArr, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue