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{ var PreRenderHooks = map[string][]func(http.ResponseWriter, *http.Request, *User, interface{}) bool{
"pre_render": nil, "pre_render": nil,
"pre_render_forum_list": nil, "pre_render_forums": nil,
"pre_render_forum": nil, "pre_render_forum": nil,
"pre_render_topic_list": nil, "pre_render_topics": nil,
"pre_render_topic": nil, "pre_render_topic": nil,
"pre_render_profile": nil, "pre_render_profile": nil,
"pre_render_custom_page": 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 PanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*Header, PanelStats, RouteError) = panelUserCheck
var SimplePanelUserCheck func(http.ResponseWriter, *http.Request, *User) (*HeaderLite, RouteError) = simplePanelUserCheck 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 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 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 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 return header, nil
} }
func forumUserCheck(w http.ResponseWriter, r *http.Request, user *User, fid int) (header *Header, rerr RouteError) { func forumUserCheck(header *Header, w http.ResponseWriter, r *http.Request, user *User, fid int) (rerr RouteError) {
header, rerr = UserCheck(w, r, user)
if rerr != nil {
return header, rerr
}
if !Forums.Exists(fid) { 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) skip, rerr := header.Hooks.VhookSkippable("forum_check_pre_perms", w, r, user, &fid, &header)
if skip || rerr != nil { if skip || rerr != nil {
return header, rerr return rerr
} }
fperms, err := FPStore.Get(fid, user.Group) fperms, err := FPStore.Get(fid, user.Group)
if err == ErrNoRows { if err == ErrNoRows {
fperms = BlankForumPerms() fperms = BlankForumPerms()
} else if err != nil { } else if err != nil {
return header, InternalError(err, w, r) return InternalError(err, w, r)
} }
cascadeForumPerms(fperms, user) cascadeForumPerms(fperms, user)
header.CurrentUser = *user // TODO: Use a pointer instead for CurrentUser, so we don't have to do this 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? // 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 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 { func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
// SEO URLs... _, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/"):])
halves := strings.Split(r.URL.Path[len("/guild/"):], ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
guildID, err := strconv.Atoi(halves[1])
if err != nil { if err != nil {
return common.PreError("Not a valid guild ID", w, r) 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 return ferr
} }
// SEO URLs... _, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/members/"):])
halves := strings.Split(r.URL.Path[len("/guild/members/"):], ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
guildID, err := strconv.Atoi(halves[1])
if err != nil { if err != nil {
return common.PreError("Not a valid group ID", w, r) 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? // TODO: Swap out LocalError for a panic for this?
func BenchmarkTopicAdminRouteParallel(b *testing.B) { func BenchmarkTopicAdminRouteParallel(b *testing.B) {
binit(b) binit(b)
prev := common.Dev.DebugMode cfg := NewStashConfig()
prev2 := common.Dev.SuperDebug
common.Dev.DebugMode = false common.Dev.DebugMode = false
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
@ -128,27 +127,30 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
topicW := httptest.NewRecorder() w := httptest.NewRecorder()
topicReqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil)) reqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
topicReqAdmin.AddCookie(&adminUIDCookie) reqAdmin.AddCookie(&adminUIDCookie)
topicReqAdmin.AddCookie(&adminSessionCookie) reqAdmin.AddCookie(&adminSessionCookie)
// Deal with the session stuff, etc. // Deal with the session stuff, etc.
user, ok := common.PreRoute(topicW, topicReqAdmin) user, ok := common.PreRoute(w, reqAdmin)
if !ok { if !ok {
b.Fatal("Mysterious error!") b.Fatal("Mysterious error!")
} }
//topicW.Body.Reset() head, err := common.UserCheck(w, reqAdmin, &user)
routes.ViewTopic(topicW, topicReqAdmin, user, "1") if err != nil {
if topicW.Code != 200 { b.Fatal(err)
b.Log(topicW.Body) }
//w.Body.Reset()
routes.ViewTopic(w, reqAdmin, user, head, "1")
if w.Code != 200 {
b.Log(w.Body)
b.Fatal("HTTP Error!") b.Fatal("HTTP Error!")
} }
} }
}) })
common.Dev.DebugMode = prev cfg.Restore()
common.Dev.SuperDebug = prev2
} }
func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) { func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
@ -157,8 +159,7 @@ func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
prev := common.Dev.DebugMode cfg := NewStashConfig()
prev2 := common.Dev.SuperDebug
common.Dev.DebugMode = false common.Dev.DebugMode = false
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
@ -169,29 +170,28 @@ func BenchmarkTopicAdminRouteParallelWithRouter(b *testing.B) {
if !admin.IsAdmin { if !admin.IsAdmin {
b.Fatal("UID1 is not an admin") b.Fatal("UID1 is not an admin")
} }
adminUIDCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: common.Year} uidCookie := http.Cookie{Name: "uid", Value: "1", Path: "/", MaxAge: common.Year}
adminSessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: common.Year} sessionCookie := http.Cookie{Name: "session", Value: admin.Session, Path: "/", MaxAge: common.Year}
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
topicW := httptest.NewRecorder() w := httptest.NewRecorder()
topicReqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil)) reqAdmin := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
topicReqAdmin.AddCookie(&adminUIDCookie) reqAdmin.AddCookie(&uidCookie)
topicReqAdmin.AddCookie(&adminSessionCookie) reqAdmin.AddCookie(&sessionCookie)
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") 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")
topicReqAdmin.Header.Set("Host", "localhost") reqAdmin.Header.Set("Host", "localhost")
topicReqAdmin.Host = "localhost" reqAdmin.Host = "localhost"
//topicW.Body.Reset() //w.Body.Reset()
router.ServeHTTP(topicW, topicReqAdmin) router.ServeHTTP(w, reqAdmin)
if topicW.Code != 200 { if w.Code != 200 {
b.Log(topicW.Body) b.Log(w.Body)
b.Fatal("HTTP Error!") b.Fatal("HTTP Error!")
} }
} }
}) })
common.Dev.DebugMode = prev cfg.Restore()
common.Dev.SuperDebug = prev2
} }
func BenchmarkTopicAdminRouteParallelAlt(b *testing.B) { func BenchmarkTopicAdminRouteParallelAlt(b *testing.B) {
@ -208,50 +208,56 @@ func BenchmarkTopicAdminRouteParallelAltAlt(b *testing.B) {
func BenchmarkTopicGuestRouteParallel(b *testing.B) { func BenchmarkTopicGuestRouteParallel(b *testing.B) {
binit(b) binit(b)
prev := common.Dev.DebugMode cfg := NewStashConfig()
prev2 := common.Dev.SuperDebug
common.Dev.DebugMode = false common.Dev.DebugMode = false
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
topicW := httptest.NewRecorder() w := httptest.NewRecorder()
topicReq := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil)) req := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
//topicW.Body.Reset() user := common.GuestUser
routes.ViewTopic(topicW, topicReq, common.GuestUser, "1")
if topicW.Code != 200 { head, err := common.UserCheck(w, req, &user)
b.Log(topicW.Body) 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!") b.Fatal("HTTP Error!")
} }
} }
}) })
cfg.Restore()
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
} }
func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) { func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) {
binit(b) binit(b)
prev := common.Dev.DebugMode cfg := NewStashConfig()
prev2 := common.Dev.SuperDebug
common.Dev.DebugMode = true common.Dev.DebugMode = true
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
topicW := httptest.NewRecorder() w := httptest.NewRecorder()
topicReq := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil)) req := httptest.NewRequest("get", "/topic/hm.1", bytes.NewReader(nil))
//topicW.Body.Reset() user := common.GuestUser
routes.ViewTopic(topicW, topicReq, common.GuestUser, "1")
if topicW.Code != 200 { head, err := common.UserCheck(w, req, &user)
b.Log(topicW.Body) 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!") b.Fatal("HTTP Error!")
} }
} }
}) })
cfg.Restore()
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
} }
func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) { func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
@ -260,8 +266,7 @@ func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
prev := common.Dev.DebugMode cfg := NewStashConfig()
prev2 := common.Dev.SuperDebug
common.Dev.DebugMode = false common.Dev.DebugMode = false
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
@ -273,23 +278,22 @@ func BenchmarkTopicGuestRouteParallelWithRouter(b *testing.B) {
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
topicW := httptest.NewRecorder() w := httptest.NewRecorder()
topicReq := httptest.NewRequest("GET", "/topic/hm.1", bytes.NewReader(nil)) req := 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") 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")
topicReq.Header.Set("Host", "localhost") req.Header.Set("Host", "localhost")
topicReq.Host = "localhost" req.Host = "localhost"
//topicW.Body.Reset() //w.Body.Reset()
router.ServeHTTP(topicW, topicReq) router.ServeHTTP(w, req)
if topicW.Code != 200 { if w.Code != 200 {
b.Log(topicW.Body) b.Log(w.Body)
b.Fatal("HTTP Error!") b.Fatal("HTTP Error!")
} }
} }
}) })
//defer pprof.StopCPUProfile() //defer pprof.StopCPUProfile()
common.Dev.DebugMode = prev cfg.Restore()
common.Dev.SuperDebug = prev2
} }
func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) { func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
@ -298,45 +302,42 @@ func BenchmarkBadRouteGuestRouteParallelWithRouter(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
prev := common.Dev.DebugMode cfg := NewStashConfig()
prev2 := common.Dev.SuperDebug
common.Dev.DebugMode = false common.Dev.DebugMode = false
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
b.RunParallel(func(pb *testing.PB) { b.RunParallel(func(pb *testing.PB) {
for pb.Next() { for pb.Next() {
badW := httptest.NewRecorder() w := httptest.NewRecorder()
badReq := httptest.NewRequest("GET", "/garble/haa", bytes.NewReader(nil)) req := 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") 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")
badReq.Header.Set("Host", "localhost") req.Header.Set("Host", "localhost")
badReq.Host = "localhost" req.Host = "localhost"
router.ServeHTTP(badW, badReq) router.ServeHTTP(w, req)
} }
}) })
cfg.Restore()
common.Dev.DebugMode = prev
common.Dev.SuperDebug = prev2
} }
func obRoute(b *testing.B,path string) { func obRoute(b *testing.B, path string) {
binit(b) binit(b)
cfg := NewStashConfig() cfg := NewStashConfig()
common.Dev.DebugMode = false common.Dev.DebugMode = false
common.Dev.SuperDebug = false common.Dev.SuperDebug = false
b.RunParallel(benchRoute(b,path)) b.RunParallel(benchRoute(b, path))
cfg.Restore() cfg.Restore()
} }
func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) { func BenchmarkTopicsGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/topics/") obRoute(b, "/topics/")
} }
func BenchmarkForumsGuestRouteParallelWithRouter(b *testing.B) { func BenchmarkForumsGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/forums/") obRoute(b, "/forums/")
} }
func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) { func BenchmarkForumGuestRouteParallelWithRouter(b *testing.B) {
obRoute(b,"/forum/general.2") obRoute(b, "/forum/general.2")
} }
func binit(b *testing.B) { func binit(b *testing.B) {
@ -355,7 +356,7 @@ type StashConfig struct {
func NewStashConfig() *StashConfig { func NewStashConfig() *StashConfig {
prev := common.Dev.DebugMode prev := common.Dev.DebugMode
prev2 := common.Dev.SuperDebug prev2 := common.Dev.SuperDebug
return &StashConfig{prev,prev2} return &StashConfig{prev, prev2}
} }
func (cfg *StashConfig) Restore() { func (cfg *StashConfig) Restore() {
@ -385,7 +386,7 @@ func benchRoute(b *testing.B, path string) func(*testing.PB) {
} }
func BenchmarkProfileGuestRouteParallelWithRouter(b *testing.B) { 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 // 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) { 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, 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") 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, 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") expect(t, user2.Perms.ViewTopic == secondShouldBe, "Sam should be able to access the general forum")
} }

View File

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

View File

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

View File

@ -5,6 +5,8 @@ import "strings"
type RouteImpl struct { type RouteImpl struct {
Name string Name string
Path string Path string
Action bool
NoHead bool
Vars []string Vars []string
RunBefore []Runnable 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) { func addRouteGroup(routeGroup *RouteGroup) {
routeGroups = append(routeGroups, routeGroup) routeGroups = append(routeGroups, routeGroup)
} }
func blankRoute() *RouteImpl { func blankRoute() *RouteImpl {
return &RouteImpl{"", "", []string{}, []Runnable{}, nil} return &RouteImpl{"", "", false, false, []string{}, []Runnable{}, nil}
} }
func route(fname string, path string, args ...string) *RouteImpl { func route(fname string, path string, action bool, special bool, args ...string) *RouteImpl {
return &RouteImpl{fname, path, args, []Runnable{}, nil} return &RouteImpl{fname, path, action, special, args, []Runnable{}, nil}
} }
func View(fname string, path string, args ...string) *RouteImpl { 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 { 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") { if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly") 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 { 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") { if !route.hasBefore("AdminOnly") {
route.Before("SuperModOnly") 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 { func Action(fname string, path string, args ...string) *RouteImpl {
route := route(fname, path, args...) route := route(fname, path, true, false, args...)
route.Before("NoSessionMismatch") route.Before("NoSessionMismatch")
if !route.hasBefore("SuperModOnly", "AdminOnly") { if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly") 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 { 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 { 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 // 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 { 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") { if !route.hasBefore("SuperModOnly", "AdminOnly") {
route.Before("MemberOnly") route.Before("MemberOnly")
} }
@ -135,8 +142,7 @@ func UploadAction(fname string, path string, args ...string) *uploadAction {
func (action *uploadAction) MaxSizeVar(varName string) *RouteImpl { func (action *uploadAction) MaxSizeVar(varName string) *RouteImpl {
action.Route.LitBeforeMultiline(`err = common.HandleUploadRoute(w,req,user,` + varName + `) action.Route.LitBeforeMultiline(`err = common.HandleUploadRoute(w,req,user,` + varName + `)
if err != nil { if err != nil {
router.handleError(err,w,req,user) return err
return
}`) }`)
action.Route.Before("NoUploadSessionMismatch") action.Route.Before("NoUploadSessionMismatch")
return action.Route return action.Route

View File

@ -8,7 +8,7 @@ func routes() {
addRoute(View("routes.ViewForum", "/forum/", "extraData")) addRoute(View("routes.ViewForum", "/forum/", "extraData"))
addRoute(AnonAction("routes.ChangeTheme", "/theme/")) addRoute(AnonAction("routes.ChangeTheme", "/theme/"))
addRoute( addRoute(
View("routes.ShowAttachment", "/attachs/", "extraData").Before("ParseForm").NoGzip(), View("routes.ShowAttachment", "/attachs/", "extraData").Before("ParseForm").NoGzip().NoHeader(),
) )
apiGroup := newRouteGroup("/api/", apiGroup := newRouteGroup("/api/",
@ -16,7 +16,7 @@ func routes() {
View("routeAPIPhrases", "/api/phrases/"), // TODO: Be careful with exposing the panel phrases here View("routeAPIPhrases", "/api/phrases/"), // TODO: Be careful with exposing the panel phrases here
View("routes.APIMe", "/api/me/"), View("routes.APIMe", "/api/me/"),
View("routeJSAntispam", "/api/watches/"), View("routeJSAntispam", "/api/watches/"),
) ).NoHeader()
addRouteGroup(apiGroup) addRouteGroup(apiGroup)
// TODO: Reduce the number of Befores. With a new method, perhaps? // TODO: Reduce the number of Befores. With a new method, perhaps?
@ -143,7 +143,7 @@ func buildAccountRoutes() {
} }
func buildPanelRoutes() { func buildPanelRoutes() {
panelGroup := newRouteGroup("/panel/").Before("SuperModOnly") panelGroup := newRouteGroup("/panel/").Before("SuperModOnly").NoHeader()
panelGroup.Routes( panelGroup.Routes(
View("panel.Dashboard", "/panel/"), View("panel.Dashboard", "/panel/"),
View("panel.Forums", "/panel/forums/"), 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 // A blank list to fill out that parameter in Page for routes which don't use it
var tList []interface{} var tList []interface{}
//var nList []string
var successJSONBytes = []byte(`{"success":"1"}`) var successJSONBytes = []byte(`{"success":"1"}`)
// TODO: Refactor this // TODO: Refactor this

View File

@ -15,18 +15,14 @@ import (
"strings" "strings"
"github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen"
"github.com/Azareal/Gosora/common/phrases" "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 // A blank list to fill out that parameter in Page for routes which don't use it
var tList []interface{} var tList []interface{}
func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountLogin(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
if user.Loggedin { if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user) 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 return subtle.ConstantTimeCompare([]byte(signedSession), []byte(expected)) == 1
} }
func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
if user.Loggedin { if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user) 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 return nil
} }
func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountRegister(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
if user.Loggedin { if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user) return common.LocalError("You're already logged in.", w, r, user)
} }
header.Title = phrases.GetTitlePhrase("register") header.Title = phrases.GetTitlePhrase("register")
pi := common.Page{header, tList, nil} pi := common.Page{header, tList, nil}
return renderTemplate("register", w, r, header, pi) 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? // 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) { func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request, user *common.User, header *common.Header) {
header, ferr := common.UserCheck(w, r, user)
if ferr != nil {
return nil, ferr
}
header.Title = phrases.GetTitlePhrase(titlePhrase) header.Title = phrases.GetTitlePhrase(titlePhrase)
header.Path = "/user/edit/" header.Path = "/user/edit/"
header.AddSheet(header.Theme.Name + "/account.css") header.AddSheet(header.Theme.Name + "/account.css")
header.AddScript("account.js") header.AddScript("account.js")
return header, nil
} }
func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := accountEditHead("account", w, r, &user) accountEditHead("account", w, r, &user, header)
if ferr != nil {
return ferr
}
if r.FormValue("avatar_updated") == "1" { if r.FormValue("avatar_updated") == "1" {
header.AddNotice("account_avatar_updated") header.AddNotice("account_avatar_updated")
@ -391,12 +370,8 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) commo
} }
//edit_password //edit_password
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountEditPassword(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := accountEditHead("account_password", w, r, &user) accountEditHead("account_password", w, r, &user, header)
if ferr != nil {
return ferr
}
pi := common.Page{header, tList, nil} pi := common.Page{header, tList, nil}
return renderTemplate("account_own_edit_password", w, r, header, pi) 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 return nil
} }
func AccountEditMFA(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountEditMFA(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := accountEditHead("account_mfa", w, r, &user) accountEditHead("account_mfa", w, r, &user, header)
if ferr != nil {
return ferr
}
mfaItem, err := common.MFAstore.Get(user.ID) mfaItem, err := common.MFAstore.Get(user.ID)
if err != sql.ErrNoRows && err != nil { 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 // 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 { func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := accountEditHead("account_mfa_setup", w, r, &user) accountEditHead("account_mfa_setup", w, r, &user, header)
if ferr != nil {
return ferr
}
// Flash an error if mfa is already setup // Flash an error if mfa is already setup
_, err := common.MFAstore.Get(user.ID) _, err := common.MFAstore.Get(user.ID)
@ -657,11 +626,8 @@ func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, user co
return nil return nil
} }
func AccountEditEmail(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func AccountEditEmail(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := accountEditHead("account_email", w, r, &user) accountEditHead("account_email", w, r, &user, header)
if ferr != nil {
return ferr
}
emails, err := common.Emails.GetEmailsByUser(&user) emails, err := common.Emails.GetEmailsByUser(&user)
if err != nil { if err != nil {
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
@ -733,11 +699,7 @@ func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user co
return nil return nil
} }
func LevelList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func LevelList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = phrases.GetTitlePhrase("account_level_list") header.Title = phrases.GetTitlePhrase("account_level_list")
var fScores = common.GetLevels(20) var fScores = common.GetLevels(20)

View File

@ -2,12 +2,23 @@ package routes
import ( import (
"net/http" "net/http"
"strconv"
"strings"
"github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common"
) )
var successJSONBytes = []byte(`{"success":"1"}`) 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 { 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) { if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) {
return nil return nil

View File

@ -4,10 +4,10 @@ import (
"database/sql" "database/sql"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters" "github.com/Azareal/Gosora/common/counters"
"github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen" "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")) page, _ := strconv.Atoi(r.FormValue("page"))
_, fid, err := ParseSEOURL(sfid)
// SEO URLs...
halves := strings.Split(sfid, ".")
if len(halves) < 2 {
halves = append(halves, halves[0])
}
fid, err := strconv.Atoi(halves[1])
if err != nil { 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 { if ferr != nil {
return ferr 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) pageList := common.Paginate(forum.TopicCount, common.Config.ItemsPerPage, 5)
pi := common.ForumPage{header, topicList, forum, common.Paginator{pageList, page, lastPage}} pi := common.ForumPage{header, topicList, forum, common.Paginator{pageList, page, lastPage}}
if common.RunPreRenderHook("pre_render_forum", w, r, &user, &pi) { ferr = renderTemplate("forum", w, r, header, pi)
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "forum", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
counters.ForumViewCounter.Bump(forum.ID) counters.ForumViewCounter.Bump(forum.ID)
return nil return ferr
} }

View File

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

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() // 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 { func Overview(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = phrases.GetTitlePhrase("overview") header.Title = phrases.GetTitlePhrase("overview")
header.Zone = "overview" header.Zone = "overview"
pi := common.Page{header, tList, nil} pi := common.Page{header, tList, nil}
if common.RunPreRenderHook("pre_render_overview", w, r, &user, &pi) { return renderTemplate("overview", w, r, header, pi)
return nil
}
err := common.Templates.ExecuteTemplate(w, "overview.html", pi)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
} }
func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, name string) common.RouteError { func CustomPage(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header, name string) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = phrases.GetTitlePhrase("page")
header.Zone = "custom_page" header.Zone = "custom_page"
name = common.SanitiseSingleLine(name) name = common.SanitiseSingleLine(name)
page, err := common.Pages.GetByName(name) page, err := common.Pages.GetByName(name)
if err == nil { if err == nil {
header.Title = page.Title header.Title = page.Title
pi := common.CustomPagePage{header, page} pi := common.CustomPagePage{header, page}
if common.RunPreRenderHook("pre_render_custom_page", w, r, &user, &pi) { return renderTemplate("custom_page", w, r, header, pi)
return nil
}
err := common.RunThemeTemplate(header.Theme.Name, "custom_page", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
} else if err != sql.ErrNoRows { } else if err != sql.ErrNoRows {
return common.InternalError(err, w, r) 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) return common.NotFound(w, r, header)
} }
header.Title = phrases.GetTitlePhrase("page")
pi := common.Page{header, tList, nil} pi := common.Page{header, tList, nil}
// TODO: Pass the page name to the pre-render hook? // TODO: Pass the page name to the pre-render hook?
if common.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) { if common.RunPreRenderHook("pre_render_tmpl_page", w, r, &user, &pi) {
return nil return nil
} }
err = common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi) err = common.Templates.ExecuteTemplate(w, "page_"+name+".html", pi)
if err != nil { if err != nil {
return common.InternalError(err, w, r) 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 { func ShowAttachment(w http.ResponseWriter, r *http.Request, user common.User, filename string) common.RouteError {
filename = common.Stripslashes(filename) filename = common.Stripslashes(filename)
var ext = filepath.Ext("./attachs/" + filename) var ext = filepath.Ext("./attachs/" + filename)
//log.Print("ext ", ext)
//log.Print("filename ", filename)
if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) { if !common.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
return common.LocalError("Bad extension", w, r, user) return common.LocalError("Bad extension", w, r, user)
} }

View File

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

View File

@ -3,7 +3,6 @@ package routes
import ( import (
"database/sql" "database/sql"
"errors" "errors"
"log"
"net/http" "net/http"
"strconv" "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 { 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) pollID, err := strconv.Atoi(sPollID)
if err != nil { if err != nil {
return common.PreError("The provided PollID is not a valid number.", w, r) return common.PreError("The provided PollID is not a valid number.", w, r)

View File

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

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")) page, _ := strconv.Atoi(r.FormValue("page"))
_, tid, err := ParseSEOURL(urlBit)
// 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])
if err != nil { if err != nil {
return common.PreError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r) 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 = "" topic.ClassName = ""
header, ferr := common.ForumUserCheck(w, r, &user, topic.ParentID) ferr := common.ForumUserCheck(header, w, r, &user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -163,22 +155,22 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
if replyItem.ActionType != "" { if replyItem.ActionType != "" {
switch replyItem.ActionType { switch replyItem.ActionType {
case "lock": 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" replyItem.ActionIcon = "&#x1F512;&#xFE0E"
case "unlock": 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" replyItem.ActionIcon = "&#x1F513;&#xFE0E"
case "stick": 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" replyItem.ActionIcon = "&#x1F4CC;&#xFE0E"
case "unstick": 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" replyItem.ActionIcon = "&#x1F4CC;&#xFE0E"
case "move": 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? // TODO: Only fire this off if a corresponding phrase for the ActionType doesn't exist? Or maybe have some sort of action registry?
default: default:
replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_default",replyItem.ActionType) replyItem.ActionType = phrases.GetTmplPhrasef("topic.action_topic_default", replyItem.ActionType)
replyItem.ActionIcon = "" 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? // ? - Log username changes and put restrictions on this?
// TODO: Test this // TODO: Test this
// TODO: Revamp this route // 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 fid int
var err error var err error
if sfid != "" { if sfid != "" {
@ -245,7 +237,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user common.User, sfid
fid = common.Config.DefaultForum fid = common.Config.DefaultForum
} }
header, ferr := common.ForumUserCheck(w, r, &user, fid) ferr := common.ForumUserCheck(header, w, r, &user, fid)
if ferr != nil { if ferr != nil {
return ferr 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 { 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 { if rerr != nil {
return rerr return rerr
} }
if !user.Perms.ViewTopic || !user.Perms.PinTopic { if !user.Perms.ViewTopic || !user.Perms.PinTopic {
return common.NoPermissions(w, r, user) 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) { func topicActionPre(stid string, action string, w http.ResponseWriter, r *http.Request, user common.User) (*common.Topic, common.RouteError) {
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { 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) 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 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 { if err != nil {
return common.InternalError(err, w, r) 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 { 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 { if rerr != nil {
return rerr return rerr
} }
if !user.Perms.ViewTopic || !user.Perms.PinTopic { if !user.Perms.ViewTopic || !user.Perms.PinTopic {
return common.NoPermissions(w, r, user) 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 { 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 { 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 { if rerr != nil {
return rerr return rerr
} }
if !user.Perms.ViewTopic || !user.Perms.CloseTopic { if !user.Perms.ViewTopic || !user.Perms.CloseTopic {
return common.NoPermissions(w, r, user) 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 // ! JS only route

View File

@ -9,11 +9,7 @@ import (
"github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/common/phrases"
) )
func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func TopicList(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = phrases.GetTitlePhrase("topics") header.Title = phrases.GetTitlePhrase("topics")
header.Zone = "topics" header.Zone = "topics"
header.Path = "/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} 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 renderTemplate("topics", w, r, header, pi)
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "topics", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
} }
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.User, header *common.Header) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = phrases.GetTitlePhrase("topics") header.Title = phrases.GetTitlePhrase("topics")
header.Zone = "topics" header.Zone = "topics"
header.Path = "/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} 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 renderTemplate("topics", w, r, header, pi)
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "topics", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
} }