Trying to reduce the amount of UserCheck() boilerplate in the routes.

Reduced the amount of boilerplate in routes with renderTemplate()
Reduced the amount of boilerplate in routes with ParseSEOURL()
Removed some dated commented bits of code.
Used StashConfig in a few more places in the benchmarks to reduce the amount of boilerplate.

Renamed the pre_render_forum_list hook to pre_render_forums.
Renamed the pre_render_topic_list hook to pre_render_topics.
Renamed a few benchmark variables to simplify the code.
This commit is contained in:
Azareal 2018-11-12 19:23:36 +10:00
parent 83dc26aa43
commit 9f273a99f5
21 changed files with 472 additions and 654 deletions

View File

@ -215,9 +215,9 @@ var messageHooks = map[string][]func(Message, PageInt, ...interface{}) interface
var PreRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool{
"pre_render": nil,
"pre_render_forum_list": nil,
"pre_render_forums": nil,
"pre_render_forum": nil,
"pre_render_topic_list": nil,
"pre_render_topics": nil,
"pre_render_topic": nil,
"pre_render_profile": nil,
"pre_render_custom_page": nil,

View File

@ -16,7 +16,7 @@ var PreRoute func(http.ResponseWriter, *http.Request) (User, bool) = preRoute
var PanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*Header, PanelStats, RouteError) = panelUserCheck
var SimplePanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*HeaderLite, RouteError) = simplePanelUserCheck
var SimpleForumUserCheck func(w http.ResponseWriter, r *http.Request, user *User, fid int) (headerLite *HeaderLite, err RouteError) = simpleForumUserCheck
var ForumUserCheck func(w http.ResponseWriter, r *http.Request, user *User, fid int) (header *Header, err RouteError) = forumUserCheck
var ForumUserCheck func(header *Header, w http.ResponseWriter, r *http.Request, user *User, fid int) (err RouteError) = forumUserCheck
var SimpleUserCheck func(w http.ResponseWriter, r *http.Request, user *User) (headerLite *HeaderLite, err RouteError) = simpleUserCheck
var UserCheck func(w http.ResponseWriter, r *http.Request, user *User) (header *Header, err RouteError) = userCheck
@ -45,29 +45,25 @@ func simpleForumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fi
return header, nil
}
func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (header *Header, rerr RouteError) {
header, rerr = UserCheck(w, r, user)
if rerr != nil {
return header, rerr
}
func forumUserCheck(header *Header, w http.ResponseWriter, r *http.Request, user *User, fid int) (rerr RouteError) {
if !Forums.Exists(fid) {
return header, NotFound(w, r, header)
return NotFound(w, r, header)
}
skip, rerr := header.Hooks.VhookSkippable("forum_check_pre_perms", w, r, user, &fid, &header)
if skip || rerr != nil {
return header, rerr
return rerr
}
fperms, err := FPStore.Get(fid, user.Group)
if err == ErrNoRows {
fperms = BlankForumPerms()
} else if err != nil {
return header, InternalError(err, w, r)
return InternalError(err, w, r)
}
cascadeForumPerms(fperms, user)
header.CurrentUser = *user // TODO: Use a pointer instead for CurrentUser, so we don't have to do this
return header, rerr
return rerr
}
// TODO: Put this on the user instance? Do we really want forum specific logic in there? Maybe, a method which spits a new pointer with the same contents as user?
@ -216,21 +212,6 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
}
}
/*pusher, ok := w.(http.Pusher)
if ok {
pusher.Push("/static/"+theme.Name+"/main.css", nil)
pusher.Push("/static/global.js", nil)
pusher.Push("/static/jquery-3.1.1.min.js", nil)
// TODO: Test these
for _, sheet := range header.Stylesheets {
pusher.Push("/static/"+sheet, nil)
}
for _, script := range header.Scripts {
pusher.Push("/static/"+script, nil)
}
// TODO: Push avatars?
}*/
return header, nil
}

View File

@ -200,12 +200,7 @@ func RouteGuildList(w http.ResponseWriter, r *http.Request, user common.User) co
}
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
// SEO URLs...
halves := strings.Split(r.URL.Path[len("/guild/"):], ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
guildID, err := strconv.Atoi(halves[1])
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/"):])
if err != nil {
return common.PreError("Not a valid guild ID", w, r)
}
@ -303,12 +298,7 @@ func RouteMemberList(w http.ResponseWriter, r *http.Request, user common.User) c
return ferr
}
// SEO URLs...
halves := strings.Split(r.URL.Path[len("/guild/members/"):], ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
guildID, err := strconv.Atoi(halves[1])
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/members/"):])
if err != nil {
return common.PreError("Not a valid group ID", w, r)
}

File diff suppressed because it is too large Load Diff

View File

@ -111,8 +111,7 @@ func init() {
// TODO: Swap out LocalError for a panic for this?
func BenchmarkTopicAdminRouteParallel(b *testing.B) {
binit(b)
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
cfg := NewStashConfig()
common.Dev.DebugMode = false
common.Dev.SuperDebug = false
@ -128,27 +127,30 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
topicW := httptest.NewRecorder()
topicReqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
topicReqAdmin.AddCookie(&adminUIDCookie)
topicReqAdmin.AddCookie(&adminSessionCookie)
w := httptest.NewRecorder()
reqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
reqAdmin.AddCookie(&adminUIDCookie)
reqAdmin.AddCookie(&adminSessionCookie)
// Deal with the session stuff, etc.
user, ok := common.PreRoute(topicW, topicReqAdmin)
user, ok := common.PreRoute(w, reqAdmin)
if !ok {
b.Fatal("Mysterious error!")
}
//topicW.Body.Reset()
routes.ViewTopic(topicW, topicReqAdmin, user, "1")
if topicW.Code != 200 {
b.Log(topicW.Body)
head, err := common.UserCheck(w, reqAdmin, &user)
if err != nil {
b.Fatal(err)
}
//w.Body.Reset()
routes.ViewTopic(w, reqAdmin, user, head, "1")
if w.Code != 200 {
b.Log(w.Body)
b.Fatal("HTTP Error!")
}
}
})
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
cfg.Restore()
}
func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
@ -157,8 +159,7 @@ func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
if err != nil {
b.Fatal(err)
}
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
cfg := NewStashConfig()
common.Dev.DebugMode = false
common.Dev.SuperDebug = false
@ -169,29 +170,28 @@ func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
if !admin.IsAdmin {
b.Fatal("UID1 is not an admin")
}
adminUIDCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: common.Year}
adminSessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: common.Year}
uidCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: common.Year}
sessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: common.Year}
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
topicW := httptest.NewRecorder()
topicReqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
topicReqAdmin.AddCookie(&adminUIDCookie)
topicReqAdmin.AddCookie(&adminSessionCookie)
topicReqAdmin.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
topicReqAdmin.Header.Set("Host", "localhost")
topicReqAdmin.Host = "localhost"
//topicW.Body.Reset()
router.ServeHTTP(topicW, topicReqAdmin)
if topicW.Code != 200 {
b.Log(topicW.Body)
w := httptest.NewRecorder()
reqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
reqAdmin.AddCookie(&uidCookie)
reqAdmin.AddCookie(&sessionCookie)
reqAdmin.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
reqAdmin.Header.Set("Host", "localhost")
reqAdmin.Host = "localhost"
//w.Body.Reset()
router.ServeHTTP(w, reqAdmin)
if w.Code != 200 {
b.Log(w.Body)
b.Fatal("HTTP Error!")
}
}
})
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
cfg.Restore()
}
func BenchmarkTopicAdminRouteParallelAlt(b *testing.B) {
@ -208,50 +208,56 @@ func BenchmarkTopicAdminRouteParallelAltAlt(b *testing.B) {
func BenchmarkTopicGuestRouteParallel(b *testing.B) {
binit(b)
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
cfg := NewStashConfig()
common.Dev.DebugMode = false
common.Dev.SuperDebug = false
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
topicW := httptest.NewRecorder()
topicReq := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
//topicW.Body.Reset()
routes.ViewTopic(topicW, topicReq, common.GuestUser, "1")
if topicW.Code != 200 {
b.Log(topicW.Body)
w := httptest.NewRecorder()
req := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
user := common.GuestUser
head, err := common.UserCheck(w, req, &user)
if err != nil {
b.Fatal(err)
}
//w.Body.Reset()
routes.ViewTopic(w, req, user, head, "1")
if w.Code != 200 {
b.Log(w.Body)
b.Fatal("HTTP Error!")
}
}
})
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
cfg.Restore()
}
func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) {
binit(b)
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
cfg := NewStashConfig()
common.Dev.DebugMode = true
common.Dev.SuperDebug = false
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
topicW := httptest.NewRecorder()
topicReq := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
//topicW.Body.Reset()
routes.ViewTopic(topicW, topicReq, common.GuestUser, "1")
if topicW.Code != 200 {
b.Log(topicW.Body)
w := httptest.NewRecorder()
req := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
user := common.GuestUser
head, err := common.UserCheck(w, req, &user)
if err != nil {
b.Fatal(err)
}
//w.Body.Reset()
routes.ViewTopic(w, req, user, head, "1")
if w.Code != 200 {
b.Log(w.Body)
b.Fatal("HTTP Error!")
}
}
})
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
cfg.Restore()
}
func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
@ -260,8 +266,7 @@ func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
if err != nil {
b.Fatal(err)
}
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
cfg := NewStashConfig()
common.Dev.DebugMode = false
common.Dev.SuperDebug = false
@ -273,23 +278,22 @@ func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
topicW := httptest.NewRecorder()
topicReq := httptest.NewRequest("GET", "/topic/hm.1", bytes.NewReader(nil))
topicReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
topicReq.Header.Set("Host", "localhost")
topicReq.Host = "localhost"
//topicW.Body.Reset()
router.ServeHTTP(topicW, topicReq)
if topicW.Code != 200 {
b.Log(topicW.Body)
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/topic/hm.1", bytes.NewReader(nil))
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
req.Header.Set("Host", "localhost")
req.Host = "localhost"
//w.Body.Reset()
router.ServeHTTP(w, req)
if w.Code != 200 {
b.Log(w.Body)
b.Fatal("HTTP Error!")
}
}
})
//defer pprof.StopCPUProfile()
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
cfg.Restore()
}
func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
@ -298,45 +302,42 @@ func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
if err != nil {
b.Fatal(err)
}
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
cfg := NewStashConfig()
common.Dev.DebugMode = false
common.Dev.SuperDebug = false
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
badW := httptest.NewRecorder()
badReq := httptest.NewRequest("GET", "/garble/haa", bytes.NewReader(nil))
badReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
badReq.Header.Set("Host", "localhost")
badReq.Host = "localhost"
router.ServeHTTP(badW, badReq)
w := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/garble/haa", bytes.NewReader(nil))
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
req.Header.Set("Host", "localhost")
req.Host = "localhost"
router.ServeHTTP(w, req)
}
})
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
cfg.Restore()
}
func obRoute(b *testing.B,path string) {
func obRoute(b *testing.B, path string) {
binit(b)
cfg := NewStashConfig()
common.Dev.DebugMode = false
common.Dev.SuperDebug = false
b.RunParallel(benchRoute(b,path))
b.RunParallel(benchRoute(b, path))
cfg.Restore()
}
func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/topics/")
obRoute(b, "/topics/")
}
func BenchmarkForumsGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/forums/")
obRoute(b, "/forums/")
}
func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/forum/general.2")
obRoute(b, "/forum/general.2")
}
func binit(b *testing.B) {
@ -355,7 +356,7 @@ type StashConfig struct {
func NewStashConfig() *StashConfig {
prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug
return &StashConfig{prev,prev2}
return &StashConfig{prev, prev2}
}
func (cfg *StashConfig) Restore() {
@ -385,7 +386,7 @@ func benchRoute(b *testing.B, path string) func(*testing.PB) {
}
func BenchmarkProfileGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/profile/admin.1")
obRoute(b, "/profile/admin.1")
}
// TODO: Make these routes compatible with the changes to the router

View File

@ -247,10 +247,18 @@ func userStoreTest(t *testing.T, newUserID int) {
}
var changeGroupTest2 = func(rank string, firstShouldBe bool, secondShouldBe bool) {
_, ferr := common.ForumUserCheck(dummyResponseRecorder, dummyRequest1, user, reportsForumID)
head, err := common.UserCheck(dummyResponseRecorder, dummyRequest1, user)
if err != nil {
t.Fatal(err)
}
head2, err := common.UserCheck(dummyResponseRecorder, dummyRequest2, user2)
if err != nil {
t.Fatal(err)
}
ferr := common.ForumUserCheck(head, dummyResponseRecorder, dummyRequest1, user, reportsForumID)
expect(t, ferr == nil, "There shouldn't be any errors in forumUserCheck")
expect(t, user.Perms.ViewTopic == firstShouldBe, rank+" should be able to access the reports forum")
_, ferr = common.ForumUserCheck(dummyResponseRecorder, dummyRequest2, user2, generalForumID)
ferr = common.ForumUserCheck(head2, dummyResponseRecorder, dummyRequest2, user2, generalForumID)
expect(t, ferr == nil, "There shouldn't be any errors in forumUserCheck")
expect(t, user2.Perms.ViewTopic == secondShouldBe, "Sam should be able to access the general forum")
}

View File

@ -56,8 +56,7 @@ func main() {
} else {
out += "\n" + indentor + "err = common." + runnable.Contents + "(w,req,user)\n" +
indentor + "if err != nil {\n" +
indentor + "\trouter.handleError(err,w,req,user)\n" +
indentor + "\treturn\n" +
indentor + "\treturn err\n" +
indentor + "}\n" + indentor
}
}
@ -71,6 +70,13 @@ func main() {
out += "\n\t\tcase \"" + route.Path[0:end] + "\":"
out += runBefore(route.RunBefore, 4)
out += "\n\t\t\tcounters.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")"
if !route.Action && !route.NoHead {
out += "\n\t\t\thead, err := common.UserCheck(w,req,&user)"
out += "\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}"
vcpy := route.Vars
route.Vars = []string{"head"}
route.Vars = append(route.Vars, vcpy...)
}
out += "\n\t\t\terr = " + route.Name + "(w,req,user"
for _, item := range route.Vars {
out += "," + item
@ -118,14 +124,20 @@ func main() {
out += `
err = common.` + runnable.Contents + `(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
return err
}
`
}
}
}
out += "\n\t\t\t\t\tcounters.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[route.Name]) + ")"
if !route.Action && !route.NoHead && !group.NoHead {
out += "\n\t\t\t\thead, err := common.UserCheck(w,req,&user)"
out += "\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}"
vcpy := route.Vars
route.Vars = []string{"head"}
route.Vars = append(route.Vars, vcpy...)
}
out += "\n\t\t\t\t\terr = " + route.Name + "(w,req,user"
for _, item := range route.Vars {
out += "," + item
@ -138,6 +150,13 @@ func main() {
out += "\n\t\t\t\tdefault:"
out += runBefore(defaultRoute.RunBefore, 4)
out += "\n\t\t\t\t\tcounters.RouteViewCounter.Bump(" + strconv.Itoa(allRouteMap[defaultRoute.Name]) + ")"
if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead {
out += "\n\t\t\t\t\thead, err := common.UserCheck(w,req,&user)"
out += "\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}"
vcpy := defaultRoute.Vars
defaultRoute.Vars = []string{"head"}
defaultRoute.Vars = append(defaultRoute.Vars, vcpy...)
}
out += "\n\t\t\t\t\terr = " + defaultRoute.Name + "(w,req,user"
for _, item := range defaultRoute.Vars {
out += ", " + item
@ -656,10 +675,15 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}()
w = gzipResponseWriter{Writer: gz, ResponseWriter: w}
}
router.routeSwitch(w, req, user, prefix, extraData)
ferr := router.routeSwitch(w, req, user, prefix, extraData)
if ferr != nil {
router.handleError(ferr,w,req,user)
}
//common.StoppedServer("Profile end")
}
func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user common.User, prefix string, extraData string) {
func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user common.User, prefix string, extraData string) common.RouteError {
var err common.RouteError
switch(prefix) {` + out + `
/*case "/sitemaps": // TODO: Count these views
@ -667,8 +691,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
err = sitemapSwitch(w,req)*/
case "/uploads":
if extraData == "" {
common.NotFound(w,req,nil)
return
return common.NotFound(w,req,nil)
}
gzw, ok := w.(gzipResponseWriter)
if ok {
@ -680,28 +703,19 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this?
router.UploadHandler(w,req) // TODO: Count these views
return
return nil
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({{index .AllRouteMap "routes.RobotsTxt"}})
err = routes.RobotsTxt(w,req)
if err != nil {
router.handleError(err,w,req,user)
}
return
return routes.RobotsTxt(w,req)
/*case "sitemap.xml":
counters.RouteViewCounter.Bump({{index .AllRouteMap "routes.SitemapXml"}})
err = routes.SitemapXml(w,req)
if err != nil {
router.handleError(err,w,req,user)
return routes.SitemapXml(w,req)*/
}
return*/
}
common.NotFound(w,req,nil)
return
return common.NotFound(w,req,nil)
default:
// A fallback for the routes which haven't been converted to the new router yet or plugins
router.RLock()
@ -711,11 +725,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
if ok {
counters.RouteViewCounter.Bump({{index .AllRouteMap "routes.DynamicRoute" }}) // 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
return handle(w,req,user)
}
lowerPath := strings.ToLower(req.URL.Path)
@ -725,12 +735,9 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
router.DumpRequest(req,"Bad Route")
}
counters.RouteViewCounter.Bump({{index .AllRouteMap "routes.BadRoute" }})
common.NotFound(w,req,nil)
return
}
if err != nil {
router.handleError(err,w,req,user)
return common.NotFound(w,req,nil)
}
return err
}
`
var tmpl = template.Must(template.New("router").Parse(fileData))

View File

@ -4,6 +4,8 @@ type RouteGroup struct {
Path string
RouteList []*RouteImpl
RunBefore []Runnable
NoHead bool
}
func newRouteGroup(path string, routes ...*RouteImpl) *RouteGroup {
@ -35,6 +37,11 @@ func inStringList(needle string, list []string) bool {
return false
}
func (group *RouteGroup) NoHeader() *RouteGroup {
group.NoHead = true
return group
}
func (group *RouteGroup) Before(lines ...string) *RouteGroup {
for _, line := range lines {
group.RunBefore = append(group.RunBefore, Runnable{line, false})

View File

@ -5,6 +5,8 @@ import "strings"
type RouteImpl struct {
Name string
Path string
Action bool
NoHead bool
Vars []string
RunBefore []Runnable
@ -70,24 +72,29 @@ func (route *RouteImpl) NoGzip() *RouteImpl {
}`)
}
func (route *RouteImpl) NoHeader() *RouteImpl {
route.NoHead = true
return route
}
func addRouteGroup(routeGroup *RouteGroup) {
routeGroups = append(routeGroups, routeGroup)
}
func blankRoute() *RouteImpl {
return &RouteImpl{"", "", []string{}, []Runnable{}, nil}
return &RouteImpl{"", "", false, false, []string{}, []Runnable{}, nil}
}
func route(fname string, path string, args ...string) *RouteImpl {
return &RouteImpl{fname, path, args, []Runnable{}, nil}
func route(fname string, path string, action bool, special bool, args ...string) *RouteImpl {
return &RouteImpl{fname, path, action, special, args, []Runnable{}, nil}
}
func View(fname string, path string, args ...string) *RouteImpl {
return route(fname, path, args...)
return route(fname, path, false, false, args...)
}
func MemberView(fname string, path string, args ...string) *RouteImpl {
route := route(fname, path, args...)
route := route(fname, path, false, false, args...)
if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly")
}
@ -95,7 +102,7 @@ func MemberView(fname string, path string, args ...string) *RouteImpl {
}
func ModView(fname string, path string, args ...string) *RouteImpl {
route := route(fname, path, args...)
route := route(fname, path, false, false, args...)
if !route.hasBefore("AdminOnly") {
route.Before("SuperModOnly")
}
@ -103,7 +110,7 @@ func ModView(fname string, path string, args ...string) *RouteImpl {
}
func Action(fname string, path string, args ...string) *RouteImpl {
route := route(fname, path, args...)
route := route(fname, path, true, false, args...)
route.Before("NoSessionMismatch")
if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly")
@ -112,11 +119,11 @@ func Action(fname string, path string, args ...string) *RouteImpl {
}
func AnonAction(fname string, path string, args ...string) *RouteImpl {
return route(fname, path, args...).Before("ParseForm")
return route(fname, path, true, false, args...).Before("ParseForm")
}
func Special(fname string, path string, args ...string) *RouteImpl {
return route(fname, path, args...).LitBefore("req.URL.Path += extraData")
return route(fname, path, false, true, args...).LitBefore("req.URL.Path += extraData")
}
// Make this it's own type to force the user to manipulate methods on it to set parameters
@ -125,7 +132,7 @@ type uploadAction struct {
}
func UploadAction(fname string, path string, args ...string) *uploadAction {
route := route(fname, path, args...)
route := route(fname, path, true, false, args...)
if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly")
}
@ -135,8 +142,7 @@ func UploadAction(fname string, path string, args ...string) *uploadAction {
func (action *uploadAction) MaxSizeVar(varName string) *RouteImpl {
action.Route.LitBeforeMultiline(`err = common.HandleUploadRoute(w,req,user,` + varName + `)
if err != nil {
router.handleError(err,w,req,user)
return
return err
}`)
action.Route.Before("NoUploadSessionMismatch")
return action.Route

View File

@ -8,7 +8,7 @@ func routes() {
addRoute(View("routes.ViewForum", "/forum/", "extraData"))
addRoute(AnonAction("routes.ChangeTheme", "/theme/"))
addRoute(
View("routes.ShowAttachment", "/attachs/", "extraData").Before("ParseForm").NoGzip(),
View("routes.ShowAttachment", "/attachs/", "extraData").Before("ParseForm").NoGzip().NoHeader(),
)
apiGroup := newRouteGroup("/api/",
@ -16,7 +16,7 @@ func routes() {
View("routeAPIPhrases", "/api/phrases/"), // TODO: Be careful with exposing the panel phrases here
View("routes.APIMe", "/api/me/"),
View("routeJSAntispam", "/api/watches/"),
)
).NoHeader()
addRouteGroup(apiGroup)
// TODO: Reduce the number of Befores. With a new method, perhaps?
@ -143,7 +143,7 @@ func buildAccountRoutes() {
}
func buildPanelRoutes() {
panelGroup := newRouteGroup("/panel/").Before("SuperModOnly")
panelGroup := newRouteGroup("/panel/").Before("SuperModOnly").NoHeader()
panelGroup.Routes(
View("panel.Dashboard", "/panel/"),
View("panel.Forums", "/panel/forums/"),

View File

@ -21,8 +21,6 @@ import (
// A blank list to fill out that parameter in Page for routes which don't use it
var tList []interface{}
//var nList []string
var successJSONBytes = []byte(`{"success":"1"}`)
// TODO: Refactor this

View File

@ -15,18 +15,14 @@ import (
"strings"
"github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
)
// A blank list to fill out that parameter in Page for routes which don't use it
var tList []interface{}
func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user)
}
@ -133,11 +129,7 @@ func mfaVerifySession(provSession string, signedSession string, uid int) bool {
return subtle.ConstantTimeCompare([]byte(signedSession), []byte(expected)) == 1
}
func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user)
}
@ -186,16 +178,11 @@ func AccountLogout(w http.ResponseWriter, r *http.Request, user common.User) com
return nil
}
func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user)
}
header.Title = phrases.GetTitlePhrase("register")
pi := common.Page{header, tList, nil}
return renderTemplate("register", w, r, header, pi)
}
@ -345,23 +332,15 @@ func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.U
}
// TODO: Figure a way of making this into middleware?
func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request, user *common.User) (*common.Header, common.RouteError) {
header, ferr := common.UserCheck(w, r, user)
if ferr != nil {
return nil, ferr
}
func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request, user *common.User, header *common.Header) {
header.Title = phrases.GetTitlePhrase(titlePhrase)
header.Path = "/user/edit/"
header.AddSheet(header.Theme.Name + "/account.css")
header.AddScript("account.js")
return header, nil
}
func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := accountEditHead("account", w, r, &user)
if ferr != nil {
return ferr
}
func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
accountEditHead("account", w, r, &user, header)
if r.FormValue("avatar_updated") == "1" {
header.AddNotice("account_avatar_updated")
@ -391,12 +370,8 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) commo
}
//edit_password
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := accountEditHead("account_password", w, r, &user)
if ferr != nil {
return ferr
}
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
accountEditHead("account_password", w, r, &user, header)
pi := common.Page{header, tList, nil}
return renderTemplate("account_own_edit_password", w, r, header, pi)
}
@ -540,11 +515,8 @@ func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user comm
return nil
}
func AccountEditMFA(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := accountEditHead("account_mfa", w, r, &user)
if ferr != nil {
return ferr
}
func AccountEditMFA(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
accountEditHead("account_mfa", w, r, &user, header)
mfaItem, err := common.MFAstore.Get(user.ID)
if err != sql.ErrNoRows && err != nil {
@ -565,11 +537,8 @@ func AccountEditMFA(w http.ResponseWriter, r *http.Request, user common.User) co
}
// If not setup, generate a string, otherwise give an option to disable mfa given the right code
func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := accountEditHead("account_mfa_setup", w, r, &user)
if ferr != nil {
return ferr
}
func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
accountEditHead("account_mfa_setup", w, r, &user, header)
// Flash an error if mfa is already setup
_, err := common.MFAstore.Get(user.ID)
@ -657,11 +626,8 @@ func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, user co
return nil
}
func AccountEditEmail(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := accountEditHead("account_email", w, r, &user)
if ferr != nil {
return ferr
}
func AccountEditEmail(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
accountEditHead("account_email", w, r, &user, header)
emails, err := common.Emails.GetEmailsByUser(&user)
if err != nil {
return common.InternalError(err, w, r)
@ -733,11 +699,7 @@ func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user co
return nil
}
func LevelList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func LevelList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header.Title = phrases.GetTitlePhrase("account_level_list")
var fScores = common.GetLevels(20)

View File

@ -2,12 +2,23 @@ package routes
import (
"net/http"
"strconv"
"strings"
"github.com/Azareal/Gosora/common"
)
var successJSONBytes = []byte(`{"success":"1"}`)
func ParseSEOURL(urlBit string) (slug string, id int, err error) {
halves := strings.Split(urlBit, ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
tid, err := strconv.Atoi(halves[1])
return halves[0], tid, err
}
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *common.Header, pi interface{}) common.RouteError {
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
return nil

View File

@ -4,10 +4,10 @@ import (
"database/sql"
"net/http"
"strconv"
"strings"
"github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen"
)
@ -27,20 +27,14 @@ func init() {
})
}
func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError {
func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, sfid string) common.RouteError {
page, _ := strconv.Atoi(r.FormValue("page"))
// SEO URLs...
halves := strings.Split(sfid, ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
fid, err := strconv.Atoi(halves[1])
_, fid, err := ParseSEOURL(sfid)
if err != nil {
return common.PreError("The provided ForumID is not a valid number.", w, r)
return common.PreError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r)
}
header, ferr := common.ForumUserCheck(w, r, &user, fid)
ferr := common.ForumUserCheck(header, w, r, &user, fid)
if ferr != nil {
return ferr
}
@ -114,13 +108,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, sfid st
pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
pi := common.ForumPage{header, topicList, forum, common.Paginator{pageList, page, lastPage}}
if common.RunPreRenderHook("pre_render_forum", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "forum", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
ferr = renderTemplate("forum", w, r, header, pi)
counters.ForumViewCounter.Bump(forum.ID)
return nil
return ferr
}

View File

@ -8,11 +8,7 @@ import (
"github.com/Azareal/Gosora/common/phrases"
)
func ForumList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func ForumList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header.Title = phrases.GetTitlePhrase("forums")
header.Zone = "forums"
header.Path = "/forums/"
@ -54,12 +50,5 @@ func ForumList(w http.ResponseWriter, r *http.Request, user common.User) common.
}
pi := common.ForumsPage{header, forumList}
if common.RunPreRenderHook("pre_render_forum_list", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "forums", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
return renderTemplate("forums", w, r, header, pi)
}

View File

@ -49,46 +49,21 @@ func StaticFile(w http.ResponseWriter, r *http.Request) {
// Other options instead of io.Copy: io.CopyN(), w.Write(), http.ServeContent()
}
func Overview(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func Overview(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header.Title = phrases.GetTitlePhrase("overview")
header.Zone = "overview"
pi := common.Page{header, tList, nil}
if common.RunPreRenderHook("pre_render_overview", w, r, &user, &pi) {
return nil
}
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
return renderTemplate("overview", w, r, header, pi)
}
func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name string) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = phrases.GetTitlePhrase("page")
func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, name string) common.RouteError {
header.Zone = "custom_page"
name = common.SanitiseSingleLine(name)
page, err := common.Pages.GetByName(name)
if err == nil {
header.Title = page.Title
pi := common.CustomPagePage{header, page}
if common.RunPreRenderHook("pre_render_custom_page", w, r, &user, &pi) {
return nil
}
err := common.RunThemeTemplate(header.Theme.Name, "custom_page", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
return renderTemplate("custom_page", w, r, header, pi)
} else if err != sql.ErrNoRows {
return common.InternalError(err, w, r)
}
@ -98,12 +73,12 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name s
return common.NotFound(w, r, header)
}
header.Title = phrases.GetTitlePhrase("page")
pi := common.Page{header, tList, nil}
// TODO: Pass the page name to the pre-render hook?
if common.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) {
return nil
}
err = common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
if err != nil {
return common.InternalError(err, w, r)
@ -130,8 +105,6 @@ func init() {
func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, filename string) common.RouteError {
filename = common.Stripslashes(filename)
var ext = filepath.Ext("./attachs/" + filename)
//log.Print("ext ", ext)
//log.Print("filename ", filename)
if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
return common.LocalError("Bad extension", w, r, user)
}

View File

@ -7,13 +7,8 @@ import (
"github.com/Azareal/Gosora/common/phrases"
)
func IPSearch(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func IPSearch(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header.Title = phrases.GetTitlePhrase("ip_search")
// TODO: How should we handle the permissions if we extend this into an alt detector of sorts?
if !user.Perms.ViewIPs {
return common.NoPermissions(w, r, user)

View File

@ -3,7 +3,6 @@ package routes
import (
"database/sql"
"errors"
"log"
"net/http"
"strconv"
@ -69,7 +68,7 @@ func PollVote(w http.ResponseWriter, r *http.Request, user common.User, sPollID
}
func PollResults(w http.ResponseWriter, r *http.Request, user common.User, sPollID string) common.RouteError {
log.Print("in PollResults")
//log.Print("in PollResults")
pollID, err := strconv.Atoi(sPollID)
if err != nil {
return common.PreError("The provided PollID is not a valid number.", w, r)

View File

@ -3,7 +3,6 @@ package routes
import (
"database/sql"
"net/http"
"strconv"
"strings"
"time"
@ -29,11 +28,7 @@ func init() {
}
// TODO: Remove the View part of the name?
func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
// TODO: Preload this?
header.AddSheet(header.Theme.Name + "/profile.css")
@ -43,13 +38,8 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) commo
var rid, replyCreatedBy, replyLastEdit, replyLastEditBy, replyLines, replyGroup int
var replyList []common.ReplyUser
// SEO URLs...
// TODO: Do a 301 if it's the wrong username? Do a canonical too?
halves := strings.Split(r.URL.Path[len("/user/"):], ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
pid, err := strconv.Atoi(halves[1])
_, pid, err := ParseSEOURL(r.URL.Path[len("/user/"):])
if err != nil {
return common.LocalError("The provided UserID is not a valid number.", w, r, user)
}
@ -125,13 +115,5 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) commo
nextScore := common.GetLevelScore(puser.Level+1) - prevScore
ppage := common.ProfilePage{header, replyList, *puser, currentScore, nextScore}
if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) {
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "profile", ppage, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
return renderTemplate("profile", w, r, header, ppage)
}

View File

@ -37,17 +37,9 @@ func init() {
})
}
func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit string) common.RouteError {
func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, urlBit string) common.RouteError {
page, _ := strconv.Atoi(r.FormValue("page"))
// SEO URLs...
// TODO: Make a shared function for this
halves := strings.Split(urlBit, ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
tid, err := strconv.Atoi(halves[1])
_, tid, err := ParseSEOURL(urlBit)
if err != nil {
return common.PreError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r)
}
@ -61,7 +53,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
}
topic.ClassName = ""
header, ferr := common.ForumUserCheck(w, r, &user, topic.ParentID)
ferr := common.ForumUserCheck(header, w, r, &user, topic.ParentID)
if ferr != nil {
return ferr
}
@ -163,22 +155,22 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
if replyItem.ActionType != "" {
switch replyItem.ActionType {
case "lock":
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_lock",replyItem.UserLink,replyItem.CreatedByName)
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_lock", replyItem.UserLink, replyItem.CreatedByName)
replyItem.ActionIcon = "&#x1F512;&#xFE0E"
case "unlock":
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_unlock",replyItem.UserLink,replyItem.CreatedByName)
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_unlock", replyItem.UserLink, replyItem.CreatedByName)
replyItem.ActionIcon = "&#x1F513;&#xFE0E"
case "stick":
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_stick",replyItem.UserLink,replyItem.CreatedByName)
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_stick", replyItem.UserLink, replyItem.CreatedByName)
replyItem.ActionIcon = "&#x1F4CC;&#xFE0E"
case "unstick":
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_unstick",replyItem.UserLink,replyItem.CreatedByName)
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_unstick", replyItem.UserLink, replyItem.CreatedByName)
replyItem.ActionIcon = "&#x1F4CC;&#xFE0E"
case "move":
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_move",replyItem.UserLink,replyItem.CreatedByName)
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_move", replyItem.UserLink, replyItem.CreatedByName)
// TODO: Only fire this off if a corresponding phrase for the ActionType doesn't exist? Or maybe have some sort of action registry?
default:
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_default",replyItem.ActionType)
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_default", replyItem.ActionType)
replyItem.ActionIcon = ""
}
}
@ -232,7 +224,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
// ? - Log username changes and put restrictions on this?
// TODO: Test this
// TODO: Revamp this route
func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError {
func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, sfid string) common.RouteError {
var fid int
var err error
if sfid != "" {
@ -245,7 +237,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid
fid = common.Config.DefaultForum
}
header, ferr := common.ForumUserCheck(w, r, &user, fid)
ferr := common.ForumUserCheck(header, w, r, &user, fid)
if ferr != nil {
return ferr
}
@ -593,20 +585,20 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User)
}
func StickTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError {
topic,rerr := topicActionPre(stid,"pin",w,r,user)
topic, rerr := topicActionPre(stid, "pin", w, r, user)
if rerr != nil {
return rerr
}
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
return common.NoPermissions(w, r, user)
}
return topicActionPost(topic.Stick(),"stick",w,r,topic,user)
return topicActionPost(topic.Stick(), "stick", w, r, topic, user)
}
func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.Request, user common.User) (*common.Topic, common.RouteError) {
tid, err := strconv.Atoi(stid)
if err != nil {
return nil,common.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
return nil, common.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
}
topic, err := common.Topics.Get(tid)
@ -625,7 +617,7 @@ func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.R
return topic, nil
}
func topicActionPost(err error, action string,w http.ResponseWriter, r *http.Request, topic *common.Topic, user common.User) common.RouteError {
func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Request, topic *common.Topic, user common.User) common.RouteError {
if err != nil {
return common.InternalError(err, w, r)
}
@ -638,14 +630,14 @@ func topicActionPost(err error, action string,w http.ResponseWriter, r *http.Req
}
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError {
topic,rerr := topicActionPre(stid,"unpin",w,r,user)
topic, rerr := topicActionPre(stid, "unpin", w, r, user)
if rerr != nil {
return rerr
}
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
return common.NoPermissions(w, r, user)
}
return topicActionPost(topic.Unstick(),"unstick",w,r,topic,user)
return topicActionPost(topic.Unstick(), "unstick", w, r, topic, user)
}
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
@ -707,14 +699,14 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User) c
}
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, user common.User, stid string) common.RouteError {
topic,rerr := topicActionPre(stid,"unlock",w,r,user)
topic, rerr := topicActionPre(stid, "unlock", w, r, user)
if rerr != nil {
return rerr
}
if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
return common.NoPermissions(w, r, user)
}
return topicActionPost(topic.Unlock(),"unlock",w,r,topic,user)
return topicActionPost(topic.Unlock(), "unlock", w, r, topic, user)
}
// ! JS only route

View File

@ -9,11 +9,7 @@ import (
"github.com/Azareal/Gosora/common/phrases"
)
func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func TopicList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header.Title = phrases.GetTitlePhrase("topics")
header.Zone = "topics"
header.Path = "/topics/"
@ -47,21 +43,10 @@ func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.
}
pi := common.TopicListPage{header, topicList, forumList, common.Config.DefaultForum, common.TopicListSort{"lastupdated", false}, paginator}
if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "topics", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
return renderTemplate("topics", w, r, header, pi)
}
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header.Title = phrases.GetTitlePhrase("topics")
header.Zone = "topics"
header.Path = "/topics/"
@ -95,12 +80,5 @@ func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.Use
}
pi := common.TopicListPage{header, topicList, forumList, common.Config.DefaultForum, common.TopicListSort{"mostviewed", false}, paginator}
if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "topics", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
return renderTemplate("topics", w, r, header, pi)
}