gosora/gen_router.go
Azareal a5f5f4af7e Added the Page Manager for faster and easier custom page creation.
Added the PageStore.

Renamed account_own_edit.html to account_own_edit_password.html
Renamed custom-page.html to custom_page.html
Renamed the pre_render_custom_page hook to pre_render_tmpl_page.
Added a new pre_render_custom_page hook, not to be confused with the previous one.
Renamed the pre_render_account_own_edit_critical hook to pre_render_account_own_edit_password.
Moved the report forum ID into a constant.
Renamed todaysReportCount to topicsTopicCountByForum and made it more generic.
Renamed panel-menu.html to panel_menu.html
Renamed panel-inner-menu.html to panel_inner_menu.html
Removed an irrelevant editable_parent in a no results row.
Fixed the profile page loading the wrong profile.css
Fixed a bug where the last poster avatar would break on the forum page.
Added the AddNotice method to *Header.
Greatly simplified many of the page struct definitions.
Added the ErrorPage page struct and refactored the error pages to use it.
Added the BasePanelPage page struct and refactored the panel page structs to use it.
Tweaked the DefaultHeader function to set the user on the spot rather than after the fact.
Simplified AccountEditAvatarSubmit into a redirect.
Add the addElement closure in the control panel dashboard to reduce the amount of complexity.
Tweaked LogWarning to better handle nils.

Added the account_username phrase.
Added the account_avatar phrase.
Added the account_email phrase.
Added the panel_pages phrase.
Added the panel_pages_edit phrase.
Added the panel_page_created phrase.
Added the panel_page_updated phrase.
Added the panel_page_deleted phrase.
Added the account_menu_security phrase.
Added the panel_menu_pages phrase.
Added the panel_pages_head phrase.
Added the panel_pages_edit_button_aria phrase.
Added the panel_pages_delete_button_aria phrase.
Added the panel_pages_no_pages phrase.
Added the panel_pages_create_head phrase.
Added the panel_pages_create_name phrase.
Added the panel_pages_create_name_placeholder phrase.
Added the panel_pages_create_title phrase.
Added the panel_pages_create_title_placeholder phrase.
Added the panel_pages_create_body_placeholder phrase.
Added the panel_pages_create_submit_button phrase.
Added the panel_pages_edit_head phrase.
Added the panel_pages_name phrase.
Added the panel_pages_title phrase.
Added the panel_pages_edit_update_button phrase.

Began work on two-factor authentication.
Made more progress with the Nox Theme.
2018-06-06 10:21:22 +10:00

1995 lines
58 KiB
Go

// Code generated by. DO NOT EDIT.
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main
import (
"log"
"strings"
"strconv"
"sync"
"errors"
"os"
"net/http"
"./common"
"./common/counters"
"./routes"
"./routes/panel"
)
var ErrNoRoute = errors.New("That route doesn't exist.")
// TODO: What about the /uploads/ route? x.x
var RouteMap = map[string]interface{}{
"routeAPI": routeAPI,
"routes.Overview": routes.Overview,
"routes.CustomPage": routes.CustomPage,
"routes.ForumList": routes.ForumList,
"routes.ViewForum": routes.ViewForum,
"routes.ChangeTheme": routes.ChangeTheme,
"routes.ShowAttachment": routes.ShowAttachment,
"common.RouteWebsockets": common.RouteWebsockets,
"routes.ReportSubmit": routes.ReportSubmit,
"routes.CreateTopic": routes.CreateTopic,
"routes.TopicList": routes.TopicList,
"panel.Forums": panel.Forums,
"panel.ForumsCreateSubmit": panel.ForumsCreateSubmit,
"panel.ForumsDelete": panel.ForumsDelete,
"panel.ForumsDeleteSubmit": panel.ForumsDeleteSubmit,
"panel.ForumsEdit": panel.ForumsEdit,
"panel.ForumsEditSubmit": panel.ForumsEditSubmit,
"panel.ForumsEditPermsSubmit": panel.ForumsEditPermsSubmit,
"panel.ForumsEditPermsAdvance": panel.ForumsEditPermsAdvance,
"panel.ForumsEditPermsAdvanceSubmit": panel.ForumsEditPermsAdvanceSubmit,
"panel.Settings": panel.Settings,
"panel.SettingEdit": panel.SettingEdit,
"panel.SettingEditSubmit": panel.SettingEditSubmit,
"routePanelWordFilters": routePanelWordFilters,
"routePanelWordFiltersCreateSubmit": routePanelWordFiltersCreateSubmit,
"routePanelWordFiltersEdit": routePanelWordFiltersEdit,
"routePanelWordFiltersEditSubmit": routePanelWordFiltersEditSubmit,
"routePanelWordFiltersDeleteSubmit": routePanelWordFiltersDeleteSubmit,
"panel.Pages": panel.Pages,
"panel.PagesCreateSubmit": panel.PagesCreateSubmit,
"panel.PagesEdit": panel.PagesEdit,
"panel.PagesEditSubmit": panel.PagesEditSubmit,
"panel.PagesDeleteSubmit": panel.PagesDeleteSubmit,
"routePanelThemes": routePanelThemes,
"routePanelThemesSetDefault": routePanelThemesSetDefault,
"routePanelThemesMenus": routePanelThemesMenus,
"routePanelThemesMenusEdit": routePanelThemesMenusEdit,
"routePanelThemesMenuItemEdit": routePanelThemesMenuItemEdit,
"routePanelThemesMenuItemEditSubmit": routePanelThemesMenuItemEditSubmit,
"routePanelThemesMenuItemCreateSubmit": routePanelThemesMenuItemCreateSubmit,
"routePanelThemesMenuItemDeleteSubmit": routePanelThemesMenuItemDeleteSubmit,
"routePanelThemesMenuItemOrderSubmit": routePanelThemesMenuItemOrderSubmit,
"routePanelPlugins": routePanelPlugins,
"routePanelPluginsActivate": routePanelPluginsActivate,
"routePanelPluginsDeactivate": routePanelPluginsDeactivate,
"routePanelPluginsInstall": routePanelPluginsInstall,
"routePanelUsers": routePanelUsers,
"routePanelUsersEdit": routePanelUsersEdit,
"routePanelUsersEditSubmit": routePanelUsersEditSubmit,
"panel.AnalyticsViews": panel.AnalyticsViews,
"panel.AnalyticsRoutes": panel.AnalyticsRoutes,
"panel.AnalyticsAgents": panel.AnalyticsAgents,
"panel.AnalyticsSystems": panel.AnalyticsSystems,
"panel.AnalyticsLanguages": panel.AnalyticsLanguages,
"panel.AnalyticsReferrers": panel.AnalyticsReferrers,
"panel.AnalyticsRouteViews": panel.AnalyticsRouteViews,
"panel.AnalyticsAgentViews": panel.AnalyticsAgentViews,
"panel.AnalyticsForumViews": panel.AnalyticsForumViews,
"panel.AnalyticsSystemViews": panel.AnalyticsSystemViews,
"panel.AnalyticsLanguageViews": panel.AnalyticsLanguageViews,
"panel.AnalyticsReferrerViews": panel.AnalyticsReferrerViews,
"panel.AnalyticsPosts": panel.AnalyticsPosts,
"panel.AnalyticsTopics": panel.AnalyticsTopics,
"panel.AnalyticsForums": panel.AnalyticsForums,
"routePanelGroups": routePanelGroups,
"routePanelGroupsEdit": routePanelGroupsEdit,
"routePanelGroupsEditPerms": routePanelGroupsEditPerms,
"routePanelGroupsEditSubmit": routePanelGroupsEditSubmit,
"routePanelGroupsEditPermsSubmit": routePanelGroupsEditPermsSubmit,
"routePanelGroupsCreateSubmit": routePanelGroupsCreateSubmit,
"panel.Backups": panel.Backups,
"panel.LogsRegs": panel.LogsRegs,
"panel.LogsMod": panel.LogsMod,
"panel.Debug": panel.Debug,
"routePanelDashboard": routePanelDashboard,
"routes.AccountEditCritical": routes.AccountEditCritical,
"routes.AccountEditCriticalSubmit": routes.AccountEditCriticalSubmit,
"routes.AccountEditAvatar": routes.AccountEditAvatar,
"routes.AccountEditAvatarSubmit": routes.AccountEditAvatarSubmit,
"routes.AccountEditUsername": routes.AccountEditUsername,
"routes.AccountEditUsernameSubmit": routes.AccountEditUsernameSubmit,
"routes.AccountEditEmail": routes.AccountEditEmail,
"routes.AccountEditEmailTokenSubmit": routes.AccountEditEmailTokenSubmit,
"routes.ViewProfile": routes.ViewProfile,
"routes.BanUserSubmit": routes.BanUserSubmit,
"routes.UnbanUser": routes.UnbanUser,
"routes.ActivateUser": routes.ActivateUser,
"routes.IPSearch": routes.IPSearch,
"routes.CreateTopicSubmit": routes.CreateTopicSubmit,
"routes.EditTopicSubmit": routes.EditTopicSubmit,
"routes.DeleteTopicSubmit": routes.DeleteTopicSubmit,
"routes.StickTopicSubmit": routes.StickTopicSubmit,
"routes.UnstickTopicSubmit": routes.UnstickTopicSubmit,
"routes.LockTopicSubmit": routes.LockTopicSubmit,
"routes.UnlockTopicSubmit": routes.UnlockTopicSubmit,
"routes.MoveTopicSubmit": routes.MoveTopicSubmit,
"routes.LikeTopicSubmit": routes.LikeTopicSubmit,
"routes.ViewTopic": routes.ViewTopic,
"routes.CreateReplySubmit": routes.CreateReplySubmit,
"routes.ReplyEditSubmit": routes.ReplyEditSubmit,
"routes.ReplyDeleteSubmit": routes.ReplyDeleteSubmit,
"routes.ReplyLikeSubmit": routes.ReplyLikeSubmit,
"routes.ProfileReplyCreateSubmit": routes.ProfileReplyCreateSubmit,
"routes.ProfileReplyEditSubmit": routes.ProfileReplyEditSubmit,
"routes.ProfileReplyDeleteSubmit": routes.ProfileReplyDeleteSubmit,
"routes.PollVote": routes.PollVote,
"routes.PollResults": routes.PollResults,
"routes.AccountLogin": routes.AccountLogin,
"routes.AccountRegister": routes.AccountRegister,
"routes.AccountLogout": routes.AccountLogout,
"routes.AccountLoginSubmit": routes.AccountLoginSubmit,
"routes.AccountRegisterSubmit": routes.AccountRegisterSubmit,
"routes.DynamicRoute": routes.DynamicRoute,
"routes.UploadedFile": routes.UploadedFile,
"routes.StaticFile": routes.StaticFile,
"routes.RobotsTxt": routes.RobotsTxt,
"routes.SitemapXml": routes.SitemapXml,
"routes.BadRoute": routes.BadRoute,
}
// ! NEVER RELY ON THESE REMAINING THE SAME BETWEEN COMMITS
var routeMapEnum = map[string]int{
"routeAPI": 0,
"routes.Overview": 1,
"routes.CustomPage": 2,
"routes.ForumList": 3,
"routes.ViewForum": 4,
"routes.ChangeTheme": 5,
"routes.ShowAttachment": 6,
"common.RouteWebsockets": 7,
"routes.ReportSubmit": 8,
"routes.CreateTopic": 9,
"routes.TopicList": 10,
"panel.Forums": 11,
"panel.ForumsCreateSubmit": 12,
"panel.ForumsDelete": 13,
"panel.ForumsDeleteSubmit": 14,
"panel.ForumsEdit": 15,
"panel.ForumsEditSubmit": 16,
"panel.ForumsEditPermsSubmit": 17,
"panel.ForumsEditPermsAdvance": 18,
"panel.ForumsEditPermsAdvanceSubmit": 19,
"panel.Settings": 20,
"panel.SettingEdit": 21,
"panel.SettingEditSubmit": 22,
"routePanelWordFilters": 23,
"routePanelWordFiltersCreateSubmit": 24,
"routePanelWordFiltersEdit": 25,
"routePanelWordFiltersEditSubmit": 26,
"routePanelWordFiltersDeleteSubmit": 27,
"panel.Pages": 28,
"panel.PagesCreateSubmit": 29,
"panel.PagesEdit": 30,
"panel.PagesEditSubmit": 31,
"panel.PagesDeleteSubmit": 32,
"routePanelThemes": 33,
"routePanelThemesSetDefault": 34,
"routePanelThemesMenus": 35,
"routePanelThemesMenusEdit": 36,
"routePanelThemesMenuItemEdit": 37,
"routePanelThemesMenuItemEditSubmit": 38,
"routePanelThemesMenuItemCreateSubmit": 39,
"routePanelThemesMenuItemDeleteSubmit": 40,
"routePanelThemesMenuItemOrderSubmit": 41,
"routePanelPlugins": 42,
"routePanelPluginsActivate": 43,
"routePanelPluginsDeactivate": 44,
"routePanelPluginsInstall": 45,
"routePanelUsers": 46,
"routePanelUsersEdit": 47,
"routePanelUsersEditSubmit": 48,
"panel.AnalyticsViews": 49,
"panel.AnalyticsRoutes": 50,
"panel.AnalyticsAgents": 51,
"panel.AnalyticsSystems": 52,
"panel.AnalyticsLanguages": 53,
"panel.AnalyticsReferrers": 54,
"panel.AnalyticsRouteViews": 55,
"panel.AnalyticsAgentViews": 56,
"panel.AnalyticsForumViews": 57,
"panel.AnalyticsSystemViews": 58,
"panel.AnalyticsLanguageViews": 59,
"panel.AnalyticsReferrerViews": 60,
"panel.AnalyticsPosts": 61,
"panel.AnalyticsTopics": 62,
"panel.AnalyticsForums": 63,
"routePanelGroups": 64,
"routePanelGroupsEdit": 65,
"routePanelGroupsEditPerms": 66,
"routePanelGroupsEditSubmit": 67,
"routePanelGroupsEditPermsSubmit": 68,
"routePanelGroupsCreateSubmit": 69,
"panel.Backups": 70,
"panel.LogsRegs": 71,
"panel.LogsMod": 72,
"panel.Debug": 73,
"routePanelDashboard": 74,
"routes.AccountEditCritical": 75,
"routes.AccountEditCriticalSubmit": 76,
"routes.AccountEditAvatar": 77,
"routes.AccountEditAvatarSubmit": 78,
"routes.AccountEditUsername": 79,
"routes.AccountEditUsernameSubmit": 80,
"routes.AccountEditEmail": 81,
"routes.AccountEditEmailTokenSubmit": 82,
"routes.ViewProfile": 83,
"routes.BanUserSubmit": 84,
"routes.UnbanUser": 85,
"routes.ActivateUser": 86,
"routes.IPSearch": 87,
"routes.CreateTopicSubmit": 88,
"routes.EditTopicSubmit": 89,
"routes.DeleteTopicSubmit": 90,
"routes.StickTopicSubmit": 91,
"routes.UnstickTopicSubmit": 92,
"routes.LockTopicSubmit": 93,
"routes.UnlockTopicSubmit": 94,
"routes.MoveTopicSubmit": 95,
"routes.LikeTopicSubmit": 96,
"routes.ViewTopic": 97,
"routes.CreateReplySubmit": 98,
"routes.ReplyEditSubmit": 99,
"routes.ReplyDeleteSubmit": 100,
"routes.ReplyLikeSubmit": 101,
"routes.ProfileReplyCreateSubmit": 102,
"routes.ProfileReplyEditSubmit": 103,
"routes.ProfileReplyDeleteSubmit": 104,
"routes.PollVote": 105,
"routes.PollResults": 106,
"routes.AccountLogin": 107,
"routes.AccountRegister": 108,
"routes.AccountLogout": 109,
"routes.AccountLoginSubmit": 110,
"routes.AccountRegisterSubmit": 111,
"routes.DynamicRoute": 112,
"routes.UploadedFile": 113,
"routes.StaticFile": 114,
"routes.RobotsTxt": 115,
"routes.SitemapXml": 116,
"routes.BadRoute": 117,
}
var reverseRouteMapEnum = map[int]string{
0: "routeAPI",
1: "routes.Overview",
2: "routes.CustomPage",
3: "routes.ForumList",
4: "routes.ViewForum",
5: "routes.ChangeTheme",
6: "routes.ShowAttachment",
7: "common.RouteWebsockets",
8: "routes.ReportSubmit",
9: "routes.CreateTopic",
10: "routes.TopicList",
11: "panel.Forums",
12: "panel.ForumsCreateSubmit",
13: "panel.ForumsDelete",
14: "panel.ForumsDeleteSubmit",
15: "panel.ForumsEdit",
16: "panel.ForumsEditSubmit",
17: "panel.ForumsEditPermsSubmit",
18: "panel.ForumsEditPermsAdvance",
19: "panel.ForumsEditPermsAdvanceSubmit",
20: "panel.Settings",
21: "panel.SettingEdit",
22: "panel.SettingEditSubmit",
23: "routePanelWordFilters",
24: "routePanelWordFiltersCreateSubmit",
25: "routePanelWordFiltersEdit",
26: "routePanelWordFiltersEditSubmit",
27: "routePanelWordFiltersDeleteSubmit",
28: "panel.Pages",
29: "panel.PagesCreateSubmit",
30: "panel.PagesEdit",
31: "panel.PagesEditSubmit",
32: "panel.PagesDeleteSubmit",
33: "routePanelThemes",
34: "routePanelThemesSetDefault",
35: "routePanelThemesMenus",
36: "routePanelThemesMenusEdit",
37: "routePanelThemesMenuItemEdit",
38: "routePanelThemesMenuItemEditSubmit",
39: "routePanelThemesMenuItemCreateSubmit",
40: "routePanelThemesMenuItemDeleteSubmit",
41: "routePanelThemesMenuItemOrderSubmit",
42: "routePanelPlugins",
43: "routePanelPluginsActivate",
44: "routePanelPluginsDeactivate",
45: "routePanelPluginsInstall",
46: "routePanelUsers",
47: "routePanelUsersEdit",
48: "routePanelUsersEditSubmit",
49: "panel.AnalyticsViews",
50: "panel.AnalyticsRoutes",
51: "panel.AnalyticsAgents",
52: "panel.AnalyticsSystems",
53: "panel.AnalyticsLanguages",
54: "panel.AnalyticsReferrers",
55: "panel.AnalyticsRouteViews",
56: "panel.AnalyticsAgentViews",
57: "panel.AnalyticsForumViews",
58: "panel.AnalyticsSystemViews",
59: "panel.AnalyticsLanguageViews",
60: "panel.AnalyticsReferrerViews",
61: "panel.AnalyticsPosts",
62: "panel.AnalyticsTopics",
63: "panel.AnalyticsForums",
64: "routePanelGroups",
65: "routePanelGroupsEdit",
66: "routePanelGroupsEditPerms",
67: "routePanelGroupsEditSubmit",
68: "routePanelGroupsEditPermsSubmit",
69: "routePanelGroupsCreateSubmit",
70: "panel.Backups",
71: "panel.LogsRegs",
72: "panel.LogsMod",
73: "panel.Debug",
74: "routePanelDashboard",
75: "routes.AccountEditCritical",
76: "routes.AccountEditCriticalSubmit",
77: "routes.AccountEditAvatar",
78: "routes.AccountEditAvatarSubmit",
79: "routes.AccountEditUsername",
80: "routes.AccountEditUsernameSubmit",
81: "routes.AccountEditEmail",
82: "routes.AccountEditEmailTokenSubmit",
83: "routes.ViewProfile",
84: "routes.BanUserSubmit",
85: "routes.UnbanUser",
86: "routes.ActivateUser",
87: "routes.IPSearch",
88: "routes.CreateTopicSubmit",
89: "routes.EditTopicSubmit",
90: "routes.DeleteTopicSubmit",
91: "routes.StickTopicSubmit",
92: "routes.UnstickTopicSubmit",
93: "routes.LockTopicSubmit",
94: "routes.UnlockTopicSubmit",
95: "routes.MoveTopicSubmit",
96: "routes.LikeTopicSubmit",
97: "routes.ViewTopic",
98: "routes.CreateReplySubmit",
99: "routes.ReplyEditSubmit",
100: "routes.ReplyDeleteSubmit",
101: "routes.ReplyLikeSubmit",
102: "routes.ProfileReplyCreateSubmit",
103: "routes.ProfileReplyEditSubmit",
104: "routes.ProfileReplyDeleteSubmit",
105: "routes.PollVote",
106: "routes.PollResults",
107: "routes.AccountLogin",
108: "routes.AccountRegister",
109: "routes.AccountLogout",
110: "routes.AccountLoginSubmit",
111: "routes.AccountRegisterSubmit",
112: "routes.DynamicRoute",
113: "routes.UploadedFile",
114: "routes.StaticFile",
115: "routes.RobotsTxt",
116: "routes.SitemapXml",
117: "routes.BadRoute",
}
var osMapEnum = map[string]int{
"unknown": 0,
"windows": 1,
"linux": 2,
"mac": 3,
"android": 4,
"iphone": 5,
}
var reverseOSMapEnum = map[int]string{
0: "unknown",
1: "windows",
2: "linux",
3: "mac",
4: "android",
5: "iphone",
}
var agentMapEnum = map[string]int{
"unknown": 0,
"firefox": 1,
"chrome": 2,
"opera": 3,
"safari": 4,
"edge": 5,
"internetexplorer": 6,
"trident": 7,
"androidchrome": 8,
"mobilesafari": 9,
"samsung": 10,
"ucbrowser": 11,
"googlebot": 12,
"yandex": 13,
"bing": 14,
"baidu": 15,
"duckduckgo": 16,
"seznambot": 17,
"discord": 18,
"twitter": 19,
"cloudflare": 20,
"uptimebot": 21,
"slackbot": 22,
"discourse": 23,
"lynx": 24,
"blank": 25,
"malformed": 26,
"suspicious": 27,
"zgrab": 28,
}
var reverseAgentMapEnum = map[int]string{
0: "unknown",
1: "firefox",
2: "chrome",
3: "opera",
4: "safari",
5: "edge",
6: "internetexplorer",
7: "trident",
8: "androidchrome",
9: "mobilesafari",
10: "samsung",
11: "ucbrowser",
12: "googlebot",
13: "yandex",
14: "bing",
15: "baidu",
16: "duckduckgo",
17: "seznambot",
18: "discord",
19: "twitter",
20: "cloudflare",
21: "uptimebot",
22: "slackbot",
23: "discourse",
24: "lynx",
25: "blank",
26: "malformed",
27: "suspicious",
28: "zgrab",
}
var markToAgent = map[string]string{
"OPR":"opera",
"Chrome":"chrome",
"Firefox":"firefox",
"MSIE":"internetexplorer",
"Trident":"trident", // Hack to support IE11
"Edge":"edge",
"Lynx":"lynx", // There's a rare android variant of lynx which isn't covered by this
"SamsungBrowser":"samsung",
"UCBrowser":"ucbrowser",
"Google":"googlebot",
"Googlebot":"googlebot",
"yandex": "yandex", // from the URL
"DuckDuckBot":"duckduckgo",
"Baiduspider":"baidu",
"bingbot":"bing",
"BingPreview":"bing",
"SeznamBot":"seznambot",
"CloudFlare":"cloudflare", // Track alwayson specifically in case there are other bots?
"Uptimebot":"uptimebot",
"Slackbot":"slackbot",
"Discordbot":"discord",
"Twitterbot":"twitter",
"Discourse":"discourse",
"zgrab":"zgrab",
}
/*var agentRank = map[string]int{
"opera":9,
"chrome":8,
"safari":1,
}*/
// TODO: Stop spilling these into the package scope?
func init() {
counters.SetRouteMapEnum(routeMapEnum)
counters.SetReverseRouteMapEnum(reverseRouteMapEnum)
counters.SetAgentMapEnum(agentMapEnum)
counters.SetReverseAgentMapEnum(reverseAgentMapEnum)
counters.SetOSMapEnum(osMapEnum)
counters.SetReverseOSMapEnum(reverseOSMapEnum)
}
type WriterIntercept struct {
w http.ResponseWriter
code int
}
func NewWriterIntercept(w http.ResponseWriter) *WriterIntercept {
return &WriterIntercept{w:w,code:200}
}
func (writ *WriterIntercept) Header() http.Header {
return writ.w.Header()
}
func (writ *WriterIntercept) Write(pieces []byte) (int, error) {
return writ.w.Write(pieces)
}
func (writ *WriterIntercept) WriteHeader(code int) {
writ.w.WriteHeader(code)
writ.code = code
}
func (writ *WriterIntercept) GetCode() int {
return writ.code
}
type GenRouter struct {
UploadHandler func(http.ResponseWriter, *http.Request)
extraRoutes map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError
requestLogger *log.Logger
sync.RWMutex
}
func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
f, err := os.OpenFile("./logs/requests.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
if err != nil {
return nil, err
}
return &GenRouter{
UploadHandler: func(w http.ResponseWriter, req *http.Request) {
writ := NewWriterIntercept(w)
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
if writ.GetCode() == 200 {
w.Header().Set("Cache-Control", "max-age=" + strconv.Itoa(int(common.Day)))
w.Header().Set("Vary", "Accept-Encoding")
}
},
extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, common.User) common.RouteError),
requestLogger: log.New(f, "", log.LstdFlags),
}, nil
}
func (router *GenRouter) handleError(err common.RouteError, w http.ResponseWriter, r *http.Request, user common.User) {
if err.Handled() {
return
}
if err.Type() == "system" {
common.InternalErrorJSQ(err, w, r, err.JSON())
return
}
common.LocalErrorJSQ(err.Error(), w, r, user,err.JSON())
}
func (router *GenRouter) Handle(_ string, _ http.Handler) {
}
func (router *GenRouter) HandleFunc(pattern string, handle func(http.ResponseWriter, *http.Request, common.User) common.RouteError) {
router.Lock()
defer router.Unlock()
router.extraRoutes[pattern] = handle
}
func (router *GenRouter) RemoveFunc(pattern string) error {
router.Lock()
defer router.Unlock()
_, ok := router.extraRoutes[pattern]
if !ok {
return ErrNoRoute
}
delete(router.extraRoutes, pattern)
return nil
}
func (router *GenRouter) DumpRequest(req *http.Request, prepend string) {
var heads string
for key, value := range req.Header {
for _, vvalue := range value {
heads += "Header '" + common.SanitiseSingleLine(key) + "': " + common.SanitiseSingleLine(vvalue) + "!!\n"
}
}
router.requestLogger.Print(prepend +
"\nUA: " + common.SanitiseSingleLine(req.UserAgent()) + "\n" +
"Method: " + common.SanitiseSingleLine(req.Method) + "\n" + heads +
"req.Host: " + common.SanitiseSingleLine(req.Host) + "\n" +
"req.URL.Path: " + common.SanitiseSingleLine(req.URL.Path) + "\n" +
"req.URL.RawQuery: " + common.SanitiseSingleLine(req.URL.RawQuery) + "\n" +
"req.Referer(): " + common.SanitiseSingleLine(req.Referer()) + "\n" +
"req.RemoteAddr: " + req.RemoteAddr + "\n")
}
func (router *GenRouter) SuspiciousRequest(req *http.Request, prepend string) {
if prepend != "" {
prepend += "\n"
}
router.DumpRequest(req,prepend+"Suspicious Request")
counters.AgentViewCounter.Bump(27)
}
// TODO: Pass the default route or config struct to the router rather than accessing it via a package global
// TODO: SetDefaultRoute
// TODO: GetDefaultRoute
func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// Redirect www. requests to the right place
if req.Host == "www." + common.Site.Host {
w.Header().Set("Connection", "close")
var s string
if common.Site.EnableSsl {
s = "s"
}
dest := "http"+s+"://" + req.Host + req.URL.Path
if len(req.URL.RawQuery) > 0 {
dest += "?" + req.URL.RawQuery
}
http.Redirect(w, req, dest, http.StatusMovedPermanently)
return
}
// Deflect malformed requests
if len(req.URL.Path) == 0 || req.URL.Path[0] != '/' || req.Host != common.Site.Host {
w.WriteHeader(200) // 400
w.Write([]byte(""))
router.DumpRequest(req,"Malformed Request")
counters.AgentViewCounter.Bump(26)
return
}
// TODO: Cover more suspicious strings and at a lower layer than this
for _, char := range req.URL.Path {
if char != '&' && !(char > 44 && char < 58) && char != '=' && char != '?' && !(char > 64 && char < 91) && char != '\\' && char != '_' && !(char > 96 && char < 123) {
router.SuspiciousRequest(req,"")
break
}
}
lowerPath := strings.ToLower(req.URL.Path)
// TODO: Flag any requests which has a dot with anything but a number after that
if strings.Contains(req.URL.Path,"..") || strings.Contains(req.URL.Path,"--") || strings.Contains(lowerPath,".php") || strings.Contains(lowerPath,".asp") || strings.Contains(lowerPath,".cgi") || strings.Contains(lowerPath,".py") || strings.Contains(lowerPath,".sql") || strings.Contains(lowerPath,".action") {
router.SuspiciousRequest(req,"")
}
var prefix, extraData string
prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1]
if req.URL.Path[len(req.URL.Path) - 1] != '/' {
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
}
if common.Dev.SuperDebug {
router.DumpRequest(req,"before routes.StaticFile")
}
// Increment the request counter
counters.GlobalViewCounter.Bump()
if prefix == "/static" {
counters.RouteViewCounter.Bump(114)
req.URL.Path += extraData
routes.StaticFile(w, req)
return
}
if common.Dev.SuperDebug {
router.requestLogger.Print("before PreRoute")
}
// Track the user agents. Unfortunately, everyone pretends to be Mozilla, so this'll be a little less efficient than I would like.
// TODO: Add a setting to disable this?
// TODO: Use a more efficient detector instead of smashing every possible combination in
ua := strings.TrimSpace(strings.Replace(strings.TrimPrefix(req.UserAgent(),"Mozilla/5.0 ")," Safari/537.36","",-1)) // Noise, no one's going to be running this and it would require some sort of agent ranking system to determine which identifier should be prioritised over another
if ua == "" {
counters.AgentViewCounter.Bump(25)
if common.Dev.DebugMode {
var prepend string
for _, char := range req.UserAgent() {
prepend += strconv.Itoa(int(char)) + " "
}
router.DumpRequest(req,"Blank UA: " + prepend)
}
} else {
var runeEquals = func(a []rune, b []rune) bool {
if len(a) != len(b) {
return false
}
for i, item := range a {
if item != b[i] {
return false
}
}
return true
}
// WIP UA Parser
var indices []int
var items []string
var buffer []rune
for index, item := range ua {
if (item > 64 && item < 91) || (item > 96 && item < 123) {
buffer = append(buffer, item)
} else if item == ' ' || item == '(' || item == ')' || item == '-' || (item > 47 && item < 58) || item == '_' || item == ';' || item == '.' || item == '+' || (item == ':' && (runeEquals(buffer,[]rune("http")) || runeEquals(buffer,[]rune("rv")))) || item == ',' || item == '/' {
if len(buffer) != 0 {
items = append(items, string(buffer))
indices = append(indices, index - 1)
buffer = buffer[:0]
}
} else {
// TODO: Test this
items = items[:0]
indices = indices[:0]
router.SuspiciousRequest(req,"")
router.requestLogger.Print("UA Buffer: ", buffer)
router.requestLogger.Print("UA Buffer String: ", string(buffer))
break
}
}
// Iterate over this in reverse as the real UA tends to be on the right side
var agent string
for i := len(items) - 1; i >= 0; i-- {
fAgent, ok := markToAgent[items[i]]
if ok {
agent = fAgent
if agent != "safari" {
break
}
}
}
if common.Dev.SuperDebug {
router.requestLogger.Print("parsed agent: ", agent)
}
var os string
for _, mark := range items {
switch(mark) {
case "Windows":
os = "windows"
case "Linux":
os = "linux"
case "Mac":
os = "mac"
case "iPhone":
os = "iphone"
case "Android":
os = "android"
}
}
if os == "" {
os = "unknown"
}
if common.Dev.SuperDebug {
router.requestLogger.Print("os: ", os)
router.requestLogger.Printf("items: %+v\n",items)
}
// Special handling
switch(agent) {
case "chrome":
if os == "android" {
agent = "androidchrome"
}
case "safari":
if os == "iphone" {
agent = "mobilesafari"
}
case "trident":
// Hack to support IE11, change this after we start logging versions
if strings.Contains(ua,"rv:11") {
agent = "internetexplorer"
}
case "zgrab":
router.SuspiciousRequest(req,"Vulnerability Scanner")
}
if agent == "" {
counters.AgentViewCounter.Bump(0)
if common.Dev.DebugMode {
var prepend string
for _, char := range req.UserAgent() {
prepend += strconv.Itoa(int(char)) + " "
}
router.DumpRequest(req,"Blank UA: " + prepend)
}
} else {
counters.AgentViewCounter.Bump(agentMapEnum[agent])
}
counters.OSViewCounter.Bump(osMapEnum[os])
}
// TODO: Do we want to track missing language headers too? Maybe as it's own type, e.g. "noheader"?
lang := req.Header.Get("Accept-Language")
if lang != "" {
lang = strings.TrimSpace(lang)
lLang := strings.Split(lang,"-")
common.DebugDetail("lLang:", lLang)
counters.LangViewCounter.Bump(lLang[0])
} else {
counters.LangViewCounter.Bump("none")
}
referrer := req.Header.Get("Referer") // Check the 'referrer' header too? :P
if referrer != "" {
// ? Optimise this a little?
referrer = strings.TrimPrefix(strings.TrimPrefix(referrer,"http://"),"https://")
referrer = strings.Split(referrer,"/")[0]
portless := strings.Split(referrer,":")[0]
if portless != "localhost" && portless != "127.0.0.1" && portless != common.Site.Host {
counters.ReferrerTracker.Bump(referrer)
}
}
// Deal with the session stuff, etc.
user, ok := common.PreRoute(w, req)
if !ok {
return
}
if common.Dev.SuperDebug {
router.requestLogger.Print(
"after PreRoute\n" +
"routeMapEnum: ", routeMapEnum)
}
var err common.RouteError
switch(prefix) {
case "/api":
counters.RouteViewCounter.Bump(0)
err = routeAPI(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/overview":
counters.RouteViewCounter.Bump(1)
err = routes.Overview(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/pages":
counters.RouteViewCounter.Bump(2)
err = routes.CustomPage(w,req,user,extraData)
if err != nil {
router.handleError(err,w,req,user)
}
case "/forums":
counters.RouteViewCounter.Bump(3)
err = routes.ForumList(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/forum":
counters.RouteViewCounter.Bump(4)
err = routes.ViewForum(w,req,user,extraData)
if err != nil {
router.handleError(err,w,req,user)
}
case "/theme":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(5)
err = routes.ChangeTheme(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/attachs":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(6)
err = routes.ShowAttachment(w,req,user,extraData)
if err != nil {
router.handleError(err,w,req,user)
}
case "/ws":
req.URL.Path += extraData
counters.RouteViewCounter.Bump(7)
err = common.RouteWebsockets(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
case "/report":
err = common.NoBanned(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
switch(req.URL.Path) {
case "/report/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(8)
err = routes.ReportSubmit(w,req,user,extraData)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/topics":
switch(req.URL.Path) {
case "/topics/create/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(9)
err = routes.CreateTopic(w,req,user,extraData)
default:
counters.RouteViewCounter.Bump(10)
err = routes.TopicList(w,req,user)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/panel":
err = common.SuperModOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
switch(req.URL.Path) {
case "/panel/forums/":
counters.RouteViewCounter.Bump(11)
err = panel.Forums(w,req,user)
case "/panel/forums/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(12)
err = panel.ForumsCreateSubmit(w,req,user)
case "/panel/forums/delete/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(13)
err = panel.ForumsDelete(w,req,user,extraData)
case "/panel/forums/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(14)
err = panel.ForumsDeleteSubmit(w,req,user,extraData)
case "/panel/forums/edit/":
counters.RouteViewCounter.Bump(15)
err = panel.ForumsEdit(w,req,user,extraData)
case "/panel/forums/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(16)
err = panel.ForumsEditSubmit(w,req,user,extraData)
case "/panel/forums/edit/perms/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(17)
err = panel.ForumsEditPermsSubmit(w,req,user,extraData)
case "/panel/forums/edit/perms/":
counters.RouteViewCounter.Bump(18)
err = panel.ForumsEditPermsAdvance(w,req,user,extraData)
case "/panel/forums/edit/perms/adv/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(19)
err = panel.ForumsEditPermsAdvanceSubmit(w,req,user,extraData)
case "/panel/settings/":
counters.RouteViewCounter.Bump(20)
err = panel.Settings(w,req,user)
case "/panel/settings/edit/":
counters.RouteViewCounter.Bump(21)
err = panel.SettingEdit(w,req,user,extraData)
case "/panel/settings/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(22)
err = panel.SettingEditSubmit(w,req,user,extraData)
case "/panel/settings/word-filters/":
counters.RouteViewCounter.Bump(23)
err = routePanelWordFilters(w,req,user)
case "/panel/settings/word-filters/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(24)
err = routePanelWordFiltersCreateSubmit(w,req,user)
case "/panel/settings/word-filters/edit/":
counters.RouteViewCounter.Bump(25)
err = routePanelWordFiltersEdit(w,req,user,extraData)
case "/panel/settings/word-filters/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(26)
err = routePanelWordFiltersEditSubmit(w,req,user,extraData)
case "/panel/settings/word-filters/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(27)
err = routePanelWordFiltersDeleteSubmit(w,req,user,extraData)
case "/panel/pages/":
err = common.AdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(28)
err = panel.Pages(w,req,user)
case "/panel/pages/create/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.AdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(29)
err = panel.PagesCreateSubmit(w,req,user)
case "/panel/pages/edit/":
err = common.AdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(30)
err = panel.PagesEdit(w,req,user,extraData)
case "/panel/pages/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.AdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(31)
err = panel.PagesEditSubmit(w,req,user,extraData)
case "/panel/pages/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.AdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(32)
err = panel.PagesDeleteSubmit(w,req,user,extraData)
case "/panel/themes/":
counters.RouteViewCounter.Bump(33)
err = routePanelThemes(w,req,user)
case "/panel/themes/default/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(34)
err = routePanelThemesSetDefault(w,req,user,extraData)
case "/panel/themes/menus/":
counters.RouteViewCounter.Bump(35)
err = routePanelThemesMenus(w,req,user)
case "/panel/themes/menus/edit/":
counters.RouteViewCounter.Bump(36)
err = routePanelThemesMenusEdit(w,req,user,extraData)
case "/panel/themes/menus/item/edit/":
counters.RouteViewCounter.Bump(37)
err = routePanelThemesMenuItemEdit(w,req,user,extraData)
case "/panel/themes/menus/item/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(38)
err = routePanelThemesMenuItemEditSubmit(w,req,user,extraData)
case "/panel/themes/menus/item/create/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(39)
err = routePanelThemesMenuItemCreateSubmit(w,req,user)
case "/panel/themes/menus/item/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(40)
err = routePanelThemesMenuItemDeleteSubmit(w,req,user,extraData)
case "/panel/themes/menus/item/order/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(41)
err = routePanelThemesMenuItemOrderSubmit(w,req,user,extraData)
case "/panel/plugins/":
counters.RouteViewCounter.Bump(42)
err = routePanelPlugins(w,req,user)
case "/panel/plugins/activate/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(43)
err = routePanelPluginsActivate(w,req,user,extraData)
case "/panel/plugins/deactivate/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(44)
err = routePanelPluginsDeactivate(w,req,user,extraData)
case "/panel/plugins/install/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(45)
err = routePanelPluginsInstall(w,req,user,extraData)
case "/panel/users/":
counters.RouteViewCounter.Bump(46)
err = routePanelUsers(w,req,user)
case "/panel/users/edit/":
counters.RouteViewCounter.Bump(47)
err = routePanelUsersEdit(w,req,user,extraData)
case "/panel/users/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(48)
err = routePanelUsersEditSubmit(w,req,user,extraData)
case "/panel/analytics/views/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(49)
err = panel.AnalyticsViews(w,req,user)
case "/panel/analytics/routes/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(50)
err = panel.AnalyticsRoutes(w,req,user)
case "/panel/analytics/agents/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(51)
err = panel.AnalyticsAgents(w,req,user)
case "/panel/analytics/systems/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(52)
err = panel.AnalyticsSystems(w,req,user)
case "/panel/analytics/langs/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(53)
err = panel.AnalyticsLanguages(w,req,user)
case "/panel/analytics/referrers/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(54)
err = panel.AnalyticsReferrers(w,req,user)
case "/panel/analytics/route/":
counters.RouteViewCounter.Bump(55)
err = panel.AnalyticsRouteViews(w,req,user,extraData)
case "/panel/analytics/agent/":
counters.RouteViewCounter.Bump(56)
err = panel.AnalyticsAgentViews(w,req,user,extraData)
case "/panel/analytics/forum/":
counters.RouteViewCounter.Bump(57)
err = panel.AnalyticsForumViews(w,req,user,extraData)
case "/panel/analytics/system/":
counters.RouteViewCounter.Bump(58)
err = panel.AnalyticsSystemViews(w,req,user,extraData)
case "/panel/analytics/lang/":
counters.RouteViewCounter.Bump(59)
err = panel.AnalyticsLanguageViews(w,req,user,extraData)
case "/panel/analytics/referrer/":
counters.RouteViewCounter.Bump(60)
err = panel.AnalyticsReferrerViews(w,req,user,extraData)
case "/panel/analytics/posts/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(61)
err = panel.AnalyticsPosts(w,req,user)
case "/panel/analytics/topics/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(62)
err = panel.AnalyticsTopics(w,req,user)
case "/panel/analytics/forums/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(63)
err = panel.AnalyticsForums(w,req,user)
case "/panel/groups/":
counters.RouteViewCounter.Bump(64)
err = routePanelGroups(w,req,user)
case "/panel/groups/edit/":
counters.RouteViewCounter.Bump(65)
err = routePanelGroupsEdit(w,req,user,extraData)
case "/panel/groups/edit/perms/":
counters.RouteViewCounter.Bump(66)
err = routePanelGroupsEditPerms(w,req,user,extraData)
case "/panel/groups/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(67)
err = routePanelGroupsEditSubmit(w,req,user,extraData)
case "/panel/groups/edit/perms/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(68)
err = routePanelGroupsEditPermsSubmit(w,req,user,extraData)
case "/panel/groups/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(69)
err = routePanelGroupsCreateSubmit(w,req,user)
case "/panel/backups/":
err = common.SuperAdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(70)
err = panel.Backups(w,req,user,extraData)
case "/panel/logs/regs/":
counters.RouteViewCounter.Bump(71)
err = panel.LogsRegs(w,req,user)
case "/panel/logs/mod/":
counters.RouteViewCounter.Bump(72)
err = panel.LogsMod(w,req,user)
case "/panel/debug/":
err = common.AdminOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(73)
err = panel.Debug(w,req,user)
default:
counters.RouteViewCounter.Bump(74)
err = routePanelDashboard(w,req,user)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/user":
switch(req.URL.Path) {
case "/user/edit/critical/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(75)
err = routes.AccountEditCritical(w,req,user)
case "/user/edit/critical/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(76)
err = routes.AccountEditCriticalSubmit(w,req,user)
case "/user/edit/avatar/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(77)
err = routes.AccountEditAvatar(w,req,user)
case "/user/edit/avatar/submit/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(78)
err = routes.AccountEditAvatarSubmit(w,req,user)
case "/user/edit/username/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(79)
err = routes.AccountEditUsername(w,req,user)
case "/user/edit/username/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(80)
err = routes.AccountEditUsernameSubmit(w,req,user)
case "/user/edit/email/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(81)
err = routes.AccountEditEmail(w,req,user)
case "/user/edit/token/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(82)
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
default:
req.URL.Path += extraData
counters.RouteViewCounter.Bump(83)
err = routes.ViewProfile(w,req,user)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/users":
switch(req.URL.Path) {
case "/users/ban/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(84)
err = routes.BanUserSubmit(w,req,user,extraData)
case "/users/unban/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(85)
err = routes.UnbanUser(w,req,user,extraData)
case "/users/activate/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(86)
err = routes.ActivateUser(w,req,user,extraData)
case "/users/ips/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(87)
err = routes.IPSearch(w,req,user)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/topic":
switch(req.URL.Path) {
case "/topic/create/submit/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(88)
err = routes.CreateTopicSubmit(w,req,user)
case "/topic/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(89)
err = routes.EditTopicSubmit(w,req,user,extraData)
case "/topic/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
req.URL.Path += extraData
counters.RouteViewCounter.Bump(90)
err = routes.DeleteTopicSubmit(w,req,user)
case "/topic/stick/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(91)
err = routes.StickTopicSubmit(w,req,user,extraData)
case "/topic/unstick/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(92)
err = routes.UnstickTopicSubmit(w,req,user,extraData)
case "/topic/lock/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
req.URL.Path += extraData
counters.RouteViewCounter.Bump(93)
err = routes.LockTopicSubmit(w,req,user)
case "/topic/unlock/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(94)
err = routes.UnlockTopicSubmit(w,req,user,extraData)
case "/topic/move/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(95)
err = routes.MoveTopicSubmit(w,req,user,extraData)
case "/topic/like/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(96)
err = routes.LikeTopicSubmit(w,req,user,extraData)
default:
counters.RouteViewCounter.Bump(97)
err = routes.ViewTopic(w,req,user, extraData)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/reply":
switch(req.URL.Path) {
case "/reply/create/":
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.HandleUploadRoute(w,req,user,int(common.Config.MaxRequestSize))
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.NoUploadSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(98)
err = routes.CreateReplySubmit(w,req,user)
case "/reply/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(99)
err = routes.ReplyEditSubmit(w,req,user,extraData)
case "/reply/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(100)
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
case "/reply/like/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(101)
err = routes.ReplyLikeSubmit(w,req,user,extraData)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/profile":
switch(req.URL.Path) {
case "/profile/reply/create/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(102)
err = routes.ProfileReplyCreateSubmit(w,req,user)
case "/profile/reply/edit/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(103)
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
case "/profile/reply/delete/submit/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(104)
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/poll":
switch(req.URL.Path) {
case "/poll/vote/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(105)
err = routes.PollVote(w,req,user,extraData)
case "/poll/results/":
counters.RouteViewCounter.Bump(106)
err = routes.PollResults(w,req,user,extraData)
}
if err != nil {
router.handleError(err,w,req,user)
}
case "/accounts":
switch(req.URL.Path) {
case "/accounts/login/":
counters.RouteViewCounter.Bump(107)
err = routes.AccountLogin(w,req,user)
case "/accounts/create/":
counters.RouteViewCounter.Bump(108)
err = routes.AccountRegister(w,req,user)
case "/accounts/logout/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(109)
err = routes.AccountLogout(w,req,user)
case "/accounts/login/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(110)
err = routes.AccountLoginSubmit(w,req,user)
case "/accounts/create/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
counters.RouteViewCounter.Bump(111)
err = routes.AccountRegisterSubmit(w,req,user)
}
if err != nil {
router.handleError(err,w,req,user)
}
/*case "/sitemaps": // TODO: Count these views
req.URL.Path += extraData
err = sitemapSwitch(w,req)
if err != nil {
router.handleError(err,w,req,user)
}*/
case "/uploads":
if extraData == "" {
common.NotFound(w,req,nil)
return
}
counters.RouteViewCounter.Bump(113)
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
router.UploadHandler(w,req) // TODO: Count these views
case "":
// Stop the favicons, robots.txt file, etc. resolving to the topics list
// TODO: Add support for favicons and robots.txt files
switch(extraData) {
case "robots.txt":
counters.RouteViewCounter.Bump(115)
err = routes.RobotsTxt(w,req)
if err != nil {
router.handleError(err,w,req,user)
}
return
/*case "sitemap.xml":
counters.RouteViewCounter.Bump(116)
err = routes.SitemapXml(w,req)
if err != nil {
router.handleError(err,w,req,user)
}
return*/
}
if extraData != "" {
common.NotFound(w,req,nil)
return
}
handle, ok := RouteMap[common.Config.DefaultRoute]
if !ok {
// TODO: Make this a startup error not a runtime one
router.requestLogger.Print("Unable to find the default route")
common.NotFound(w,req,nil)
return
}
counters.RouteViewCounter.Bump(routeMapEnum[common.Config.DefaultRoute])
handle.(func(http.ResponseWriter, *http.Request, common.User) common.RouteError)(w,req,user)
default:
// A fallback for the routes which haven't been converted to the new router yet or plugins
router.RLock()
handle, ok := router.extraRoutes[req.URL.Path]
router.RUnlock()
if ok {
counters.RouteViewCounter.Bump(112) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData
err = handle(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
}
return
}
lowerPath := strings.ToLower(req.URL.Path)
if strings.Contains(lowerPath,"admin") || strings.Contains(lowerPath,"sql") || strings.Contains(lowerPath,"manage") || strings.Contains(lowerPath,"//") || strings.Contains(lowerPath,"\\\\") || strings.Contains(lowerPath,"wp") || strings.Contains(lowerPath,"wordpress") || strings.Contains(lowerPath,"config") || strings.Contains(lowerPath,"setup") || strings.Contains(lowerPath,"install") || strings.Contains(lowerPath,"update") || strings.Contains(lowerPath,"php") {
router.SuspiciousRequest(req,"Bad Route")
} else {
router.DumpRequest(req,"Bad Route")
}
counters.RouteViewCounter.Bump(117)
common.NotFound(w,req,nil)
}
}