gosora/gen_router.go
Azareal ca80d0dd6f Began work on the Nox Theme.
Removed the Tempra Cursive Theme.
You can now do bulk moderation actions with Shadow.

Added:
Argon2 as a dependency.
The EmailStore.
The ReportStore.
The Copy method to *Setting.
The AddColumn method to the query builder and adapters.
The textarea setting type.
More logging to better debug issues.
The GetOffset method to the UserStore.

Removed:
Sortable from Code Climate's Analysis.
MemberCheck and memberCheck as they're obsolete now.
The obsolete url_tags setting.
The BcryptGeneratePasswordNoSalt function.
Some redundant fields from some of the page structs.

Revamped:
The Control Panel Setting List and Editor.

Refactored:
The password hashing logic to make it more amenable to multiple hashing algorithms.
The email portion of the Account Manager.
The Control Panel User List.
The report system.
simplePanelUserCheck and simpleUserCheck to remove the duplicated logic as the two do the exact same thing.

Fixed:
Missing slugs in the profile links in the User Manager.
A few template initialisers potentially reducing the number of odd template edge cases.
Some problems with the footer.
Custom selection colour not applying to images on Shadow.
The avatars of the bottom row of the topic list on Conflux leaking out.

Other:
Moved the startTime variable into package common and exported it.
Moved the password hashing logic from user.go to auth.go
Split common/themes.go into common/theme.go and common/theme_list.go
Replaced the SettingLabels phrase category with the more generic SettingPhrases category.
Moved a load of routes, including panel ones into the routes and panel packages.
Hid the notifications link from the Account Menu.
Moved more inline CSS into the CSS files and made things a little more flexible here and there.
Continued work on PgSQL, still a ways away.
Guests now have a default avatar like everyone else.
Tweaked some of the font sizes on Cosora to make the text look a little nicer.
Partially implemented the theme dock override logic.
Partially implemented a "symlink" like feature for theme directories.
... And a bunch of other things I might have missed.

You will need to run this update script / patcher for this commit.
Warning: This is an "unstable commit", therefore some things may be a little less stable than I'd like. For instance, the Shadow Theme is a little broken in this commit.
2018-05-27 19:18:29 +10:00

1922 lines
56 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,
"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,
"routePanelThemes": 28,
"routePanelThemesSetDefault": 29,
"routePanelThemesMenus": 30,
"routePanelThemesMenusEdit": 31,
"routePanelThemesMenuItemEdit": 32,
"routePanelThemesMenuItemEditSubmit": 33,
"routePanelThemesMenuItemCreateSubmit": 34,
"routePanelThemesMenuItemDeleteSubmit": 35,
"routePanelThemesMenuItemOrderSubmit": 36,
"routePanelPlugins": 37,
"routePanelPluginsActivate": 38,
"routePanelPluginsDeactivate": 39,
"routePanelPluginsInstall": 40,
"routePanelUsers": 41,
"routePanelUsersEdit": 42,
"routePanelUsersEditSubmit": 43,
"panel.AnalyticsViews": 44,
"panel.AnalyticsRoutes": 45,
"panel.AnalyticsAgents": 46,
"panel.AnalyticsSystems": 47,
"panel.AnalyticsLanguages": 48,
"panel.AnalyticsReferrers": 49,
"panel.AnalyticsRouteViews": 50,
"panel.AnalyticsAgentViews": 51,
"panel.AnalyticsForumViews": 52,
"panel.AnalyticsSystemViews": 53,
"panel.AnalyticsLanguageViews": 54,
"panel.AnalyticsReferrerViews": 55,
"panel.AnalyticsPosts": 56,
"panel.AnalyticsTopics": 57,
"panel.AnalyticsForums": 58,
"routePanelGroups": 59,
"routePanelGroupsEdit": 60,
"routePanelGroupsEditPerms": 61,
"routePanelGroupsEditSubmit": 62,
"routePanelGroupsEditPermsSubmit": 63,
"routePanelGroupsCreateSubmit": 64,
"panel.Backups": 65,
"panel.LogsRegs": 66,
"panel.LogsMod": 67,
"panel.Debug": 68,
"routePanelDashboard": 69,
"routes.AccountEditCritical": 70,
"routes.AccountEditCriticalSubmit": 71,
"routes.AccountEditAvatar": 72,
"routes.AccountEditAvatarSubmit": 73,
"routes.AccountEditUsername": 74,
"routes.AccountEditUsernameSubmit": 75,
"routes.AccountEditEmail": 76,
"routes.AccountEditEmailTokenSubmit": 77,
"routes.ViewProfile": 78,
"routes.BanUserSubmit": 79,
"routes.UnbanUser": 80,
"routes.ActivateUser": 81,
"routes.IPSearch": 82,
"routes.CreateTopicSubmit": 83,
"routes.EditTopicSubmit": 84,
"routes.DeleteTopicSubmit": 85,
"routes.StickTopicSubmit": 86,
"routes.UnstickTopicSubmit": 87,
"routes.LockTopicSubmit": 88,
"routes.UnlockTopicSubmit": 89,
"routes.MoveTopicSubmit": 90,
"routes.LikeTopicSubmit": 91,
"routes.ViewTopic": 92,
"routes.CreateReplySubmit": 93,
"routes.ReplyEditSubmit": 94,
"routes.ReplyDeleteSubmit": 95,
"routes.ReplyLikeSubmit": 96,
"routes.ProfileReplyCreateSubmit": 97,
"routes.ProfileReplyEditSubmit": 98,
"routes.ProfileReplyDeleteSubmit": 99,
"routes.PollVote": 100,
"routes.PollResults": 101,
"routes.AccountLogin": 102,
"routes.AccountRegister": 103,
"routes.AccountLogout": 104,
"routes.AccountLoginSubmit": 105,
"routes.AccountRegisterSubmit": 106,
"routes.DynamicRoute": 107,
"routes.UploadedFile": 108,
"routes.StaticFile": 109,
"routes.RobotsTxt": 110,
"routes.SitemapXml": 111,
"routes.BadRoute": 112,
}
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: "routePanelThemes",
29: "routePanelThemesSetDefault",
30: "routePanelThemesMenus",
31: "routePanelThemesMenusEdit",
32: "routePanelThemesMenuItemEdit",
33: "routePanelThemesMenuItemEditSubmit",
34: "routePanelThemesMenuItemCreateSubmit",
35: "routePanelThemesMenuItemDeleteSubmit",
36: "routePanelThemesMenuItemOrderSubmit",
37: "routePanelPlugins",
38: "routePanelPluginsActivate",
39: "routePanelPluginsDeactivate",
40: "routePanelPluginsInstall",
41: "routePanelUsers",
42: "routePanelUsersEdit",
43: "routePanelUsersEditSubmit",
44: "panel.AnalyticsViews",
45: "panel.AnalyticsRoutes",
46: "panel.AnalyticsAgents",
47: "panel.AnalyticsSystems",
48: "panel.AnalyticsLanguages",
49: "panel.AnalyticsReferrers",
50: "panel.AnalyticsRouteViews",
51: "panel.AnalyticsAgentViews",
52: "panel.AnalyticsForumViews",
53: "panel.AnalyticsSystemViews",
54: "panel.AnalyticsLanguageViews",
55: "panel.AnalyticsReferrerViews",
56: "panel.AnalyticsPosts",
57: "panel.AnalyticsTopics",
58: "panel.AnalyticsForums",
59: "routePanelGroups",
60: "routePanelGroupsEdit",
61: "routePanelGroupsEditPerms",
62: "routePanelGroupsEditSubmit",
63: "routePanelGroupsEditPermsSubmit",
64: "routePanelGroupsCreateSubmit",
65: "panel.Backups",
66: "panel.LogsRegs",
67: "panel.LogsMod",
68: "panel.Debug",
69: "routePanelDashboard",
70: "routes.AccountEditCritical",
71: "routes.AccountEditCriticalSubmit",
72: "routes.AccountEditAvatar",
73: "routes.AccountEditAvatarSubmit",
74: "routes.AccountEditUsername",
75: "routes.AccountEditUsernameSubmit",
76: "routes.AccountEditEmail",
77: "routes.AccountEditEmailTokenSubmit",
78: "routes.ViewProfile",
79: "routes.BanUserSubmit",
80: "routes.UnbanUser",
81: "routes.ActivateUser",
82: "routes.IPSearch",
83: "routes.CreateTopicSubmit",
84: "routes.EditTopicSubmit",
85: "routes.DeleteTopicSubmit",
86: "routes.StickTopicSubmit",
87: "routes.UnstickTopicSubmit",
88: "routes.LockTopicSubmit",
89: "routes.UnlockTopicSubmit",
90: "routes.MoveTopicSubmit",
91: "routes.LikeTopicSubmit",
92: "routes.ViewTopic",
93: "routes.CreateReplySubmit",
94: "routes.ReplyEditSubmit",
95: "routes.ReplyDeleteSubmit",
96: "routes.ReplyLikeSubmit",
97: "routes.ProfileReplyCreateSubmit",
98: "routes.ProfileReplyEditSubmit",
99: "routes.ProfileReplyDeleteSubmit",
100: "routes.PollVote",
101: "routes.PollResults",
102: "routes.AccountLogin",
103: "routes.AccountRegister",
104: "routes.AccountLogout",
105: "routes.AccountLoginSubmit",
106: "routes.AccountRegisterSubmit",
107: "routes.DynamicRoute",
108: "routes.UploadedFile",
109: "routes.StaticFile",
110: "routes.RobotsTxt",
111: "routes.SitemapXml",
112: "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) StripNewlines(data string) string {
// TODO: Strip out all sub-32s?
return strings.Replace(strings.Replace(data,"\n","",-1),"\r","",-1)
}
func (router *GenRouter) DumpRequest(req *http.Request, prepend string) {
var heads string
for key, value := range req.Header {
for _, vvalue := range value {
heads += "Header '" + router.StripNewlines(key) + "': " + router.StripNewlines(vvalue) + "!!\n"
}
}
router.requestLogger.Print(prepend +
"\nUA: " + router.StripNewlines(req.UserAgent()) + "\n" +
"Method: " + router.StripNewlines(req.Method) + "\n" + heads +
"req.Host: " + router.StripNewlines(req.Host) + "\n" +
"req.URL.Path: " + router.StripNewlines(req.URL.Path) + "\n" +
"req.URL.RawQuery: " + router.StripNewlines(req.URL.RawQuery) + "\n" +
"req.Referer(): " + router.StripNewlines(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(109)
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/themes/":
counters.RouteViewCounter.Bump(28)
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(29)
err = routePanelThemesSetDefault(w,req,user,extraData)
case "/panel/themes/menus/":
counters.RouteViewCounter.Bump(30)
err = routePanelThemesMenus(w,req,user)
case "/panel/themes/menus/edit/":
counters.RouteViewCounter.Bump(31)
err = routePanelThemesMenusEdit(w,req,user,extraData)
case "/panel/themes/menus/item/edit/":
counters.RouteViewCounter.Bump(32)
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(33)
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(34)
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(35)
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(36)
err = routePanelThemesMenuItemOrderSubmit(w,req,user,extraData)
case "/panel/plugins/":
counters.RouteViewCounter.Bump(37)
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(38)
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(39)
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(40)
err = routePanelPluginsInstall(w,req,user,extraData)
case "/panel/users/":
counters.RouteViewCounter.Bump(41)
err = routePanelUsers(w,req,user)
case "/panel/users/edit/":
counters.RouteViewCounter.Bump(42)
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(43)
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(44)
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(45)
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(46)
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(47)
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(48)
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(49)
err = panel.AnalyticsReferrers(w,req,user)
case "/panel/analytics/route/":
counters.RouteViewCounter.Bump(50)
err = panel.AnalyticsRouteViews(w,req,user,extraData)
case "/panel/analytics/agent/":
counters.RouteViewCounter.Bump(51)
err = panel.AnalyticsAgentViews(w,req,user,extraData)
case "/panel/analytics/forum/":
counters.RouteViewCounter.Bump(52)
err = panel.AnalyticsForumViews(w,req,user,extraData)
case "/panel/analytics/system/":
counters.RouteViewCounter.Bump(53)
err = panel.AnalyticsSystemViews(w,req,user,extraData)
case "/panel/analytics/lang/":
counters.RouteViewCounter.Bump(54)
err = panel.AnalyticsLanguageViews(w,req,user,extraData)
case "/panel/analytics/referrer/":
counters.RouteViewCounter.Bump(55)
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(56)
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(57)
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(58)
err = panel.AnalyticsForums(w,req,user)
case "/panel/groups/":
counters.RouteViewCounter.Bump(59)
err = routePanelGroups(w,req,user)
case "/panel/groups/edit/":
counters.RouteViewCounter.Bump(60)
err = routePanelGroupsEdit(w,req,user,extraData)
case "/panel/groups/edit/perms/":
counters.RouteViewCounter.Bump(61)
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(62)
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(63)
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(64)
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(65)
err = panel.Backups(w,req,user,extraData)
case "/panel/logs/regs/":
counters.RouteViewCounter.Bump(66)
err = panel.LogsRegs(w,req,user)
case "/panel/logs/mod/":
counters.RouteViewCounter.Bump(67)
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(68)
err = panel.Debug(w,req,user)
default:
counters.RouteViewCounter.Bump(69)
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(70)
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(71)
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(72)
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(73)
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(74)
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(75)
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(76)
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(77)
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
default:
req.URL.Path += extraData
counters.RouteViewCounter.Bump(78)
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(79)
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(80)
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(81)
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(82)
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(83)
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(84)
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(85)
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(86)
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(87)
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(88)
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(89)
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(90)
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(91)
err = routes.LikeTopicSubmit(w,req,user,extraData)
default:
counters.RouteViewCounter.Bump(92)
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(93)
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(94)
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(95)
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(96)
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(97)
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(98)
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(99)
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(100)
err = routes.PollVote(w,req,user,extraData)
case "/poll/results/":
counters.RouteViewCounter.Bump(101)
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(102)
err = routes.AccountLogin(w,req,user)
case "/accounts/create/":
counters.RouteViewCounter.Bump(103)
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(104)
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(105)
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(106)
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(108)
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(110)
err = routes.RobotsTxt(w,req)
if err != nil {
router.handleError(err,w,req,user)
}
return
/*case "sitemap.xml":
counters.RouteViewCounter.Bump(111)
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(107) // 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(112)
common.NotFound(w,req,nil)
}
}