Revert "Revert "will a pointer make this faster...?""

This reverts commit 501bcc2425.
This commit is contained in:
Azareal 2020-03-18 19:21:34 +10:00
parent 501bcc2425
commit b66a494f1c
46 changed files with 664 additions and 667 deletions

View File

@ -192,7 +192,7 @@ func buildAlertSb(sb *strings.Builder, msg string, sub []string, path, avatar st
sb.WriteRune('}') sb.WriteRune('}')
} }
func BuildAlertSb(sb *strings.Builder, a *Alert, user User /* The current user */) (err error) { func BuildAlertSb(sb *strings.Builder, a *Alert, u *User /* The current user */) (err error) {
var targetUser *User var targetUser *User
if a.Actor == nil { if a.Actor == nil {
a.Actor, err = Users.Get(a.ActorID) a.Actor, err = Users.Get(a.ActorID)
@ -248,7 +248,7 @@ func BuildAlertSb(sb *strings.Builder, a *Alert, user User /* The current user *
} }
url = topic.Link url = topic.Link
area = topic.Title area = topic.Title
own = a.TargetUserID == user.ID own = a.TargetUserID == u.ID
case "user": case "user":
targetUser, err = Users.Get(a.ElementID) targetUser, err = Users.Get(a.ElementID)
if err != nil { if err != nil {
@ -257,16 +257,16 @@ func BuildAlertSb(sb *strings.Builder, a *Alert, user User /* The current user *
} }
area = targetUser.Name area = targetUser.Name
url = targetUser.Link url = targetUser.Link
own = a.TargetUserID == user.ID own = a.TargetUserID == u.ID
case "post": case "post":
topic, err := TopicByReplyID(a.ElementID) t, err := TopicByReplyID(a.ElementID)
if err != nil { if err != nil {
DebugLogf("Unable to find linked topic by reply ID %d", a.ElementID) DebugLogf("Unable to find linked topic by reply ID %d", a.ElementID)
return errors.New(phrases.GetErrorPhrase("alerts_no_linked_topic_by_reply")) return errors.New(phrases.GetErrorPhrase("alerts_no_linked_topic_by_reply"))
} }
url = topic.Link url = t.Link
area = topic.Title area = t.Title
own = a.TargetUserID == user.ID own = a.TargetUserID == u.ID
default: default:
return errors.New(phrases.GetErrorPhrase("alerts_invalid_elementtype")) return errors.New(phrases.GetErrorPhrase("alerts_invalid_elementtype"))
} }

View File

@ -125,7 +125,7 @@ func LogWarning(err error, extra ...string) {
errorBuffer = append(errorBuffer, ErrorItem{err, stack}) errorBuffer = append(errorBuffer, ErrorItem{err, stack})
} }
func errorHeader(w http.ResponseWriter, user User, title string) *Header { func errorHeader(w http.ResponseWriter, user *User, title string) *Header {
h := DefaultHeader(w, user) h := DefaultHeader(w, user)
h.Title = title h.Title = title
h.Zone = "error" h.Zone = "error"
@ -138,7 +138,7 @@ func errorHeader(w http.ResponseWriter, user User, title string) *Header {
// ! Do not call CustomError here or we might get an error loop // ! Do not call CustomError here or we might get an error loop
func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError { func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500) w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")} pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
LogError(err) LogError(err)
return HandledRouteError() return HandledRouteError()
@ -165,7 +165,7 @@ func InternalErrorJS(err error, w http.ResponseWriter, r *http.Request) RouteErr
// When the task system detects if the database is down, some database errors might slip by this // When the task system detects if the database is down, some database errors might slip by this
func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError { func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500) w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")} pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
} }
@ -173,7 +173,7 @@ func DatabaseError(w http.ResponseWriter, r *http.Request) RouteError {
func InternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteError { func InternalErrorXML(err error, w http.ResponseWriter, r *http.Request) RouteError {
w.Header().Set("Content-Type", "application/xml") w.Header().Set("Content-Type", "application/xml")
w.WriteHeader(500) w.WriteHeader(500)
w.Write([]byte(`<?xml version="1.0" encoding="UTF-8"?> w.Write([]byte(`<?xml version="1.0"encoding="UTF-8"?>
<error>` + phrases.GetErrorPhrase("internal_error_body") + `</error>`)) <error>` + phrases.GetErrorPhrase("internal_error_body") + `</error>`))
LogError(err) LogError(err)
return HandledRouteError() return HandledRouteError()
@ -192,7 +192,7 @@ func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) R
// ! Do not call CustomError here otherwise we might get an error loop // ! Do not call CustomError here otherwise we might get an error loop
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError { func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
w.WriteHeader(500) w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("error_title")), errmsg} pi := ErrorPage{errorHeader(w, &GuestUser, phrases.GetErrorPhrase("error_title")), errmsg}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
} }
@ -212,30 +212,30 @@ func PreErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, js bool)
// LocalError is an error shown to the end-user when something goes wrong and it's not the software's fault // LocalError is an error shown to the end-user when something goes wrong and it's not the software's fault
// TODO: Pass header in for this and similar errors instead of having to pass in both user and w? Would also allow for more stateful things, although this could be a problem // TODO: Pass header in for this and similar errors instead of having to pass in both user and w? Would also allow for more stateful things, although this could be a problem
/*func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) RouteError { /*func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(500) w.WriteHeader(500)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("local_error_title")), errmsg} pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("local_error_title")), errmsg}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
}*/ }*/
func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user User) RouteError { func LocalError(errmsg string, w http.ResponseWriter, r *http.Request, user *User) RouteError {
return SimpleError(errmsg, w, r, errorHeader(w, user, "")) return SimpleError(errmsg, w, r, errorHeader(w, user, ""))
} }
func SimpleError(errmsg string, w http.ResponseWriter, r *http.Request, header *Header) RouteError { func SimpleError(errmsg string, w http.ResponseWriter, r *http.Request, h *Header) RouteError {
if header == nil { if h == nil {
header = errorHeader(w, GuestUser, phrases.GetErrorPhrase("local_error_title")) h = errorHeader(w, &GuestUser, phrases.GetErrorPhrase("local_error_title"))
} else { } else {
header.Title = phrases.GetErrorPhrase("local_error_title") h.Title = phrases.GetErrorPhrase("local_error_title")
} }
w.WriteHeader(500) w.WriteHeader(500)
pi := ErrorPage{header, errmsg} pi := ErrorPage{h, errmsg}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
} }
func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user User, js bool) RouteError { func LocalErrorJSQ(errmsg string, w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
if !js { if !js {
return SimpleError(errmsg, w, r, errorHeader(w, user, "")) return SimpleError(errmsg, w, r, errorHeader(w, user, ""))
} }
@ -250,28 +250,28 @@ func LocalErrorJS(errmsg string, w http.ResponseWriter, r *http.Request) RouteEr
// TODO: We might want to centralise the error logic in the future and just return what the error handler needs to construct the response rather than handling it here // TODO: We might want to centralise the error logic in the future and just return what the error handler needs to construct the response rather than handling it here
// NoPermissions is an error shown to the end-user when they try to access an area which they aren't authorised to access // NoPermissions is an error shown to the end-user when they try to access an area which they aren't authorised to access
func NoPermissions(w http.ResponseWriter, r *http.Request, user User) RouteError { func NoPermissions(w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("no_permissions_title")), phrases.GetErrorPhrase("no_permissions_body")} pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("no_permissions_title")), phrases.GetErrorPhrase("no_permissions_body")}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
} }
func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user User, js bool) RouteError { func NoPermissionsJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
if !js { if !js {
return NoPermissions(w, r, user) return NoPermissions(w, r, user)
} }
return NoPermissionsJS(w, r, user) return NoPermissionsJS(w, r, user)
} }
func NoPermissionsJS(w http.ResponseWriter, r *http.Request, user User) RouteError { func NoPermissionsJS(w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
writeJsonError(phrases.GetErrorPhrase("no_permissions_body"), w) writeJsonError(phrases.GetErrorPhrase("no_permissions_body"), w)
return HandledRouteError() return HandledRouteError()
} }
// ? - Is this actually used? Should it be used? A ban in Gosora should be more of a permission revocation to stop them posting rather than something which spits up an error page, right? // ? - Is this actually used? Should it be used? A ban in Gosora should be more of a permission revocation to stop them posting rather than something which spits up an error page, right?
func Banned(w http.ResponseWriter, r *http.Request, user User) RouteError { func Banned(w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("banned_title")), phrases.GetErrorPhrase("banned_body")} pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("banned_title")), phrases.GetErrorPhrase("banned_body")}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
@ -280,21 +280,21 @@ func Banned(w http.ResponseWriter, r *http.Request, user User) RouteError {
// nolint // nolint
// BannedJSQ is the version of the banned error page which handles both JavaScript requests and normal page loads // BannedJSQ is the version of the banned error page which handles both JavaScript requests and normal page loads
func BannedJSQ(w http.ResponseWriter, r *http.Request, user User, js bool) RouteError { func BannedJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
if !js { if !js {
return Banned(w, r, user) return Banned(w, r, user)
} }
return BannedJS(w, r, user) return BannedJS(w, r, user)
} }
func BannedJS(w http.ResponseWriter, r *http.Request, user User) RouteError { func BannedJS(w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
writeJsonError(phrases.GetErrorPhrase("banned_body"), w) writeJsonError(phrases.GetErrorPhrase("banned_body"), w)
return HandledRouteError() return HandledRouteError()
} }
// nolint // nolint
func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, js bool) RouteError { func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user *User, js bool) RouteError {
if !js { if !js {
return LoginRequired(w, r, user) return LoginRequired(w, r, user)
} }
@ -303,12 +303,12 @@ func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, js bool
// ? - Where is this used? Should we use it more? // ? - Where is this used? Should we use it more?
// LoginRequired is an error shown to the end-user when they try to access an area which requires them to login // LoginRequired is an error shown to the end-user when they try to access an area which requires them to login
func LoginRequired(w http.ResponseWriter, r *http.Request, user User) RouteError { func LoginRequired(w http.ResponseWriter, r *http.Request, user *User) RouteError {
return CustomError(phrases.GetErrorPhrase("login_required_body"), 401, phrases.GetErrorPhrase("no_permissions_title"), w, r, nil, user) return CustomError(phrases.GetErrorPhrase("login_required_body"), 401, phrases.GetErrorPhrase("no_permissions_title"), w, r, nil, user)
} }
// nolint // nolint
func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteError { func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(401) w.WriteHeader(401)
writeJsonError(phrases.GetErrorPhrase("login_required_body"), w) writeJsonError(phrases.GetErrorPhrase("login_required_body"), w)
return HandledRouteError() return HandledRouteError()
@ -316,7 +316,7 @@ func LoginRequiredJS(w http.ResponseWriter, r *http.Request, user User) RouteErr
// SecurityError is used whenever a session mismatch is found // SecurityError is used whenever a session mismatch is found
// ? - Should we add JS and JSQ versions of this? // ? - Should we add JS and JSQ versions of this?
func SecurityError(w http.ResponseWriter, r *http.Request, user User) RouteError { func SecurityError(w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(403) w.WriteHeader(403)
pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")} pi := ErrorPage{errorHeader(w, user, phrases.GetErrorPhrase("security_error_title")), phrases.GetErrorPhrase("security_error_body")}
err := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi) err := RenderTemplateAlias("error", "security_error", w, r, pi.Header, pi)
@ -335,8 +335,8 @@ func MicroNotFound(w http.ResponseWriter, r *http.Request) RouteError {
// NotFound is used when the requested page doesn't exist // NotFound is used when the requested page doesn't exist
// ? - Add a JSQ version of this? // ? - Add a JSQ version of this?
// ? - Add a user parameter? // ? - Add a user parameter?
func NotFound(w http.ResponseWriter, r *http.Request, header *Header) RouteError { func NotFound(w http.ResponseWriter, r *http.Request, h *Header) RouteError {
return CustomError(phrases.GetErrorPhrase("not_found_body"), 404, phrases.GetErrorPhrase("not_found_title"), w, r, header, GuestUser) return CustomError(phrases.GetErrorPhrase("not_found_body"), 404, phrases.GetErrorPhrase("not_found_title"), w, r, h, &GuestUser)
} }
// ? - Add a user parameter? // ? - Add a user parameter?
@ -346,42 +346,42 @@ func NotFoundJS(w http.ResponseWriter, r *http.Request) RouteError {
return HandledRouteError() return HandledRouteError()
} }
func NotFoundJSQ(w http.ResponseWriter, r *http.Request, header *Header, js bool) RouteError { func NotFoundJSQ(w http.ResponseWriter, r *http.Request, h *Header, js bool) RouteError {
if js { if js {
return NotFoundJS(w, r) return NotFoundJS(w, r)
} }
if header == nil { if h == nil {
header = DefaultHeader(w, GuestUser) h = DefaultHeader(w, &GuestUser)
} }
return NotFound(w, r, header) return NotFound(w, r, h)
} }
// CustomError lets us make custom error types which aren't covered by the generic functions above // CustomError lets us make custom error types which aren't covered by the generic functions above
func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, header *Header, user User) (rerr RouteError) { func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, h *Header, user *User) (rerr RouteError) {
if header == nil { if h == nil {
header, rerr = UserCheck(w, r, &user) h, rerr = UserCheck(w, r, user)
if rerr != nil { if rerr != nil {
header = errorHeader(w, user, errtitle) h = errorHeader(w, user, errtitle)
} }
} }
header.Title = errtitle h.Title = errtitle
header.Zone = "error" h.Zone = "error"
w.WriteHeader(errcode) w.WriteHeader(errcode)
pi := ErrorPage{header, errmsg} pi := ErrorPage{h, errmsg}
handleErrorTemplate(w, r, pi) handleErrorTemplate(w, r, pi)
return HandledRouteError() return HandledRouteError()
} }
// CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed // CustomErrorJSQ is a version of CustomError which lets us handle both JSON and regular pages depending on how it's being accessed
func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, header *Header, user User, js bool) RouteError { func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, h *Header, user *User, js bool) RouteError {
if !js { if !js {
return CustomError(errmsg, errcode, errtitle, w, r, header, user) return CustomError(errmsg, errcode, errtitle, w, r, h, user)
} }
return CustomErrorJS(errmsg, errcode, w, r, user) return CustomErrorJS(errmsg, errcode, w, r, user)
} }
// CustomErrorJS is the pure JSON version of CustomError // CustomErrorJS is the pure JSON version of CustomError
func CustomErrorJS(errmsg string, errcode int, w http.ResponseWriter, r *http.Request, user User) RouteError { func CustomErrorJS(errmsg string, errcode int, w http.ResponseWriter, r *http.Request, user *User) RouteError {
w.WriteHeader(errcode) w.WriteHeader(errcode)
writeJsonError(errmsg, w) writeJsonError(errmsg, w)
return HandledRouteError() return HandledRouteError()
@ -400,4 +400,4 @@ func handleErrorTemplate(w http.ResponseWriter, r *http.Request, pi ErrorPage) {
} }
// Alias of routes.renderTemplate // Alias of routes.renderTemplate
var RenderTemplateAlias func(tmplName, hookName string, w http.ResponseWriter, r *http.Request, header *Header, pi interface{}) error var RenderTemplateAlias func(tmplName, hookName string, w http.ResponseWriter, r *http.Request, h *Header, pi interface{}) error

View File

@ -32,7 +32,7 @@ type Header struct {
Themes map[string]*Theme // TODO: Use a slice containing every theme instead of the main map for speed? Themes map[string]*Theme // TODO: Use a slice containing every theme instead of the main map for speed?
Theme *Theme Theme *Theme
//TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over? //TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over?
CurrentUser User // TODO: Deprecate CurrentUser on the page structs and use a pointer here CurrentUser *User // TODO: Deprecate CurrentUser on the page structs and use a pointer here
Hooks *HookTable Hooks *HookTable
Zone string Zone string
ZoneID int ZoneID int
@ -780,9 +780,9 @@ type AreYouSure struct {
} }
// TODO: Write a test for this // TODO: Write a test for this
func DefaultHeader(w http.ResponseWriter, user User) *Header { func DefaultHeader(w http.ResponseWriter, user *User) *Header {
return &Header{Site: Site, Theme: Themes[fallbackTheme], CurrentUser: user, Writer: w} return &Header{Site: Site, Theme: Themes[fallbackTheme], CurrentUser: user, Writer: w}
} }
func SimpleDefaultHeader(w http.ResponseWriter) *Header { func SimpleDefaultHeader(w http.ResponseWriter) *Header {
return &Header{Site: Site, Theme: Themes[fallbackTheme], CurrentUser: GuestUser, Writer: w} return &Header{Site: Site, Theme: Themes[fallbackTheme], CurrentUser: &GuestUser, Writer: w}
} }

View File

@ -71,7 +71,7 @@ func forumUserCheck(header *Header, w http.ResponseWriter, r *http.Request, user
return 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 rerr return rerr
} }
@ -107,7 +107,7 @@ func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (h *Head
Settings: SettingBox.Load().(SettingMap), Settings: SettingBox.Load().(SettingMap),
Themes: Themes, Themes: Themes,
Theme: theme, Theme: theme,
CurrentUser: *user, CurrentUser: user,
Hooks: GetHookTable(), Hooks: GetHookTable(),
Zone: "panel", Zone: "panel",
Writer: w, Writer: w,
@ -202,7 +202,7 @@ func GetThemeByReq(r *http.Request) *Theme {
} }
func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) { func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) {
return userCheck2(w,r,user,uutils.Nanotime()) return userCheck2(w, r, user, uutils.Nanotime())
} }
// TODO: Add the ability for admins to restrict certain themes to certain groups? // TODO: Add the ability for admins to restrict certain themes to certain groups?
@ -214,12 +214,12 @@ func userCheck2(w http.ResponseWriter, r *http.Request, user *User, nano int64)
Settings: SettingBox.Load().(SettingMap), Settings: SettingBox.Load().(SettingMap),
Themes: Themes, Themes: Themes,
Theme: theme, Theme: theme,
CurrentUser: *user, // ! Some things rely on this being a pointer downstream from this function CurrentUser: user, // ! Some things rely on this being a pointer downstream from this function
Hooks: GetHookTable(), Hooks: GetHookTable(),
Zone: "frontend", Zone: "frontend",
Writer: w, Writer: w,
IsoCode: phrases.GetLangPack().IsoCode, IsoCode: phrases.GetLangPack().IsoCode,
StartedAt: nano, StartedAt: nano,
} }
// TODO: Optimise this by avoiding accessing a map string index // TODO: Optimise this by avoiding accessing a map string index
header.GoogSiteVerify = header.Settings["google_site_verify"].(string) header.GoogSiteVerify = header.Settings["google_site_verify"].(string)
@ -338,7 +338,7 @@ func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
return *usercpy, true return *usercpy, true
} }
func UploadAvatar(w http.ResponseWriter, r *http.Request, user User, tuid int) (ext string, ferr RouteError) { func UploadAvatar(w http.ResponseWriter, r *http.Request, user *User, tuid int) (ext string, ferr RouteError) {
// We don't want multiple files // We don't want multiple files
// TODO: Are we doing this correctly? // TODO: Are we doing this correctly?
filenameMap := make(map[string]bool) filenameMap := make(map[string]bool)
@ -404,7 +404,7 @@ func UploadAvatar(w http.ResponseWriter, r *http.Request, user User, tuid int) (
return ext, nil return ext, nil
} }
func ChangeAvatar(path string, w http.ResponseWriter, r *http.Request, user User) RouteError { func ChangeAvatar(path string, w http.ResponseWriter, r *http.Request, user *User) RouteError {
err := user.ChangeAvatar(path) err := user.ChangeAvatar(path)
if err != nil { if err != nil {
return InternalError(err, w, r) return InternalError(err, w, r)
@ -430,7 +430,7 @@ func ChangeAvatar(path string, w http.ResponseWriter, r *http.Request, user User
} }
// SuperAdminOnly makes sure that only super admin can access certain critical panel routes // SuperAdminOnly makes sure that only super admin can access certain critical panel routes
func SuperAdminOnly(w http.ResponseWriter, r *http.Request, user User) RouteError { func SuperAdminOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if !user.IsSuperAdmin { if !user.IsSuperAdmin {
return NoPermissions(w, r, user) return NoPermissions(w, r, user)
} }
@ -438,7 +438,7 @@ func SuperAdminOnly(w http.ResponseWriter, r *http.Request, user User) RouteErro
} }
// AdminOnly makes sure that only admins can access certain panel routes // AdminOnly makes sure that only admins can access certain panel routes
func AdminOnly(w http.ResponseWriter, r *http.Request, user User) RouteError { func AdminOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if !user.IsAdmin { if !user.IsAdmin {
return NoPermissions(w, r, user) return NoPermissions(w, r, user)
} }
@ -446,7 +446,7 @@ func AdminOnly(w http.ResponseWriter, r *http.Request, user User) RouteError {
} }
// SuperModeOnly makes sure that only super mods or higher can access the panel routes // SuperModeOnly makes sure that only super mods or higher can access the panel routes
func SuperModOnly(w http.ResponseWriter, r *http.Request, user User) RouteError { func SuperModOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if !user.IsSuperMod { if !user.IsSuperMod {
return NoPermissions(w, r, user) return NoPermissions(w, r, user)
} }
@ -454,7 +454,7 @@ func SuperModOnly(w http.ResponseWriter, r *http.Request, user User) RouteError
} }
// MemberOnly makes sure that only logged in users can access this route // MemberOnly makes sure that only logged in users can access this route
func MemberOnly(w http.ResponseWriter, r *http.Request, user User) RouteError { func MemberOnly(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if !user.Loggedin { if !user.Loggedin {
return LoginRequired(w, r, user) return LoginRequired(w, r, user)
} }
@ -462,21 +462,21 @@ func MemberOnly(w http.ResponseWriter, r *http.Request, user User) RouteError {
} }
// NoBanned stops any banned users from accessing this route // NoBanned stops any banned users from accessing this route
func NoBanned(w http.ResponseWriter, r *http.Request, user User) RouteError { func NoBanned(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if user.IsBanned { if user.IsBanned {
return Banned(w, r, user) return Banned(w, r, user)
} }
return nil return nil
} }
func ParseForm(w http.ResponseWriter, r *http.Request, user User) RouteError { func ParseForm(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if err := r.ParseForm(); err != nil { if err := r.ParseForm(); err != nil {
return LocalError("Bad Form", w, r, user) return LocalError("Bad Form", w, r, user)
} }
return nil return nil
} }
func NoSessionMismatch(w http.ResponseWriter, r *http.Request, user User) RouteError { func NoSessionMismatch(w http.ResponseWriter, r *http.Request, user *User) RouteError {
if err := r.ParseForm(); err != nil { if err := r.ParseForm(); err != nil {
return LocalError("Bad Form", w, r, user) return LocalError("Bad Form", w, r, user)
} }
@ -495,7 +495,7 @@ func ReqIsJson(r *http.Request) bool {
return r.Header.Get("Content-type") == "application/json" return r.Header.Get("Content-type") == "application/json"
} }
func HandleUploadRoute(w http.ResponseWriter, r *http.Request, user User, maxFileSize int) RouteError { func HandleUploadRoute(w http.ResponseWriter, r *http.Request, user *User, maxFileSize int) RouteError {
// TODO: Reuse this code more // TODO: Reuse this code more
if r.ContentLength > int64(maxFileSize) { if r.ContentLength > int64(maxFileSize) {
size, unit := ConvertByteUnit(float64(maxFileSize)) size, unit := ConvertByteUnit(float64(maxFileSize))
@ -510,7 +510,7 @@ func HandleUploadRoute(w http.ResponseWriter, r *http.Request, user User, maxFil
return nil return nil
} }
func NoUploadSessionMismatch(w http.ResponseWriter, r *http.Request, user User) RouteError { func NoUploadSessionMismatch(w http.ResponseWriter, r *http.Request, user *User) RouteError {
// TODO: Try to eliminate some of these allocations // TODO: Try to eliminate some of these allocations
sess := []byte(user.Session) sess := []byte(user.Session)
if len(sess) == 0 { if len(sess) == 0 {

View File

@ -91,20 +91,20 @@ var Template_error_handle = genIntTmpl("error")
var Template_ip_search_handle = genIntTmpl("ip_search") var Template_ip_search_handle = genIntTmpl("ip_search")
var Template_account_handle = genIntTmpl("account") var Template_account_handle = genIntTmpl("account")
func tmplInitUsers() (User, User, User) { func tmplInitUsers() (*User, *User, *User) {
avatar, microAvatar := BuildAvatar(62, "") avatar, microAvatar := BuildAvatar(62, "")
user := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", avatar, microAvatar, "", "", 0, 0, 0, 0, StartTime, "0.0.0.0.0", 0, 0, nil} u := User{62, BuildProfileURL("fake-user", 62), "Fake User", "compiler@localhost", 0, false, false, false, false, false, false, GuestPerms, make(map[string]bool), "", false, "", avatar, microAvatar, "", "", 0, 0, 0, 0, StartTime, "0.0.0.0.0", 0, 0, nil}
// TODO: Do a more accurate level calculation for this? // TODO: Do a more accurate level calculation for this?
avatar, microAvatar = BuildAvatar(1, "") avatar, microAvatar = BuildAvatar(1, "")
user2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", 58, 1000, 0, 1000, StartTime, "127.0.0.1", 0, 0, nil} u2 := User{1, BuildProfileURL("admin-alice", 1), "Admin Alice", "alice@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", 58, 1000, 0, 1000, StartTime, "127.0.0.1", 0, 0, nil}
avatar, microAvatar = BuildAvatar(2, "") avatar, microAvatar = BuildAvatar(2, "")
user3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", 42, 900, 0, 900, StartTime, "::1", 0, 0, nil} u3 := User{2, BuildProfileURL("admin-fred", 62), "Admin Fred", "fred@localhost", 1, true, true, true, true, false, false, AllPerms, make(map[string]bool), "", true, "", avatar, microAvatar, "", "", 42, 900, 0, 900, StartTime, "::1", 0, 0, nil}
return user, user2, user3 return &u, &u2, &u3
} }
func tmplInitHeaders(user, user2, user3 User) (*Header, *Header, *Header) { func tmplInitHeaders(user, user2, user3 *User) (*Header, *Header, *Header) {
header := &Header{ header := &Header{
Site: Site, Site: Site,
Settings: SettingBox.Load().(SettingMap), Settings: SettingBox.Load().(SettingMap),
@ -121,7 +121,7 @@ func tmplInitHeaders(user, user2, user3 User) (*Header, *Header, *Header) {
}, },
} }
buildHeader := func(user User) *Header { buildHeader := func(user *User) *Header {
head := &Header{Site: Site} head := &Header{Site: Site}
*head = *header *head = *header
head.CurrentUser = user head.CurrentUser = user
@ -224,7 +224,7 @@ func compileCommons(c *tmpl.CTemplateSet, head, head2 *Header, forumList []Forum
}*/ }*/
var topicsList []*TopicsRow var topicsList []*TopicsRow
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}) topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil})
topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}} topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}}
o.Add("topics", "c.TopicListPage", topicListPage) o.Add("topics", "c.TopicListPage", topicListPage)
@ -298,11 +298,11 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
return err return err
} }
ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0, false, false, false} // TODO: Use the score from user to generate the currentScore and nextScore ppage := ProfilePage{htitle("User 526"), replyList, *user, 0, 0, false, false, false} // TODO: Use the score from user to generate the currentScore and nextScore
t.Add("profile", "c.ProfilePage", ppage) t.Add("profile", "c.ProfilePage", ppage)
var topicsList []*TopicsRow var topicsList []*TopicsRow
topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil}) topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil})
topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}} topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, Paginator{[]int{1}, 1, 1}}
forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0) forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0)
@ -344,20 +344,20 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
t.AddStd("register", "c.Page", Page{htitle("Registration Page"), tList, false}) t.AddStd("register", "c.Page", Page{htitle("Registration Page"), tList, false})
t.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."}) t.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: &user2}, "::1"} ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: user2}, "::1"}
t.AddStd("ip_search", "c.IPSearchPage", ipSearchPage) t.AddStd("ip_search", "c.IPSearchPage", ipSearchPage)
var inter nobreak var inter nobreak
accountPage := Account{header, "dashboard", "account_own_edit", inter} accountPage := Account{header, "dashboard", "account_own_edit", inter}
t.AddStd("account", "c.Account", accountPage) t.AddStd("account", "c.Account", accountPage)
parti := []*User{&user} parti := []*User{user}
convo := &Conversation{1, BuildConvoURL(1), user.ID, time.Now(), 0, time.Now()} convo := &Conversation{1, BuildConvoURL(1), user.ID, time.Now(), 0, time.Now()}
convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1, 1, "hey", "", user.ID}, &user, "", 4, true}} convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1, 1, "hey", "", user.ID}, user, "", 4, true}}
convoPage := ConvoViewPage{header, convo, convoItems, parti, true, Paginator{[]int{1}, 1, 1}} convoPage := ConvoViewPage{header, convo, convoItems, parti, true, Paginator{[]int{1}, 1, 1}}
t.AddStd("convo", "c.ConvoViewPage", convoPage) t.AddStd("convo", "c.ConvoViewPage", convoPage)
convos := []*ConversationExtra{&ConversationExtra{&Conversation{}, []*User{&user}}} convos := []*ConversationExtra{&ConversationExtra{&Conversation{}, []*User{user}}}
var cRows []ConvoListRow var cRows []ConvoListRow
for _, convo := range convos { for _, convo := range convos {
cRows = append(cRows, ConvoListRow{convo, convo.Users, false}) cRows = append(cRows, ConvoListRow{convo, convo.Users, false})
@ -417,7 +417,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
config.SkipHandles = true config.SkipHandles = true
c.SetConfig(config) c.SetConfig(config)
for _, tmplfunc := range PrebuildTmplList { for _, tmplfunc := range PrebuildTmplList {
tmplItem := tmplfunc(user, header) tmplItem := tmplfunc(*user, header)
varList := make(map[string]tmpl.VarItem) varList := make(map[string]tmpl.VarItem)
compiledTmpl, err := c.Compile(tmplItem.Filename, tmplItem.Path, tmplItem.StructName, tmplItem.Data, varList, tmplItem.Imports...) compiledTmpl, err := c.Compile(tmplItem.Filename, tmplItem.Path, tmplItem.StructName, tmplItem.Data, varList, tmplItem.Imports...)
if err != nil { if err != nil {
@ -529,7 +529,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
t := TItemHold(make(map[string]TItem)) t := TItemHold(make(map[string]TItem))
topicsRow := &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 0, 1, "classname", 0, "", &user2, "", 0, &user3, "General", "/forum/general.2", nil} topicsRow := &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 0, 1, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil}
t.AddStd("topics_topic", "c.TopicsRow", topicsRow) t.AddStd("topics_topic", "c.TopicsRow", topicsRow)
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{ poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
@ -563,9 +563,9 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
t.AddStd("topic_c_attach_item", "c.TopicCAttachItem", TopicCAttachItem{ID: 1, ImgSrc: "", Path: "", FullPath: ""}) t.AddStd("topic_c_attach_item", "c.TopicCAttachItem", TopicCAttachItem{ID: 1, ImgSrc: "", Path: "", FullPath: ""})
t.AddStd("topic_c_poll_input", "c.TopicCPollInput", TopicCPollInput{Index: 0}) t.AddStd("topic_c_poll_input", "c.TopicCPollInput", TopicCPollInput{Index: 0})
parti := []*User{&user} parti := []*User{user}
convo := &Conversation{1, BuildConvoURL(1), user.ID, time.Now(), 0, time.Now()} convo := &Conversation{1, BuildConvoURL(1), user.ID, time.Now(), 0, time.Now()}
convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1, 1, "hey", "", user.ID}, &user, "", 4, true}} convoItems := []ConvoViewRow{ConvoViewRow{&ConversationPost{1, 1, "hey", "", user.ID}, user, "", 4, true}}
convoPage := ConvoViewPage{header, convo, convoItems, parti, true, Paginator{[]int{1}, 1, 1}} convoPage := ConvoViewPage{header, convo, convoItems, parti, true, Paginator{[]int{1}, 1, 1}}
t.AddStd("convo", "c.ConvoViewPage", convoPage) t.AddStd("convo", "c.ConvoViewPage", convoPage)

View File

@ -46,7 +46,7 @@ type WsTopicList struct {
// TODO: How should we handle errors for this? // TODO: How should we handle errors for this?
// TODO: Move this out of common? // TODO: Move this out of common?
func RouteWebsockets(w http.ResponseWriter, r *http.Request, user User) RouteError { func RouteWebsockets(w http.ResponseWriter, r *http.Request, user *User) RouteError {
// TODO: Spit out a 500 instead of nil? // TODO: Spit out a 500 instead of nil?
conn, err := wsUpgrader.Upgrade(w, r, nil) conn, err := wsUpgrader.Upgrade(w, r, nil)
if err != nil { if err != nil {

View File

@ -194,7 +194,7 @@ func BuildWidget(dock string, h *Header) (sbody string) {
// 1 = id for the default menu // 1 = id for the default menu
mhold, err := Menus.Get(1) mhold, err := Menus.Get(1)
if err == nil { if err == nil {
err := mhold.Build(h.Writer, &h.CurrentUser, h.Path) err := mhold.Build(h.Writer, h.CurrentUser, h.Path)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }
@ -259,7 +259,7 @@ func InitWidgets() (fi error) {
} }
setDock(name, dock) setDock(name, dock)
} }
f("leftOfNav") f("leftOfNav")
f("rightOfNav") f("rightOfNav")
f("leftSidebar") f("leftSidebar")

View File

@ -329,11 +329,11 @@ func (h *WsHubImpl) removeUser(uid int) {
} }
} }
func (h *WsHubImpl) AddConn(user User, conn *websocket.Conn) (*WSUser, error) { func (h *WsHubImpl) AddConn(user *User, conn *websocket.Conn) (*WSUser, error) {
if user.ID == 0 { if user.ID == 0 {
wsUser := new(WSUser) wsUser := new(WSUser)
wsUser.User = new(User) wsUser.User = new(User)
*wsUser.User = user *wsUser.User = *user
wsUser.AddSocket(conn, "") wsUser.AddSocket(conn, "")
WsHub.GuestLock.Lock() WsHub.GuestLock.Lock()
WsHub.OnlineGuests[wsUser] = true WsHub.OnlineGuests[wsUser] = true

View File

@ -161,7 +161,7 @@ func GuildWidgets(header *c.Header, guildItem *Guild) (success bool) {
Custom Pages Custom Pages
*/ */
func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteGuildList(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
h, ferr := c.UserCheck(w, r, &user) h, ferr := c.UserCheck(w, r, &user)
if ferr != nil { if ferr != nil {
return ferr return ferr
@ -192,7 +192,7 @@ func RouteGuildList(w http.ResponseWriter, r *http.Request, user c.User) c.Route
return routes.RenderTemplate("guilds_guild_list", w, r, h, pi) return routes.RenderTemplate("guilds_guild_list", w, r, h, pi)
} }
func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/"):]) _, guildID, err := routes.ParseSEOURL(r.URL.Path[len("/guild/"):])
if err != nil { if err != nil {
return c.PreError("Not a valid guild ID", w, r) return c.PreError("Not a valid guild ID", w, r)
@ -215,7 +215,7 @@ func MiddleViewGuild(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
//return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID)) //return routeForum(w, r.WithContext(ctx), user, strconv.Itoa(guildItem.MainForumID))
} }
func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
h, ferr := c.UserCheck(w, r, &user) h, ferr := c.UserCheck(w, r, &user)
if ferr != nil { if ferr != nil {
return ferr return ferr
@ -230,7 +230,7 @@ func RouteCreateGuild(w http.ResponseWriter, r *http.Request, user c.User) c.Rou
return routes.RenderTemplate("guilds_create_guild", w, r, h, c.Page{h, tList, nil}) return routes.RenderTemplate("guilds_create_guild", w, r, h, c.Page{h, tList, nil})
} }
func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
// TODO: Add an approval queue mode for group creation // TODO: Add an approval queue mode for group creation
if !user.Loggedin || !user.PluginPerms["CreateGuild"] { if !user.Loggedin || !user.PluginPerms["CreateGuild"] {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
@ -279,7 +279,7 @@ func RouteCreateGuildSubmit(w http.ResponseWriter, r *http.Request, user c.User)
return nil return nil
} }
func RouteMemberList(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func RouteMemberList(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
header, ferr := c.UserCheck(w, r, &user) header, ferr := c.UserCheck(w, r, &user)
if ferr != nil { if ferr != nil {
return ferr return ferr

View File

@ -822,7 +822,7 @@ func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
type GenRouter struct { type GenRouter struct {
UploadHandler func(http.ResponseWriter, *http.Request) UploadHandler func(http.ResponseWriter, *http.Request)
extraRoutes map[string]func(http.ResponseWriter, *http.Request, c.User) c.RouteError extraRoutes map[string]func(http.ResponseWriter, *http.Request, *c.User) c.RouteError
requestLogger *log.Logger requestLogger *log.Logger
sync.RWMutex sync.RWMutex
@ -839,12 +839,12 @@ func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
writ := NewWriterIntercept(w) writ := NewWriterIntercept(w)
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req) http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
}, },
extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, c.User) c.RouteError), extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, *c.User) c.RouteError),
requestLogger: log.New(f, "", log.LstdFlags), requestLogger: log.New(f, "", log.LstdFlags),
}, nil }, nil
} }
func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *http.Request, user c.User) { func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *http.Request, user *c.User) {
if err.Handled() { if err.Handled() {
return return
} }
@ -858,7 +858,7 @@ func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *ht
func (r *GenRouter) Handle(_ string, _ http.Handler) { func (r *GenRouter) Handle(_ string, _ http.Handler) {
} }
func (r *GenRouter) HandleFunc(pattern string, h func(http.ResponseWriter, *http.Request, c.User) c.RouteError) { func (r *GenRouter) HandleFunc(pattern string, h func(http.ResponseWriter, *http.Request, *c.User) c.RouteError) {
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
r.extraRoutes[pattern] = h r.extraRoutes[pattern] = h
@ -1200,10 +1200,11 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
// Deal with the session stuff, etc. // Deal with the session stuff, etc.
user, ok := c.PreRoute(w, req) ucpy, ok := c.PreRoute(w, req)
if !ok { if !ok {
return return
} }
user := &ucpy
user.LastAgent = agent user.LastAgent = agent
if c.Dev.SuperDebug { if c.Dev.SuperDebug {
r.requestLogger.Print( r.requestLogger.Print(
@ -1240,33 +1241,33 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
//c.StoppedServer("Profile end") //c.StoppedServer("Profile end")
} }
func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c.User, prefix, extraData string) /*(id int, orerr */c.RouteError/*)*/ { func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *c.User, prefix, extraData string) /*(id int, orerr */c.RouteError/*)*/ {
var err c.RouteError var err c.RouteError
cn := uutils.Nanotime() cn := uutils.Nanotime()
switch(prefix) { switch(prefix) {
case "/overview": case "/overview":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
err = routes.Overview(w,req,user,h) err = routes.Overview(w,req,user,h)
co.RouteViewCounter.Bump3(1, cn) co.RouteViewCounter.Bump3(1, cn)
case "/pages": case "/pages":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
err = routes.CustomPage(w,req,user,h,extraData) err = routes.CustomPage(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(2, cn) co.RouteViewCounter.Bump3(2, cn)
case "/forums": case "/forums":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
err = routes.ForumList(w,req,user,h) err = routes.ForumList(w,req,user,h)
co.RouteViewCounter.Bump3(3, cn) co.RouteViewCounter.Bump3(3, cn)
case "/forum": case "/forum":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -1335,7 +1336,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
case "/topics": case "/topics":
switch(req.URL.Path) { switch(req.URL.Path) {
case "/topics/most-viewed/": case "/topics/most-viewed/":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -1347,14 +1348,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
err = routes.CreateTopic(w,req,user,h,extraData) err = routes.CreateTopic(w,req,user,h,extraData)
co.RouteViewCounter.Bump3(14, cn) co.RouteViewCounter.Bump3(14, cn)
default: default:
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -1888,7 +1889,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -1900,7 +1901,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -1968,7 +1969,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -1993,7 +1994,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2005,7 +2006,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2043,7 +2044,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2058,7 +2059,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2070,7 +2071,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2082,7 +2083,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2094,7 +2095,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2106,7 +2107,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2118,7 +2119,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2182,7 +2183,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2207,7 +2208,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2228,7 +2229,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
co.RouteViewCounter.Bump3(122, cn) co.RouteViewCounter.Bump3(122, cn)
default: default:
req.URL.Path += extraData req.URL.Path += extraData
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2282,7 +2283,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
return err return err
} }
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2471,7 +2472,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData) err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData)
co.RouteViewCounter.Bump3(140, cn) co.RouteViewCounter.Bump3(140, cn)
default: default:
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2644,14 +2645,14 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
case "/accounts": case "/accounts":
switch(req.URL.Path) { switch(req.URL.Path) {
case "/accounts/login/": case "/accounts/login/":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
err = routes.AccountLogin(w,req,user,h) err = routes.AccountLogin(w,req,user,h)
co.RouteViewCounter.Bump3(154, cn) co.RouteViewCounter.Bump3(154, cn)
case "/accounts/create/": case "/accounts/create/":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2679,7 +2680,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
err = routes.AccountLoginSubmit(w,req,user) err = routes.AccountLoginSubmit(w,req,user)
co.RouteViewCounter.Bump3(157, cn) co.RouteViewCounter.Bump3(157, cn)
case "/accounts/mfa_verify/": case "/accounts/mfa_verify/":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2702,7 +2703,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
err = routes.AccountRegisterSubmit(w,req,user) err = routes.AccountRegisterSubmit(w,req,user)
co.RouteViewCounter.Bump3(160, cn) co.RouteViewCounter.Bump3(160, cn)
case "/accounts/password-reset/": case "/accounts/password-reset/":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }
@ -2717,7 +2718,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
err = routes.AccountPasswordResetSubmit(w,req,user) err = routes.AccountPasswordResetSubmit(w,req,user)
co.RouteViewCounter.Bump3(162, cn) co.RouteViewCounter.Bump3(162, cn)
case "/accounts/password-reset/token/": case "/accounts/password-reset/token/":
h, err := c.UserCheckNano(w,req,&user,cn) h, err := c.UserCheckNano(w,req,user,cn)
if err != nil { if err != nil {
return err return err
} }

View File

@ -17,7 +17,7 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
e "github.com/Azareal/Gosora/extend" e "github.com/Azareal/Gosora/extend"
"github.com/Azareal/Gosora/install" "github.com/Azareal/Gosora/install"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
"github.com/Azareal/Gosora/routes" "github.com/Azareal/Gosora/routes"
) )
@ -151,7 +151,7 @@ func BenchmarkTopicAdminRouteParallel(b *testing.B) {
b.Fatal(err) b.Fatal(err)
} }
//w.Body.Reset() //w.Body.Reset()
routes.ViewTopic(w, reqAdmin, user, head, "1") routes.ViewTopic(w, reqAdmin, &user, head, "1")
if w.Code != 200 { if w.Code != 200 {
b.Log(w.Body) b.Log(w.Body)
b.Fatal("HTTP Error!") b.Fatal("HTTP Error!")
@ -287,7 +287,7 @@ func BenchmarkTopicGuestRouteParallel(b *testing.B) {
b.Fatal(err) b.Fatal(err)
} }
//w.Body.Reset() //w.Body.Reset()
routes.ViewTopic(w, req, user, head, "1") routes.ViewTopic(w, req, &user, head, "1")
if w.Code != 200 { if w.Code != 200 {
b.Log(w.Body) b.Log(w.Body)
b.Fatal("HTTP Error!") b.Fatal("HTTP Error!")
@ -314,7 +314,7 @@ func BenchmarkTopicGuestRouteParallelDebugMode(b *testing.B) {
b.Fatal(err) b.Fatal(err)
} }
//w.Body.Reset() //w.Body.Reset()
routes.ViewTopic(w, req, user, head, "1") routes.ViewTopic(w, req, &user, head, "1")
if w.Code != 200 { if w.Code != 200 {
b.Log(w.Body) b.Log(w.Body)
b.Fatal("HTTP Error!") b.Fatal("HTTP Error!")
@ -940,12 +940,12 @@ func BenchmarkParserSerial(b *testing.B) {
} }
} }
} }
f("empty_post","") f("empty_post", "")
f("short_post","Hey everyone, how's it going?") f("short_post", "Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)") f("one_smily", "Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)") f("five_smilies", "Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)") f("ten_smilies", "Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)") f("twenty_smilies", "Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
} }
func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) { func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) {
@ -957,15 +957,15 @@ func BenchmarkBBCodePluginWithRegexpSerial(b *testing.B) {
} }
}) })
} }
f("empty_post","") f("empty_post", "")
f("short_post","Hey everyone, how's it going?") f("short_post", "Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)") f("one_smily", "Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)") f("five_smilies", "Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)") f("ten_smilies", "Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)") f("twenty_smilies", "Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
f("one_bold","[b]H[/b]ey everyone, how's it going?") f("one_bold", "[b]H[/b]ey everyone, how's it going?")
f("five_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?") f("five_bold", "[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
f("ten_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?") f("ten_bold", "[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
} }
func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) { func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) {
@ -977,15 +977,15 @@ func BenchmarkBBCodePluginWithoutCodeTagSerial(b *testing.B) {
} }
}) })
} }
f("empty_post","") f("empty_post", "")
f("short_post","Hey everyone, how's it going?") f("short_post", "Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)") f("one_smily", "Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)") f("five_smilies", "Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)") f("ten_smilies", "Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)") f("twenty_smilies", "Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
f("one_bold","[b]H[/b]ey everyone, how's it going?") f("one_bold", "[b]H[/b]ey everyone, how's it going?")
f("five_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?") f("five_bold", "[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
f("ten_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?") f("ten_bold", "[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
} }
func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) { func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) {
@ -997,15 +997,15 @@ func BenchmarkBBCodePluginWithFullParserSerial(b *testing.B) {
} }
}) })
} }
f("empty_post","") f("empty_post", "")
f("short_post","Hey everyone, how's it going?") f("short_post", "Hey everyone, how's it going?")
f("one_smily","Hey everyone, how's it going? :)") f("one_smily", "Hey everyone, how's it going? :)")
f("five_smilies","Hey everyone, how's it going? :):):):):)") f("five_smilies", "Hey everyone, how's it going? :):):):):)")
f("ten_smilies","Hey everyone, how's it going? :):):):):):):):):):)") f("ten_smilies", "Hey everyone, how's it going? :):):):):):):):):):)")
f("twenty_smilies","Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)") f("twenty_smilies", "Hey everyone, how's it going? :):):):):):):):):):):):):):):):):):):):)")
f("one_bold","[b]H[/b]ey everyone, how's it going?") f("one_bold", "[b]H[/b]ey everyone, how's it going?")
f("five_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?") f("five_bold", "[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b]eryone, how's it going?")
f("ten_bold","[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?") f("ten_bold", "[b]H[/b][b]e[/b][b]y[/b] [b]e[/b][b]v[/b][b]e[/b][b]r[/b][b]y[/b][b]o[/b][b]n[/b]e, how's it going?")
} }
func TestLevels(t *testing.T) { func TestLevels(t *testing.T) {

View File

@ -391,30 +391,30 @@ func TestPermsMiddleware(t *testing.T) {
dummyRequest := httptest.NewRequest("", "/forum/1", bytesBuffer) dummyRequest := httptest.NewRequest("", "/forum/1", bytesBuffer)
user := c.BlankUser() user := c.BlankUser()
ferr := c.SuperModOnly(dummyResponseRecorder, dummyRequest, *user) ferr := c.SuperModOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr != nil, "Blank users shouldn't be supermods") expect(t, ferr != nil, "Blank users shouldn't be supermods")
user.IsSuperMod = false user.IsSuperMod = false
ferr = c.SuperModOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.SuperModOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr != nil, "Non-supermods shouldn't be allowed through supermod gates") expect(t, ferr != nil, "Non-supermods shouldn't be allowed through supermod gates")
user.IsSuperMod = true user.IsSuperMod = true
ferr = c.SuperModOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.SuperModOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr == nil, "Supermods should be allowed through supermod gates") expect(t, ferr == nil, "Supermods should be allowed through supermod gates")
// TODO: Loop over the Control Panel routes and make sure only supermods can get in // TODO: Loop over the Control Panel routes and make sure only supermods can get in
user = c.BlankUser() user = c.BlankUser()
ferr = c.MemberOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.MemberOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr != nil, "Blank users shouldn't be considered loggedin") expect(t, ferr != nil, "Blank users shouldn't be considered loggedin")
user.Loggedin = false user.Loggedin = false
ferr = c.MemberOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.MemberOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr != nil, "Guests shouldn't be able to access member areas") expect(t, ferr != nil, "Guests shouldn't be able to access member areas")
user.Loggedin = true user.Loggedin = true
ferr = c.MemberOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.MemberOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr == nil, "Logged in users should be able to access member areas") expect(t, ferr == nil, "Logged in users should be able to access member areas")
// TODO: Loop over the /user/ routes and make sure only members can access the ones other than /user/username // TODO: Loop over the /user/ routes and make sure only members can access the ones other than /user/username
@ -423,15 +423,15 @@ func TestPermsMiddleware(t *testing.T) {
user = c.BlankUser() user = c.BlankUser()
ferr = c.SuperAdminOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.SuperAdminOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr != nil, "Blank users shouldn't be considered super admins") expect(t, ferr != nil, "Blank users shouldn't be considered super admins")
user.IsSuperAdmin = false user.IsSuperAdmin = false
ferr = c.SuperAdminOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.SuperAdminOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr != nil, "Non-super admins shouldn't be allowed through the super admin gate") expect(t, ferr != nil, "Non-super admins shouldn't be allowed through the super admin gate")
user.IsSuperAdmin = true user.IsSuperAdmin = true
ferr = c.SuperAdminOnly(dummyResponseRecorder, dummyRequest, *user) ferr = c.SuperAdminOnly(dummyResponseRecorder, dummyRequest, user)
expect(t, ferr == nil, "Super admins should be allowed through super admin gates") expect(t, ferr == nil, "Super admins should be allowed through super admin gates")
// TODO: Make sure only super admins can access the backups route // TODO: Make sure only super admins can access the backups route

View File

@ -79,8 +79,8 @@ func main() {
//out += "\n\t\t\tid = " + strconv.Itoa(allRouteMap[route.Name]) //out += "\n\t\t\tid = " + strconv.Itoa(allRouteMap[route.Name])
out += runBefore(route.RunBefore, 4) out += runBefore(route.RunBefore, 4)
if !route.Action && !route.NoHead { if !route.Action && !route.NoHead {
//out += "\n\t\t\th, err := c.UserCheck(w,req,&user)" //out += "\n\t\t\th, err := c.UserCheck(w,req,user)"
out += "\n\t\t\th, err := c.UserCheckNano(w,req,&user,cn)" out += "\n\t\t\th, err := c.UserCheckNano(w,req,user,cn)"
out += "\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}" out += "\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}"
vcpy := route.Vars vcpy := route.Vars
route.Vars = []string{"h"} route.Vars = []string{"h"}
@ -151,8 +151,8 @@ func main() {
} }
} }
if !route.Action && !route.NoHead && !group.NoHead { if !route.Action && !route.NoHead && !group.NoHead {
//out += "\n\t\t\t\th, err := c.UserCheck(w,req,&user)" //out += "\n\t\t\t\th, err := c.UserCheck(w,req,user)"
out += "\n\t\t\t\th, err := c.UserCheckNano(w,req,&user,cn)" out += "\n\t\t\t\th, err := c.UserCheckNano(w,req,user,cn)"
out += "\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}" out += "\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}"
vcpy := route.Vars vcpy := route.Vars
route.Vars = []string{"h"} route.Vars = []string{"h"}
@ -179,8 +179,8 @@ func main() {
//out += "\n\t\t\t\t\tid = " + strconv.Itoa(allRouteMap[defaultRoute.Name]) //out += "\n\t\t\t\t\tid = " + strconv.Itoa(allRouteMap[defaultRoute.Name])
out += runBefore(defaultRoute.RunBefore, 4) out += runBefore(defaultRoute.RunBefore, 4)
if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead { if !defaultRoute.Action && !defaultRoute.NoHead && !group.NoHead {
//out += "\n\t\t\t\t\th, err := c.UserCheck(w,req,&user)" //out += "\n\t\t\t\t\th, err := c.UserCheck(w,req,user)"
out += "\n\t\t\t\t\th, err := c.UserCheckNano(w,req,&user,cn)" out += "\n\t\t\t\t\th, err := c.UserCheckNano(w,req,user,cn)"
out += "\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}" 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 vcpy := defaultRoute.Vars
defaultRoute.Vars = []string{"h"} defaultRoute.Vars = []string{"h"}
@ -503,7 +503,7 @@ func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) {
type GenRouter struct { type GenRouter struct {
UploadHandler func(http.ResponseWriter, *http.Request) UploadHandler func(http.ResponseWriter, *http.Request)
extraRoutes map[string]func(http.ResponseWriter, *http.Request, c.User) c.RouteError extraRoutes map[string]func(http.ResponseWriter, *http.Request, *c.User) c.RouteError
requestLogger *log.Logger requestLogger *log.Logger
sync.RWMutex sync.RWMutex
@ -520,12 +520,12 @@ func NewGenRouter(uploads http.Handler) (*GenRouter, error) {
writ := NewWriterIntercept(w) writ := NewWriterIntercept(w)
http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req) http.StripPrefix("/uploads/",uploads).ServeHTTP(writ,req)
}, },
extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, c.User) c.RouteError), extraRoutes: make(map[string]func(http.ResponseWriter, *http.Request, *c.User) c.RouteError),
requestLogger: log.New(f, "", log.LstdFlags), requestLogger: log.New(f, "", log.LstdFlags),
}, nil }, nil
} }
func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *http.Request, user c.User) { func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *http.Request, user *c.User) {
if err.Handled() { if err.Handled() {
return return
} }
@ -539,7 +539,7 @@ func (r *GenRouter) handleError(err c.RouteError, w http.ResponseWriter, req *ht
func (r *GenRouter) Handle(_ string, _ http.Handler) { func (r *GenRouter) Handle(_ string, _ http.Handler) {
} }
func (r *GenRouter) HandleFunc(pattern string, h func(http.ResponseWriter, *http.Request, c.User) c.RouteError) { func (r *GenRouter) HandleFunc(pattern string, h func(http.ResponseWriter, *http.Request, *c.User) c.RouteError) {
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
r.extraRoutes[pattern] = h r.extraRoutes[pattern] = h
@ -881,10 +881,11 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
} }
// Deal with the session stuff, etc. // Deal with the session stuff, etc.
user, ok := c.PreRoute(w, req) ucpy, ok := c.PreRoute(w, req)
if !ok { if !ok {
return return
} }
user := &ucpy
user.LastAgent = agent user.LastAgent = agent
if c.Dev.SuperDebug { if c.Dev.SuperDebug {
r.requestLogger.Print( r.requestLogger.Print(
@ -921,7 +922,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
//c.StoppedServer("Profile end") //c.StoppedServer("Profile end")
} }
func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c.User, prefix, extraData string) /*(id int, orerr */c.RouteError/*)*/ { func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user *c.User, prefix, extraData string) /*(id int, orerr */c.RouteError/*)*/ {
var err c.RouteError var err c.RouteError
cn := uutils.Nanotime() cn := uutils.Nanotime()
switch(prefix) {` + out + ` switch(prefix) {` + out + `

View File

@ -33,7 +33,7 @@ var phraseLoginAlerts = []byte(`{"msgs":[{"msg":"Login to see your alerts","path
// TODO: Refactor this endpoint // TODO: Refactor this endpoint
// TODO: Move this into the routes package // TODO: Move this into the routes package
func routeAPI(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func routeAPI(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
// TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats // TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
err := r.ParseForm() err := r.ParseForm()
@ -210,7 +210,7 @@ var phraseWhitelist = []string{
"panel", // We're going to handle this specially below as this is a security boundary "panel", // We're going to handle this specially below as this is a security boundary
} }
func routeAPIPhrases(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func routeAPIPhrases(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
// TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats // TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats
h := w.Header() h := w.Header()
h.Set("Content-Type", "application/json") h.Set("Content-Type", "application/json")
@ -343,16 +343,14 @@ func routeAPIPhrases(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
// A dedicated function so we can shake things up every now and then to make the token harder to parse // A dedicated function so we can shake things up every now and then to make the token harder to parse
// TODO: Are we sure we want to do this by ID, just in case we reuse this and have multiple antispams on the page? // TODO: Are we sure we want to do this by ID, just in case we reuse this and have multiple antispams on the page?
func routeJSAntispam(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func routeJSAntispam(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
h := sha256.New() h := sha256.New()
h.Write([]byte(c.JSTokenBox.Load().(string))) h.Write([]byte(c.JSTokenBox.Load().(string)))
h.Write([]byte(user.GetIP())) h.Write([]byte(user.GetIP()))
jsToken := hex.EncodeToString(h.Sum(nil)) jsToken := hex.EncodeToString(h.Sum(nil))
innerCode := "`document.getElementByld('golden-watch').value = '" + jsToken + "';`" innerCode := "`document.getElementByld('golden-watch').value='" + jsToken + "';`"
io.WriteString(w, `let hihi = `+innerCode+`; io.WriteString(w, `let hihi=`+innerCode+`;hihi=hihi.replace('ld','Id');eval(hihi);`)
hihi = hihi.replace('ld','Id');
eval(hihi);`)
return nil return nil
} }

View File

@ -20,7 +20,7 @@ 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{}
func AccountLogin(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountLogin(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
if user.Loggedin { if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, user)
} }
@ -31,7 +31,7 @@ func AccountLogin(w http.ResponseWriter, r *http.Request, user c.User, h *c.Head
// TODO: Log failed attempted logins? // TODO: Log failed attempted logins?
// TODO: Lock IPS out if they have too many failed attempts? // TODO: Lock IPS out if they have too many failed attempts?
// TODO: Log unusual countries in comparison to the country a user usually logs in from? Alert the user about this? // TODO: Log unusual countries in comparison to the country a user usually logs in from? Alert the user about this?
func AccountLoginSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountLoginSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
if user.Loggedin { if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, user)
} }
@ -67,13 +67,13 @@ func AccountLoginSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return nil return nil
} }
return loginSuccess(uid, w, r, &user) return loginSuccess(uid, w, r, user)
} }
func loginSuccess(uid int, w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError { func loginSuccess(uid int, w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
userPtr, err := c.Users.Get(uid) userPtr, err := c.Users.Get(uid)
if err != nil { if err != nil {
return c.LocalError("Bad account", w, r, *user) return c.LocalError("Bad account", w, r, user)
} }
*user = *userPtr *user = *userPtr
@ -105,7 +105,7 @@ func extractCookie(name string, r *http.Request) (string, error) {
return cookie.Value, nil return cookie.Value, nil
} }
func mfaGetCookies(r *http.Request) (uid int, provSession string, signedSession string, err error) { func mfaGetCookies(r *http.Request) (uid int, provSession, signedSession string, err error) {
suid, err := extractCookie("uid", r) suid, err := extractCookie("uid", r)
if err != nil { if err != nil {
return 0, "", "", err return 0, "", "", err
@ -122,7 +122,7 @@ func mfaGetCookies(r *http.Request) (uid int, provSession string, signedSession
return uid, provSession, signedSession, err return uid, provSession, signedSession, err
} }
func mfaVerifySession(provSession string, signedSession string, uid int) bool { func mfaVerifySession(provSession, signedSession string, uid int) bool {
h := sha256.New() h := sha256.New()
h.Write([]byte(c.SessionSigningKeyBox.Load().(string))) h.Write([]byte(c.SessionSigningKeyBox.Load().(string)))
h.Write([]byte(provSession)) h.Write([]byte(provSession))
@ -140,50 +140,50 @@ 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 c.User, h *c.Header) c.RouteError { func AccountLoginMFAVerify(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
if user.Loggedin { if u.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, u)
} }
h.Title = p.GetTitlePhrase("login_mfa_verify") h.Title = p.GetTitlePhrase("login_mfa_verify")
uid, provSession, signedSession, err := mfaGetCookies(r) uid, provSession, signedSession, err := mfaGetCookies(r)
if err != nil { if err != nil {
return c.LocalError("Invalid cookie", w, r, user) return c.LocalError("Invalid cookie", w, r, u)
} }
if !mfaVerifySession(provSession, signedSession, uid) { if !mfaVerifySession(provSession, signedSession, uid) {
return c.LocalError("Invalid session", w, r, user) return c.LocalError("Invalid session", w, r, u)
} }
return renderTemplate("login_mfa_verify", w, r, h, c.Page{h, tList, nil}) return renderTemplate("login_mfa_verify", w, r, h, c.Page{h, tList, nil})
} }
func AccountLoginMFAVerifySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountLoginMFAVerifySubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
uid, provSession, signedSession, err := mfaGetCookies(r) uid, provSession, signedSession, err := mfaGetCookies(r)
if err != nil { if err != nil {
return c.LocalError("Invalid cookie", w, r, user) return c.LocalError("Invalid cookie", w, r, u)
} }
if !mfaVerifySession(provSession, signedSession, uid) { if !mfaVerifySession(provSession, signedSession, uid) {
return c.LocalError("Invalid session", w, r, user) return c.LocalError("Invalid session", w, r, u)
} }
token := r.PostFormValue("mfa_token") token := r.PostFormValue("mfa_token")
err = c.Auth.ValidateMFAToken(token, uid) err = c.Auth.ValidateMFAToken(token, uid)
if err != nil { if err != nil {
return c.LocalError(err.Error(), w, r, user) return c.LocalError(err.Error(), w, r, u)
} }
return loginSuccess(uid, w, r, &user) return loginSuccess(uid, w, r, u)
} }
func AccountLogout(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountLogout(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
c.Auth.Logout(w, user.ID) c.Auth.Logout(w, u.ID)
http.Redirect(w, r, "/", http.StatusSeeOther) http.Redirect(w, r, "/", http.StatusSeeOther)
return nil return nil
} }
func AccountRegister(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountRegister(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
if user.Loggedin { if u.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, u)
} }
h.Title = p.GetTitlePhrase("register") h.Title = p.GetTitlePhrase("register")
h.AddScriptAsync("register.js") h.AddScriptAsync("register.js")
@ -199,8 +199,8 @@ func isNumeric(data string) (numeric bool) {
return true return true
} }
func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountRegisterSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
headerLite, _ := c.SimpleUserCheck(w, r, &user) headerLite, _ := c.SimpleUserCheck(w, r, user)
// TODO: Should we push multiple validation errors to the user instead of just one? // TODO: Should we push multiple validation errors to the user instead of just one?
regSuccess := true regSuccess := true
@ -361,8 +361,8 @@ func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request,
h.AddScriptAsync("account.js") h.AddScriptAsync("account.js")
} }
func AccountEdit(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func AccountEdit(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header) c.RouteError {
accountEditHead("account", w, r, &user, header) accountEditHead("account", w, r, user, header)
if r.FormValue("avatar_updated") == "1" { if r.FormValue("avatar_updated") == "1" {
header.AddNotice("account_avatar_updated") header.AddNotice("account_avatar_updated")
} else if r.FormValue("username_updated") == "1" { } else if r.FormValue("username_updated") == "1" {
@ -391,14 +391,14 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user c.User, header *c.
} }
//edit_password //edit_password
func AccountEditPassword(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountEditPassword(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
accountEditHead("account_password", w, r, &user, h) accountEditHead("account_password", w, r, u, h)
return renderTemplate("account_own_edit_password", w, r, h, c.Page{h, tList, nil}) return renderTemplate("account_own_edit_password", w, r, h, c.Page{h, tList, nil})
} }
// TODO: Require re-authentication if the user hasn't logged in in a while // TODO: Require re-authentication if the user hasn't logged in in a while
func AccountEditPasswordSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditPasswordSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -433,8 +433,8 @@ func AccountEditPasswordSubmit(w http.ResponseWriter, r *http.Request, user c.Us
return nil return nil
} }
func AccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -460,8 +460,8 @@ func AccountEditAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User
return nil return nil
} }
func AccountEditRevokeAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditRevokeAvatarSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -475,33 +475,33 @@ func AccountEditRevokeAvatarSubmit(w http.ResponseWriter, r *http.Request, user
return nil return nil
} }
func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditUsernameSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, u)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
newUsername := c.SanitiseSingleLine(r.PostFormValue("account-new-username")) newUsername := c.SanitiseSingleLine(r.PostFormValue("account-new-username"))
if newUsername == "" { if newUsername == "" {
return c.LocalError("You can't leave your username blank", w, r, user) return c.LocalError("You can't leave your username blank", w, r, u)
} }
err := user.ChangeName(newUsername) err := u.ChangeName(newUsername)
if err != nil { if err != nil {
return c.LocalError("Unable to change the username. Does someone else already have this name?", w, r, user) return c.LocalError("Unable to change the username. Does someone else already have this name?", w, r, u)
} }
http.Redirect(w, r, "/user/edit/?username_updated=1", http.StatusSeeOther) http.Redirect(w, r, "/user/edit/?username_updated=1", http.StatusSeeOther)
return nil return nil
} }
func AccountEditMFA(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountEditMFA(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
accountEditHead("account_mfa", w, r, &user, h) accountEditHead("account_mfa", w, r, u, h)
mfaItem, err := c.MFAstore.Get(user.ID) mfaItem, err := c.MFAstore.Get(u.ID)
if err != sql.ErrNoRows && err != nil { if err != sql.ErrNoRows && err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} else if err == sql.ErrNoRows { } else if err == sql.ErrNoRows {
return c.LocalError("Two-factor authentication hasn't been setup on your account", w, r, user) return c.LocalError("Two-factor authentication hasn't been setup on your account", w, r, u)
} }
pi := c.Page{h, tList, mfaItem.Scratch} pi := c.Page{h, tList, mfaItem.Scratch}
@ -509,15 +509,15 @@ func AccountEditMFA(w http.ResponseWriter, r *http.Request, user c.User, h *c.He
} }
// 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 c.User, h *c.Header) c.RouteError { func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
accountEditHead("account_mfa_setup", w, r, &user, h) accountEditHead("account_mfa_setup", w, r, u, h)
// Flash an error if mfa is already setup // Flash an error if mfa is already setup
_, err := c.MFAstore.Get(user.ID) _, err := c.MFAstore.Get(u.ID)
if err != sql.ErrNoRows && err != nil { if err != sql.ErrNoRows && err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} else if err != sql.ErrNoRows { } else if err != sql.ErrNoRows {
return c.LocalError("You have already setup two-factor authentication", w, r, user) return c.LocalError("You have already setup two-factor authentication", w, r, u)
} }
// TODO: Entitise this? // TODO: Entitise this?
@ -531,8 +531,8 @@ func AccountEditMFASetup(w http.ResponseWriter, r *http.Request, user c.User, h
} }
// Form should bounce the random mfa secret back and the otp to be verified server-side to reduce the chances of a bug arising on the JS side which makes every code mismatch // Form should bounce the random mfa secret back and the otp to be verified server-side to reduce the chances of a bug arising on the JS side which makes every code mismatch
func AccountEditMFASetupSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditMFASetupSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -568,8 +568,8 @@ func AccountEditMFASetupSubmit(w http.ResponseWriter, r *http.Request, user c.Us
} }
// TODO: Implement this // TODO: Implement this
func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -591,20 +591,20 @@ func AccountEditMFADisableSubmit(w http.ResponseWriter, r *http.Request, user c.
return nil return nil
} }
func AccountEditPrivacy(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountEditPrivacy(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
accountEditHead("account_privacy", w, r, &user, h) accountEditHead("account_privacy", w, r, u, h)
profileComments := false profileComments := false
receiveConvos := false receiveConvos := false
enableEmbeds := !c.DefaultParseSettings.NoEmbed enableEmbeds := !c.DefaultParseSettings.NoEmbed
if user.ParseSettings != nil { if u.ParseSettings != nil {
enableEmbeds = !user.ParseSettings.NoEmbed enableEmbeds = !u.ParseSettings.NoEmbed
} }
pi := c.Account{h, "privacy", "account_own_edit_privacy", c.AccountPrivacyPage{h, profileComments, receiveConvos, enableEmbeds}} pi := c.Account{h, "privacy", "account_own_edit_privacy", c.AccountPrivacyPage{h, profileComments, receiveConvos, enableEmbeds}}
return renderTemplate("account", w, r, h, pi) return renderTemplate("account", w, r, h, pi)
} }
func AccountEditPrivacySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditPrivacySubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
//headerLite, _ := c.SimpleUserCheck(w, r, &user) //headerLite, _ := c.SimpleUserCheck(w, r, user)
sEnableEmbeds := r.FormValue("enable_embeds") sEnableEmbeds := r.FormValue("enable_embeds")
enableEmbeds, err := strconv.Atoi(sEnableEmbeds) enableEmbeds, err := strconv.Atoi(sEnableEmbeds)
@ -612,7 +612,7 @@ func AccountEditPrivacySubmit(w http.ResponseWriter, r *http.Request, user c.Use
return c.LocalError("enable_embeds must be 0 or 1", w, r, user) return c.LocalError("enable_embeds must be 0 or 1", w, r, user)
} }
if sEnableEmbeds != r.FormValue("o_enable_embeds") { if sEnableEmbeds != r.FormValue("o_enable_embeds") {
err = (&user).UpdatePrivacy(enableEmbeds) err = user.UpdatePrivacy(enableEmbeds)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -622,9 +622,9 @@ func AccountEditPrivacySubmit(w http.ResponseWriter, r *http.Request, user c.Use
return nil return nil
} }
func AccountEditEmail(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountEditEmail(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
accountEditHead("account_email", w, r, &user, h) accountEditHead("account_email", w, r, user, h)
emails, err := c.Emails.GetEmailsByUser(&user) emails, err := c.Emails.GetEmailsByUser(user)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -646,9 +646,9 @@ func AccountEditEmail(w http.ResponseWriter, r *http.Request, user c.User, h *c.
return renderTemplate("account", w, r, h, pi) return renderTemplate("account", w, r, h, pi)
} }
func AccountEditEmailAddSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditEmailAddSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
email := r.PostFormValue("email") email := r.PostFormValue("email")
_, err := c.Emails.Get(&user, email) _, err := c.Emails.Get(user, email)
if err == nil { if err == nil {
return c.LocalError("You have already added this email.", w, r, user) return c.LocalError("You have already added this email.", w, r, user)
} else if err != sql.ErrNoRows && err != nil { } else if err != sql.ErrNoRows && err != nil {
@ -677,12 +677,12 @@ func AccountEditEmailAddSubmit(w http.ResponseWriter, r *http.Request, user c.Us
return nil return nil
} }
func AccountEditEmailRemoveSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountEditEmailRemoveSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
headerLite, _ := c.SimpleUserCheck(w, r, &user) headerLite, _ := c.SimpleUserCheck(w, r, user)
email := r.PostFormValue("email") email := r.PostFormValue("email")
// Quick and dirty check // Quick and dirty check
_, err := c.Emails.Get(&user, email) _, err := c.Emails.Get(user, email)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.LocalError("This email isn't set on this user.", w, r, user) return c.LocalError("This email isn't set on this user.", w, r, user)
} else if err != nil { } else if err != nil {
@ -702,8 +702,8 @@ func AccountEditEmailRemoveSubmit(w http.ResponseWriter, r *http.Request, user c
} }
// TODO: Should we make this an AnonAction so someone can do this without being logged in? // TODO: Should we make this an AnonAction so someone can do this without being logged in?
func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user c.User, token string) c.RouteError { func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user *c.User, token string) c.RouteError {
header, ferr := c.UserCheck(w, r, &user) header, ferr := c.UserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -713,7 +713,7 @@ func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user c.
} }
targetEmail := c.Email{UserID: user.ID} targetEmail := c.Email{UserID: user.ID}
emails, err := c.Emails.GetEmailsByUser(&user) emails, err := c.Emails.GetEmailsByUser(user)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.LocalError("A verification email was never sent for you!", w, r, user) return c.LocalError("A verification email was never sent for you!", w, r, user)
} else if err != nil { } else if err != nil {
@ -760,13 +760,13 @@ func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user c.
return nil return nil
} }
func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountLogins(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
accountEditHead("account_logins", w, r, &user, h) accountEditHead("account_logins", w, r, u, h)
page, _ := strconv.Atoi(r.FormValue("page")) page, _ := strconv.Atoi(r.FormValue("page"))
perPage := 12 perPage := 12
offset, page, lastPage := c.PageOffset(c.LoginLogs.CountUser(user.ID), page, perPage) offset, page, lastPage := c.PageOffset(c.LoginLogs.CountUser(u.ID), page, perPage)
logs, err := c.LoginLogs.GetOffset(user.ID, offset, perPage) logs, err := c.LoginLogs.GetOffset(u.ID, offset, perPage)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -776,8 +776,8 @@ func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, h *c.Hea
return renderTemplate("account", w, r, h, pi) return renderTemplate("account", w, r, h, pi)
} }
func AccountBlocked(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountBlocked(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
accountEditHead("account_blocked", w, r, &user, h) accountEditHead("account_blocked", w, r, user, h)
page, _ := strconv.Atoi(r.FormValue("page")) page, _ := strconv.Atoi(r.FormValue("page"))
perPage := 12 perPage := 12
offset, page, lastPage := c.PageOffset(c.UserBlocks.BlockedByCount(user.ID), page, perPage) offset, page, lastPage := c.PageOffset(c.UserBlocks.BlockedByCount(user.ID), page, perPage)
@ -800,7 +800,7 @@ func AccountBlocked(w http.ResponseWriter, r *http.Request, user c.User, h *c.He
return renderTemplate("account", w, r, h, pi) return renderTemplate("account", w, r, h, pi)
} }
func LevelList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func LevelList(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
h.Title = p.GetTitlePhrase("account_level_list") h.Title = p.GetTitlePhrase("account_level_list")
fScores := c.GetLevels(20) fScores := c.GetLevels(20)
@ -822,16 +822,16 @@ func LevelList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header)
return renderTemplate("level_list", w, r, h, c.LevelListPage{h, levels[1:]}) return renderTemplate("level_list", w, r, h, c.LevelListPage{h, levels[1:]})
} }
func Alerts(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func Alerts(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
return nil return nil
} }
func AccountPasswordReset(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func AccountPasswordReset(w http.ResponseWriter, r *http.Request, u *c.User, h *c.Header) c.RouteError {
if user.Loggedin { if u.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, u)
} }
if !c.Site.EnableEmails { if !c.Site.EnableEmails {
return c.LocalError(p.GetNoticePhrase("account_mail_disabled"), w, r, user) return c.LocalError(p.GetNoticePhrase("account_mail_disabled"), w, r, u)
} }
if r.FormValue("email_sent") == "1" { if r.FormValue("email_sent") == "1" {
h.AddNotice("password_reset_email_sent") h.AddNotice("password_reset_email_sent")
@ -841,7 +841,7 @@ func AccountPasswordReset(w http.ResponseWriter, r *http.Request, user c.User, h
} }
// TODO: Ratelimit this // TODO: Ratelimit this
func AccountPasswordResetSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountPasswordResetSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
if user.Loggedin { if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, user)
} }
@ -909,7 +909,7 @@ func AccountPasswordResetSubmit(w http.ResponseWriter, r *http.Request, user c.U
return nil return nil
} }
func AccountPasswordResetToken(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func AccountPasswordResetToken(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header) c.RouteError {
if user.Loggedin { if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, user)
} }
@ -940,7 +940,7 @@ func AccountPasswordResetToken(w http.ResponseWriter, r *http.Request, user c.Us
return renderTemplate("password_reset_token", w, r, header, c.ResetPage{header, uid, html.EscapeString(token), mfa}) return renderTemplate("password_reset_token", w, r, header, c.ResetPage{header, uid, html.EscapeString(token), mfa})
} }
func AccountPasswordResetTokenSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AccountPasswordResetTokenSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
if user.Loggedin { if user.Loggedin {
return c.LocalError("You're already logged in.", w, r, user) return c.LocalError("You're already logged in.", w, r, user)
} }

View File

@ -235,7 +235,7 @@ type MeSite struct {
// APIMe returns information about the current logged-in user // APIMe returns information about the current logged-in user
// TODO: Find some way to stop intermediaries from doing compression to avoid the BREACH attack // TODO: Find some way to stop intermediaries from doing compression to avoid the BREACH attack
// TODO: Decouple site settings into a different API? I'd like to avoid having too many requests, if possible, maybe we can use a different name for this? // TODO: Decouple site settings into a different API? I'd like to avoid having too many requests, if possible, maybe we can use a different name for this?
func APIMe(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func APIMe(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
// TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats // TODO: Don't make this too JSON dependent so that we can swap in newer more efficient formats
h := w.Header() h := w.Header()
h.Set("Content-Type", "application/json") h.Set("Content-Type", "application/json")
@ -243,7 +243,7 @@ func APIMe(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
// TODO: Use this header anywhere with a user check? // TODO: Use this header anywhere with a user check?
h.Set("Cache-Control", "private") h.Set("Cache-Control", "private")
me := JsonMe{(&user).Me(), MeSite{c.Site.MaxRequestSize}} me := JsonMe{u.Me(), MeSite{c.Site.MaxRequestSize}}
jsonBytes, err := json.Marshal(me) jsonBytes, err := json.Marshal(me)
if err != nil { if err != nil {
return c.InternalErrorJS(err, w, r) return c.InternalErrorJS(err, w, r)

View File

@ -29,7 +29,7 @@ func init() {
var maxAgeYear = "max-age=" + strconv.Itoa(int(c.Year)) var maxAgeYear = "max-age=" + strconv.Itoa(int(c.Year))
func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filename string) c.RouteError { func ShowAttachment(w http.ResponseWriter, r *http.Request, user *c.User, filename string) c.RouteError {
filename = c.Stripslashes(filename) filename = c.Stripslashes(filename)
ext := filepath.Ext("./attachs/" + filename) ext := filepath.Ext("./attachs/" + filename)
if !c.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) { if !c.AllowedFileExts.Contains(strings.TrimPrefix(ext, ".")) {
@ -52,7 +52,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
} }
if sectionTable == "forums" { if sectionTable == "forums" {
_, ferr := c.SimpleForumUserCheck(w, r, &user, sid) _, ferr := c.SimpleForumUserCheck(w, r, user, sid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -88,7 +88,7 @@ func ShowAttachment(w http.ResponseWriter, r *http.Request, user c.User, filenam
return nil return nil
} }
func deleteAttachment(w http.ResponseWriter, r *http.Request, user c.User, aid int, js bool) c.RouteError { func deleteAttachment(w http.ResponseWriter, r *http.Request, user *c.User, aid int, js bool) c.RouteError {
err := c.DeleteAttachment(aid) err := c.DeleteAttachment(aid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.NotFoundJSQ(w, r, nil, js) return c.NotFoundJSQ(w, r, nil, js)
@ -101,7 +101,7 @@ func deleteAttachment(w http.ResponseWriter, r *http.Request, user c.User, aid i
// TODO: Stop duplicating this code // TODO: Stop duplicating this code
// TODO: Use a transaction here // TODO: Use a transaction here
// TODO: Move this function to neutral ground // TODO: Move this function to neutral ground
func uploadAttachment(w http.ResponseWriter, r *http.Request, user c.User, sid int, stable string, oid int, otable, extra string) (pathMap map[string]string, rerr c.RouteError) { func uploadAttachment(w http.ResponseWriter, r *http.Request, user *c.User, sid int, stable string, oid int, otable, extra string) (pathMap map[string]string, rerr c.RouteError) {
pathMap = make(map[string]string) pathMap = make(map[string]string)
files, rerr := uploadFilesWithHash(w, r, user, "./attachs/") files, rerr := uploadFilesWithHash(w, r, user, "./attachs/")
if rerr != nil { if rerr != nil {

View File

@ -120,7 +120,7 @@ func renderTemplate3(tmplName, hookName string, w http.ResponseWriter, r *http.R
s := h.Stylesheets s := h.Stylesheets
h.Stylesheets = nil h.Stylesheets = nil
if r.FormValue("i") != "1" && h.CurrentUser.LastAgent != c.Semrush { if r.FormValue("i") != "1" && h.CurrentUser.LastAgent != c.Semrush {
c.PrepResources(&h.CurrentUser, h, h.Theme) c.PrepResources(h.CurrentUser, h, h.Theme)
for _, ss := range s { for _, ss := range s {
h.Stylesheets = append(h.Stylesheets, ss) h.Stylesheets = append(h.Stylesheets, ss)
} }
@ -146,7 +146,7 @@ func renderTemplate3(tmplName, hookName string, w http.ResponseWriter, r *http.R
} }
co.PerfCounter.Push(since /*, false*/) co.PerfCounter.Push(since /*, false*/)
} }
if c.RunPreRenderHook("pre_render_"+hookName, w, r, &h.CurrentUser, pi) { if c.RunPreRenderHook("pre_render_"+hookName, w, r, h.CurrentUser, pi) {
return nil return nil
} }
err := h.Theme.RunTmpl(tmplName, pi, w) err := h.Theme.RunTmpl(tmplName, pi, w)

View File

@ -14,8 +14,8 @@ import (
p "github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
func Convos(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func Convos(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
accountEditHead("convos", w, r, &user, h) accountEditHead("convos", w, r, user, h)
h.AddScript("convo.js") h.AddScript("convo.js")
h.AddSheet(h.Theme.Name + "/convo.css") h.AddSheet(h.Theme.Name + "/convo.css")
h.AddNotice("convo_dev") h.AddNotice("convo_dev")
@ -51,8 +51,8 @@ func Convos(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.
return renderTemplate("account", w, r, h, pi) return renderTemplate("account", w, r, h, pi)
} }
func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, scid string) c.RouteError { func Convo(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header, scid string) c.RouteError {
accountEditHead("convo", w, r, &user, header) accountEditHead("convo", w, r, user, header)
header.AddSheet(header.Theme.Name + "/convo.css") header.AddSheet(header.Theme.Name + "/convo.css")
header.AddNotice("convo_dev") header.AddNotice("convo_dev")
cid, err := strconv.Atoi(scid) cid, err := strconv.Atoi(scid)
@ -127,8 +127,8 @@ func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header
return renderTemplate("account", w, r, header, pi) return renderTemplate("account", w, r, header, pi)
} }
func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func ConvosCreate(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
accountEditHead("create_convo", w, r, &user, h) accountEditHead("create_convo", w, r, user, h)
if !user.Perms.UseConvos && !user.Perms.UseConvosOnlyWithMod { if !user.Perms.UseConvos && !user.Perms.UseConvosOnlyWithMod {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -146,8 +146,8 @@ func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Head
return renderTemplate("account", w, r, h, pi) return renderTemplate("account", w, r, h, pi)
} }
func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -225,7 +225,7 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
err = c.AddActivityAndNotifyAll(c.Alert{ActorID: user.ID, Event: "create", ElementType: "convo", ElementID: cid, Actor: &user}) err = c.AddActivityAndNotifyAll(c.Alert{ActorID: user.ID, Event: "create", ElementType: "convo", ElementID: cid, Actor: user})
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -234,8 +234,8 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return nil return nil
} }
/*func ConvosDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, scid string) c.RouteError { /*func ConvosDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, scid string) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -250,8 +250,8 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return nil return nil
}*/ }*/
func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, scid string) c.RouteError { func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user *c.User, scid string) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -293,7 +293,7 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
err = c.AddActivityAndNotifyAll(c.Alert{ActorID: user.ID, Event: "reply", ElementType: "convo", ElementID: cid, Actor: &user, Extra: strconv.Itoa(pid)}) err = c.AddActivityAndNotifyAll(c.Alert{ActorID: user.ID, Event: "reply", ElementType: "convo", ElementID: cid, Actor: user, Extra: strconv.Itoa(pid)})
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -302,8 +302,8 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
return nil return nil
} }
func ConvosDeleteReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, scpid string) c.RouteError { func ConvosDeleteReplySubmit(w http.ResponseWriter, r *http.Request, user *c.User, scpid string) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -355,8 +355,8 @@ func ConvosDeleteReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
return nil return nil
} }
func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, scpid string) c.RouteError { func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user *c.User, scpid string) c.RouteError {
_, ferr := c.SimpleUserCheck(w, r, &user) _, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -408,7 +408,7 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
return nil return nil
} }
func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, spid string) c.RouteError { func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header, spid string) c.RouteError {
h.Title = p.GetTitlePhrase("create_block") h.Title = p.GetTitlePhrase("create_block")
pid, err := strconv.Atoi(spid) pid, err := strconv.Atoi(spid)
if err != nil { if err != nil {
@ -425,7 +425,7 @@ func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user c.User, h
return renderTemplate("are_you_sure", w, r, h, pi) return renderTemplate("are_you_sure", w, r, h, pi)
} }
func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
pid, err := strconv.Atoi(spid) pid, err := strconv.Atoi(spid)
if err != nil { if err != nil {
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user) return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)
@ -449,7 +449,7 @@ func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user c.U
return nil return nil
} }
func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, spid string) c.RouteError { func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header, spid string) c.RouteError {
h.Title = p.GetTitlePhrase("remove_block") h.Title = p.GetTitlePhrase("remove_block")
pid, err := strconv.Atoi(spid) pid, err := strconv.Atoi(spid)
if err != nil { if err != nil {
@ -466,7 +466,7 @@ func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, user c.User, h
return renderTemplate("are_you_sure", w, r, h, pi) return renderTemplate("are_you_sure", w, r, h, pi)
} }
func RelationsBlockRemoveSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { func RelationsBlockRemoveSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
pid, err := strconv.Atoi(spid) pid, err := strconv.Atoi(spid)
if err != nil { if err != nil {
return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user) return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user)

View File

@ -11,14 +11,14 @@ import (
) )
// TODO: Retire this in favour of an alias for /topics/? // TODO: Retire this in favour of an alias for /topics/?
func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, sfid string) c.RouteError { func ViewForum(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header, sfid string) c.RouteError {
page, _ := strconv.Atoi(r.FormValue("page")) page, _ := strconv.Atoi(r.FormValue("page"))
_, fid, err := ParseSEOURL(sfid) _, fid, err := ParseSEOURL(sfid)
if err != nil { if err != nil {
return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, header) return c.SimpleError(p.GetErrorPhrase("url_id_must_be_integer"), w, r, header)
} }
ferr := c.ForumUserCheck(header, w, r, &user, fid) ferr := c.ForumUserCheck(header, w, r, user, fid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -8,8 +8,8 @@ import (
"github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/common/phrases"
) )
func ForumList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func ForumList(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
skip, rerr := h.Hooks.VhookSkippable("route_forum_list_start", w, r, &user, h) skip, rerr := h.Hooks.VhookSkippable("route_forum_list_start", w, r, user, h)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }

View File

@ -79,13 +79,13 @@ 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 c.User, h *c.Header) c.RouteError { func Overview(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
h.Title = phrases.GetTitlePhrase("overview") h.Title = phrases.GetTitlePhrase("overview")
h.Zone = "overview" h.Zone = "overview"
return renderTemplate("overview", w, r, h, c.Page{h, tList, nil}) return renderTemplate("overview", w, r, h, c.Page{h, tList, nil})
} }
func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, name string) c.RouteError { func CustomPage(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header, name string) c.RouteError {
h.Zone = "custom_page" h.Zone = "custom_page"
name = c.SanitiseSingleLine(name) name = c.SanitiseSingleLine(name)
page, err := c.Pages.GetByName(name) page, err := c.Pages.GetByName(name)
@ -108,8 +108,8 @@ func CustomPage(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header
} }
// TODO: Set the cookie domain // TODO: Set the cookie domain
func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ChangeTheme(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
//headerLite, _ := SimpleUserCheck(w, r, &user) //headerLite, _ := SimpleUserCheck(w, r, u)
// TODO: Rename js to something else, just in case we rewrite the JS side in WebAssembly? // TODO: Rename js to something else, just in case we rewrite the JS side in WebAssembly?
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
newTheme := c.SanitiseSingleLine(r.PostFormValue("theme")) newTheme := c.SanitiseSingleLine(r.PostFormValue("theme"))
@ -117,7 +117,7 @@ func ChangeTheme(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
theme, ok := c.Themes[newTheme] theme, ok := c.Themes[newTheme]
if !ok || theme.HideFromThemes { if !ok || theme.HideFromThemes {
return c.LocalErrorJSQ("That theme doesn't exist", w, r, user, js) return c.LocalErrorJSQ("That theme doesn't exist", w, r, u, js)
} }
cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)} cookie := http.Cookie{Name: "current_theme", Value: newTheme, Path: "/", MaxAge: int(c.Year)}

View File

@ -7,7 +7,7 @@ import (
"github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/common/phrases"
) )
func IPSearch(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func IPSearch(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
h.Title = phrases.GetTitlePhrase("ip_search") h.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 {

View File

@ -255,8 +255,8 @@ func PreAnalyticsDetail(w http.ResponseWriter, r *http.Request, user *c.User) (*
return bp, nil return bp, nil
} }
func AnalyticsViews(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsViews(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -295,8 +295,8 @@ func AnalyticsViews(w http.ResponseWriter, r *http.Request, user c.User) c.Route
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_views", pi})
} }
func AnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user c.User, route string) c.RouteError { func AnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user *c.User, route string) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -330,8 +330,8 @@ func AnalyticsRouteViews(w http.ResponseWriter, r *http.Request, user c.User, ro
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_route_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_route_views", pi})
} }
func AnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user c.User, agent string) c.RouteError { func AnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user *c.User, agent string) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -370,8 +370,8 @@ func AnalyticsAgentViews(w http.ResponseWriter, r *http.Request, user c.User, ag
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_agent_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_agent_views", pi})
} }
func AnalyticsForumViews(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func AnalyticsForumViews(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -413,8 +413,8 @@ func AnalyticsForumViews(w http.ResponseWriter, r *http.Request, user c.User, sf
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_forum_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_forum_views", pi})
} }
func AnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user c.User, system string) c.RouteError { func AnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user *c.User, system string) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -452,8 +452,8 @@ func AnalyticsSystemViews(w http.ResponseWriter, r *http.Request, user c.User, s
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_system_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_system_views", pi})
} }
func AnalyticsLanguageViews(w http.ResponseWriter, r *http.Request, user c.User, lang string) c.RouteError { func AnalyticsLanguageViews(w http.ResponseWriter, r *http.Request, user *c.User, lang string) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -492,8 +492,8 @@ func AnalyticsLanguageViews(w http.ResponseWriter, r *http.Request, user c.User,
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_lang_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_lang_views", pi})
} }
func AnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, user c.User, domain string) c.RouteError { func AnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, user *c.User, domain string) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -524,8 +524,8 @@ func AnalyticsReferrerViews(w http.ResponseWriter, r *http.Request, user c.User,
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_referrer_views", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_referrer_views", pi})
} }
func AnalyticsTopics(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsTopics(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -557,8 +557,8 @@ func AnalyticsTopics(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_topics", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_topics", pi})
} }
func AnalyticsPosts(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsPosts(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -590,8 +590,8 @@ func AnalyticsPosts(w http.ResponseWriter, r *http.Request, user c.User) c.Route
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_posts", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_posts", pi})
} }
func AnalyticsMemory(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsMemory(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -626,8 +626,8 @@ func AnalyticsMemory(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
} }
// TODO: Show stack and heap memory separately on the chart // TODO: Show stack and heap memory separately on the chart
func AnalyticsActiveMemory(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsActiveMemory(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -671,8 +671,8 @@ func AnalyticsActiveMemory(w http.ResponseWriter, r *http.Request, user c.User)
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_active_memory", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_active_memory", pi})
} }
func AnalyticsPerf(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsPerf(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -789,8 +789,8 @@ func analyticsAMapToOVList(aMap map[string]map[int64]int64) (ovList []OVItem) {
return sortOVList(ovList) return sortOVList(ovList)
} }
func AnalyticsRoutesPerf(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsRoutesPerf(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -950,8 +950,8 @@ func analyticsVMapToOVList(vMap map[string]map[int64]int64) (ovList []OVItem) {
return sortOVList(ovList) return sortOVList(ovList)
} }
func AnalyticsForums(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsForums(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -1034,8 +1034,8 @@ func AnalyticsForums(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_forums", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_forums", pi})
} }
func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -1110,8 +1110,8 @@ func AnalyticsRoutes(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
} }
// Trialling multi-series charts // Trialling multi-series charts
func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -1196,8 +1196,8 @@ func AnalyticsAgents(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_agents", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_agents", pi})
} }
func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -1260,8 +1260,8 @@ func AnalyticsSystems(w http.ResponseWriter, r *http.Request, user c.User) c.Rou
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_systems", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_systems", pi})
} }
func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := PreAnalyticsDetail(w, r, &user) basePage, ferr := PreAnalyticsDetail(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -1347,8 +1347,8 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.R
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_langs", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_langs", pi})
} }
func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func AnalyticsReferrers(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "analytics", "analytics") basePage, ferr := buildBasePage(w, r, user, "analytics", "analytics")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -10,8 +10,8 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
) )
func Backups(w http.ResponseWriter, r *http.Request, user c.User, backupURL string) c.RouteError { func Backups(w http.ResponseWriter, r *http.Request, user *c.User, backupURL string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "backups", "backups") basePage, ferr := buildBasePage(w, r, user, "backups", "backups")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -22,8 +22,8 @@ func successRedirect(dest string, w http.ResponseWriter, r *http.Request, js boo
} }
// TODO: Prerender needs to handle dyntmpl templates better... // TODO: Prerender needs to handle dyntmpl templates better...
func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, header *c.Header, pi interface{}) c.RouteError { func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, h *c.Header, pi interface{}) c.RouteError {
if !header.LooseCSP { if !h.LooseCSP {
if c.Config.SslSchema { if c.Config.SslSchema {
w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self';upgrade-insecure-requests") w.Header().Set("Content-Security-Policy", "default-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-eval' 'unsafe-inline'; img-src * data: 'unsafe-eval' 'unsafe-inline'; connect-src * 'unsafe-eval' 'unsafe-inline'; frame-src 'self';upgrade-insecure-requests")
} else { } else {
@ -31,12 +31,12 @@ func renderTemplate(tmplName string, w http.ResponseWriter, r *http.Request, hea
} }
} }
header.AddScript("global.js") h.AddScript("global.js")
if c.RunPreRenderHook("pre_render_"+tmplName, w, r, &header.CurrentUser, pi) { if c.RunPreRenderHook("pre_render_"+tmplName, w, r, h.CurrentUser, pi) {
return nil return nil
} }
// TODO: Prepend this with panel_? // TODO: Prepend this with panel_?
err := header.Theme.RunTmpl(tmplName, pi, w) err := h.Theme.RunTmpl(tmplName, pi, w)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }

View File

@ -2,18 +2,18 @@ package panel
import ( import (
"database/sql" "database/sql"
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"runtime" "runtime"
"encoding/json" "strconv"
"time"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time"
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
p "github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
"github.com/Azareal/gopsutil/mem" "github.com/Azareal/gopsutil/mem"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -33,16 +33,16 @@ func dashMySQLStmts() (stmts dashStmts, err error) {
if err != nil { if err != nil {
return nil return nil
} }
stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt BETWEEN (utc_timestamp() - interval 1 "+dur+") and utc_timestamp() " + ext) stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt BETWEEN (utc_timestamp() - interval 1 " + dur + ") and utc_timestamp() " + ext)
err = errors.WithStack(ierr) err = errors.WithStack(ierr)
return stmt return stmt
} }
stmts.todaysPostCount = prepareStmt("replies", "","day") stmts.todaysPostCount = prepareStmt("replies", "", "day")
stmts.todaysTopicCount = prepareStmt("topics", "","day") stmts.todaysTopicCount = prepareStmt("topics", "", "day")
stmts.todaysNewUserCount = prepareStmt("users", "","day") stmts.todaysNewUserCount = prepareStmt("users", "", "day")
stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?","day") stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?", "day")
stmts.weeklyTopicCountByForum = prepareStmt("topics", " and parentID = ?","week") stmts.weeklyTopicCountByForum = prepareStmt("topics", " and parentID = ?", "week")
return stmts, err return stmts, err
} }
@ -54,24 +54,24 @@ func dashMSSQLStmts() (stmts dashStmts, err error) {
if err != nil { if err != nil {
return nil return nil
} }
stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt >= DATEADD("+dur+", -1, GETUTCDATE())" + ext) stmt, ierr := db.Prepare("select count(*) from " + table + " where createdAt >= DATEADD(" + dur + ", -1, GETUTCDATE())" + ext)
err = errors.WithStack(ierr) err = errors.WithStack(ierr)
return stmt return stmt
} }
stmts.todaysPostCount = prepareStmt("replies", "","DAY") stmts.todaysPostCount = prepareStmt("replies", "", "DAY")
stmts.todaysTopicCount = prepareStmt("topics", "","DAY") stmts.todaysTopicCount = prepareStmt("topics", "", "DAY")
stmts.todaysNewUserCount = prepareStmt("users", "","DAY") stmts.todaysNewUserCount = prepareStmt("users", "", "DAY")
stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?","DAY") stmts.todaysTopicCountByForum = prepareStmt("topics", " and parentID = ?", "DAY")
stmts.weeklyTopicCountByForum = prepareStmt("topics", " and parentID = ?","WEEK") stmts.weeklyTopicCountByForum = prepareStmt("topics", " and parentID = ?", "WEEK")
return stmts, err return stmts, err
} }
type GE = c.GridElement type GE = c.GridElement
func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Dashboard(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "dashboard", "dashboard") basePage, ferr := buildBasePage(w, r, user, "dashboard", "dashboard")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -175,21 +175,21 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
grid1 := []GE{} grid1 := []GE{}
addElem1 := func(id string, href string, body string, order int, class string, back string, textColour string, tooltip string) { addElem1 := func(id string, href string, body string, order int, class string, back string, textColour string, tooltip string) {
grid1 = append(grid1, GE{id,href,body,order,class,back,textColour,tooltip}) grid1 = append(grid1, GE{id, href, body, order, class, back, textColour, tooltip})
} }
gridElements := []GE{} gridElements := []GE{}
addElem := func(id string, href string, body string, order int, class string, back string, textColour string, tooltip string) { addElem := func(id string, href string, body string, order int, class string, back string, textColour string, tooltip string) {
gridElements = append(gridElements, GE{id,href,body,order,class,back,textColour,tooltip}) gridElements = append(gridElements, GE{id, href, body, order, class, back, textColour, tooltip})
} }
// TODO: Implement a check for new versions of Gosora // TODO: Implement a check for new versions of Gosora
// TODO: Localise this // TODO: Localise this
//addElem1("dash-version", "", "v" + version.String(), 0, "grid_istat stat_green", "", "", "Gosora is up-to-date :)") //addElem1("dash-version", "", "v" + version.String(), 0, "grid_istat stat_green", "", "", "Gosora is up-to-date :)")
addElem1("dash-version", "","v" + c.SoftwareVersion.String(), 0, "grid_istat", "", "", "") addElem1("dash-version", "", "v"+c.SoftwareVersion.String(), 0, "grid_istat", "", "", "")
addElem1("dash-cpu","", p.GetTmplPhrasef("panel_dashboard_cpu",cpustr), 1, "grid_istat " + cpuColour, "", "", p.GetTmplPhrase("panel_dashboard_cpu_desc")) addElem1("dash-cpu", "", p.GetTmplPhrasef("panel_dashboard_cpu", cpustr), 1, "grid_istat "+cpuColour, "", "", p.GetTmplPhrase("panel_dashboard_cpu_desc"))
addElem1("dash-ram","", p.GetTmplPhrasef("panel_dashboard_ram",ramstr), 2, "grid_istat " + ramColour, "", "", p.GetTmplPhrase("panel_dashboard_ram_desc")) addElem1("dash-ram", "", p.GetTmplPhrasef("panel_dashboard_ram", ramstr), 2, "grid_istat "+ramColour, "", "", p.GetTmplPhrase("panel_dashboard_ram_desc"))
addElem1("dash-memused","/panel/analytics/memory/", p.GetTmplPhrasef("panel_dashboard_memused",memCount, memUnit), 2, "grid_istat", "", "", p.GetTmplPhrase("panel_dashboard_memused_desc")) addElem1("dash-memused", "/panel/analytics/memory/", p.GetTmplPhrasef("panel_dashboard_memused", memCount, memUnit), 2, "grid_istat", "", "", p.GetTmplPhrase("panel_dashboard_memused_desc"))
/*dirSize := getDirSize() /*dirSize := getDirSize()
if dirSize.Size != 0 { if dirSize.Size != 0 {
@ -218,27 +218,27 @@ func Dashboard(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
uonline, uunit := c.ConvertFriendlyUnit(uonline) uonline, uunit := c.ConvertFriendlyUnit(uonline)
gonline, gunit := c.ConvertFriendlyUnit(gonline) gonline, gunit := c.ConvertFriendlyUnit(gonline)
addElem("dash-totonline", "",p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat " + onlineColour, "", "", p.GetTmplPhrase("panel_dashboard_online_desc")) addElem("dash-totonline", "", p.GetTmplPhrasef("panel_dashboard_online", totonline, totunit), 3, "grid_stat "+onlineColour, "", "", p.GetTmplPhrase("panel_dashboard_online_desc"))
addElem("dash-gonline","", p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat " + onlineGuestsColour, "", "", p.GetTmplPhrase("panel_dashboard_guests_online_desc")) addElem("dash-gonline", "", p.GetTmplPhrasef("panel_dashboard_guests_online", gonline, gunit), 4, "grid_stat "+onlineGuestsColour, "", "", p.GetTmplPhrase("panel_dashboard_guests_online_desc"))
addElem("dash-uonline","", p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat " + onlineUsersColour, "", "", p.GetTmplPhrase("panel_dashboard_users_online_desc")) addElem("dash-uonline", "", p.GetTmplPhrasef("panel_dashboard_users_online", uonline, uunit), 5, "grid_stat "+onlineUsersColour, "", "", p.GetTmplPhrase("panel_dashboard_users_online_desc"))
//addElem("dash-reqs","", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours") //addElem("dash-reqs","", strconv.Itoa(reqCount) + " reqs / second", 7, "grid_stat grid_end_group " + topicColour, "", "", "The number of requests over the last 24 hours")
} }
addElem("dash-postsperday", "",p.GetTmplPhrasef("panel_dashboard_posts", postCount, postInterval), 6, "grid_stat " + postColour, "", "", p.GetTmplPhrase("panel_dashboard_posts_desc")) addElem("dash-postsperday", "", p.GetTmplPhrasef("panel_dashboard_posts", postCount, postInterval), 6, "grid_stat "+postColour, "", "", p.GetTmplPhrase("panel_dashboard_posts_desc"))
addElem("dash-topicsperday", "",p.GetTmplPhrasef("panel_dashboard_topics", topicCount, topicInterval), 7, "grid_stat " + topicColour, "", "", p.GetTmplPhrase("panel_dashboard_topics_desc")) addElem("dash-topicsperday", "", p.GetTmplPhrasef("panel_dashboard_topics", topicCount, topicInterval), 7, "grid_stat "+topicColour, "", "", p.GetTmplPhrase("panel_dashboard_topics_desc"))
addElem("dash-totonlineperday","", p.GetTmplPhrasef("panel_dashboard_online_day"), 8, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*, "The people online over the last 24 hours"*/) addElem("dash-totonlineperday", "", p.GetTmplPhrasef("panel_dashboard_online_day"), 8, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*, "The people online over the last 24 hours"*/)
addElem("dash-searches","", p.GetTmplPhrasef("panel_dashboard_searches_day"), 9, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of searches over the last 7 days"*/) addElem("dash-searches", "", p.GetTmplPhrasef("panel_dashboard_searches_day"), 9, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of searches over the last 7 days"*/)
addElem("dash-newusers","", p.GetTmplPhrasef("panel_dashboard_new_users", newUserCount, newUserInterval), 10, "grid_stat", "", "", p.GetTmplPhrasef("panel_dashboard_new_users_desc")) addElem("dash-newusers", "", p.GetTmplPhrasef("panel_dashboard_new_users", newUserCount, newUserInterval), 10, "grid_stat", "", "", p.GetTmplPhrasef("panel_dashboard_new_users_desc"))
addElem("dash-reports","", p.GetTmplPhrasef("panel_dashboard_reports", reportCount, reportInterval), 11, "grid_stat", "", "", p.GetTmplPhrasef("panel_dashboard_reports_desc")) addElem("dash-reports", "", p.GetTmplPhrasef("panel_dashboard_reports", reportCount, reportInterval), 11, "grid_stat", "", "", p.GetTmplPhrasef("panel_dashboard_reports_desc"))
if false { if false {
addElem("dash-minperuser","", "?? minutes / user / week", 12, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of number of minutes spent by each active user over the last 7 days"*/) addElem("dash-minperuser", "", "?? minutes / user / week", 12, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of number of minutes spent by each active user over the last 7 days"*/)
addElem("dash-visitorsperweek","", "?? visitors / week", 13, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of unique visitors we've had over the last 7 days"*/) addElem("dash-visitorsperweek", "", "?? visitors / week", 13, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The number of unique visitors we've had over the last 7 days"*/)
addElem("dash-postsperuser","", "?? posts / user / week", 14, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of posts made by each active user over the past week"*/) addElem("dash-postsperuser", "", "?? posts / user / week", 14, "grid_stat stat_disabled", "", "", p.GetTmplPhrase("panel_dashboard_coming_soon") /*"The average number of posts made by each active user over the past week"*/)
} }
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right","","panel_dashboard", c.DashGrids{grid1,gridElements}}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right", "", "panel_dashboard", c.DashGrids{grid1, gridElements}})
} }
type dirSize struct { type dirSize struct {
@ -247,19 +247,21 @@ type dirSize struct {
} }
func init() { func init() {
cachedDirSize.Store(dirSize{0,time.Now()}) cachedDirSize.Store(dirSize{0, time.Now()})
} }
var cachedDirSize atomic.Value var cachedDirSize atomic.Value
var dstMu sync.Mutex var dstMu sync.Mutex
var dstMuGuess = 0 var dstMuGuess = 0
func startDirSizeTask() { func startDirSizeTask() {
if dstMuGuess==1 { if dstMuGuess == 1 {
return return
} }
dstMu.Lock() dstMu.Lock()
dstMuGuess = 1 dstMuGuess = 1
go func() { go func() {
defer func () { defer func() {
dstMuGuess = 0 dstMuGuess = 0
dstMu.Unlock() dstMu.Unlock()
}() }()
@ -267,7 +269,7 @@ func startDirSizeTask() {
if err != nil { if err != nil {
c.LogWarning(err) c.LogWarning(err)
} }
cachedDirSize.Store(dirSize{dDirSize,time.Now()}) cachedDirSize.Store(dirSize{dDirSize, time.Now()})
}() }()
} }
@ -279,13 +281,13 @@ type StatsDiskJson struct {
Total string `json:"total"` Total string `json:"total"`
} }
func StatsDisk(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func StatsDisk(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
dirSize := getDirSize() dirSize := getDirSize()
dirFloat, unit := c.ConvertByteUnit(float64(dirSize.Size)) dirFloat, unit := c.ConvertByteUnit(float64(dirSize.Size))
u := p.GetTmplPhrasef("unit", dirFloat, unit) u := p.GetTmplPhrasef("unit", dirFloat, unit)
oBytes, err := json.Marshal(StatsDiskJson{u}) oBytes, err := json.Marshal(StatsDiskJson{u})
if err != nil { if err != nil {
return c.InternalErrorJS(err,w,r) return c.InternalErrorJS(err, w, r)
} }
w.Write(oBytes) w.Write(oBytes)
return nil return nil

View File

@ -7,11 +7,11 @@ import (
"time" "time"
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Debug(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "debug", "debug") basePage, ferr := buildBasePage(w, r, user, "debug", "debug")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -45,7 +45,7 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
goroutines := runtime.NumGoroutine() goroutines := runtime.NumGoroutine()
cpus := runtime.NumCPU() cpus := runtime.NumCPU()
debugTasks := c.DebugPageTasks{c.ScheduledHalfSecondTaskCount(),c.ScheduledSecondTaskCount(),c.ScheduledFifteenMinuteTaskCount(),c.ScheduledHourTaskCount(),c.ShutdownTaskCount()} debugTasks := c.DebugPageTasks{c.ScheduledHalfSecondTaskCount(), c.ScheduledSecondTaskCount(), c.ScheduledFifteenMinuteTaskCount(), c.ScheduledHourTaskCount(), c.ShutdownTaskCount()}
var memStats runtime.MemStats var memStats runtime.MemStats
runtime.ReadMemStats(&memStats) runtime.ReadMemStats(&memStats)
@ -89,7 +89,7 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
regLogs := count("registration_logs") regLogs := count("registration_logs")
modLogs := count("moderation_logs") modLogs := count("moderation_logs")
adminLogs := count("administration_logs") adminLogs := count("administration_logs")
views := count("viewchunks") views := count("viewchunks")
viewsAgents := count("viewchunks_agents") viewsAgents := count("viewchunks_agents")
viewsForums := count("viewchunks_forums") viewsForums := count("viewchunks_forums")
@ -99,10 +99,10 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
postChunks := count("postchunks") postChunks := count("postchunks")
topicChunks := count("topicchunks") topicChunks := count("topicchunks")
if fErr != nil { if fErr != nil {
return c.InternalError(fErr,w,r) return c.InternalError(fErr, w, r)
} }
debugDatabase := c.DebugPageDatabase{c.Topics.Count(),c.Users.Count(),c.Rstore.Count(),c.Prstore.Count(),c.Activity.Count(),c.Likes.Count(),attachs,polls,loginLogs,regLogs,modLogs,adminLogs,views,viewsAgents,viewsForums,viewsLangs,viewsReferrers,viewsSystems,postChunks,topicChunks} debugDatabase := c.DebugPageDatabase{c.Topics.Count(), c.Users.Count(), c.Rstore.Count(), c.Prstore.Count(), c.Activity.Count(), c.Likes.Count(), attachs, polls, loginLogs, regLogs, modLogs, adminLogs, views, viewsAgents, viewsForums, viewsLangs, viewsReferrers, viewsSystems, postChunks, topicChunks}
dirSize := func(path string) int { dirSize := func(path string) int {
if fErr != nil { if fErr != nil {
@ -119,13 +119,13 @@ func Debug(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
logsSize := dirSize("./logs/") logsSize := dirSize("./logs/")
backupsSize := dirSize("./backups/") backupsSize := dirSize("./backups/")
if fErr != nil { if fErr != nil {
return c.InternalError(fErr,w,r) return c.InternalError(fErr, w, r)
} }
//gitSize, _ := c.DirSize("./.git") //gitSize, _ := c.DirSize("./.git")
gitSize := 0 gitSize := 0
debugDisk := c.DebugPageDisk{staticSize,attachSize,uploadsSize,logsSize,backupsSize,gitSize} debugDisk := c.DebugPageDisk{staticSize, attachSize, uploadsSize, logsSize, backupsSize, gitSize}
pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus,debugTasks, memStats, debugCache, debugDatabase, debugDisk} pi := c.PanelDebugPage{basePage, goVersion, dbVersion, uptime, openConnCount, qgen.Builder.GetAdapter().GetName(), goroutines, cpus, debugTasks, memStats, debugCache, debugDatabase, debugDisk}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right", "debug_page", "panel_debug", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_dashboard_right", "debug_page", "panel_debug", pi})
} }

View File

@ -11,8 +11,8 @@ import (
p "github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
func Forums(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Forums(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "forums", "forums") basePage, ferr := buildBasePage(w, r, user, "forums", "forums")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -52,8 +52,8 @@ func Forums(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forums", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forums", &pi})
} }
func ForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -81,8 +81,8 @@ func ForumsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
} }
// TODO: Revamp this // TODO: Revamp this
func ForumsDelete(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func ForumsDelete(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "delete_forum", "forums") basePage, ferr := buildBasePage(w, r, user, "delete_forum", "forums")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -102,17 +102,17 @@ func ForumsDelete(w http.ResponseWriter, r *http.Request, user c.User, sfid stri
} }
confirmMsg := p.GetTmplPhrasef("panel_forum_delete_are_you_sure", forum.Name) confirmMsg := p.GetTmplPhrasef("panel_forum_delete_are_you_sure", forum.Name)
yousure := c.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg} youSure := c.AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid), confirmMsg}
pi := c.PanelPage{basePage, tList, yousure} pi := c.PanelPage{basePage, tList, youSure}
if c.RunPreRenderHook("pre_render_panel_delete_forum", w, r, &user, &pi) { if c.RunPreRenderHook("pre_render_panel_delete_forum", w, r, user, &pi) {
return nil return nil
} }
return renderTemplate("panel_are_you_sure", w, r, basePage.Header, &pi) return renderTemplate("panel_are_you_sure", w, r, basePage.Header, &pi)
} }
func ForumsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func ForumsDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -139,8 +139,8 @@ func ForumsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfi
return nil return nil
} }
func ForumsOrderSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ForumsOrderSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -169,8 +169,8 @@ func ForumsOrderSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return successRedirect("/panel/forums/", w, r, js) return successRedirect("/panel/forums/", w, r, js)
} }
func ForumsEdit(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func ForumsEdit(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_forum", "forums") basePage, ferr := buildBasePage(w, r, user, "edit_forum", "forums")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -222,8 +222,8 @@ func ForumsEdit(w http.ResponseWriter, r *http.Request, user c.User, sfid string
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forum_edit", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forum_edit", &pi})
} }
func ForumsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func ForumsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -268,8 +268,8 @@ func ForumsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid
return successRedirect("/panel/forums/", w, r, js) return successRedirect("/panel/forums/", w, r, js)
} }
func ForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func ForumsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -328,8 +328,8 @@ func forumPermsExtractDash(paramList string) (fid int, gid int, err error) {
return fid, gid, err return fid, gid, err
} }
func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user c.User, paramList string) c.RouteError { func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user *c.User, paramList string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_forum", "forums") basePage, ferr := buildBasePage(w, r, user, "edit_forum", "forums")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -342,14 +342,14 @@ func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user c.User,
return c.LocalError(err.Error(), w, r, user) return c.LocalError(err.Error(), w, r, user)
} }
forum, err := c.Forums.Get(fid) f, err := c.Forums.Get(fid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.LocalError("The forum you're trying to edit doesn't exist.", w, r, user) return c.LocalError("The forum you're trying to edit doesn't exist.", w, r, user)
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
if forum.Preset == "" { if f.Preset == "" {
forum.Preset = "custom" f.Preset = "custom"
} }
fp, err := c.FPStore.Get(fid, gid) fp, err := c.FPStore.Get(fid, gid)
@ -382,12 +382,12 @@ func ForumsEditPermsAdvance(w http.ResponseWriter, r *http.Request, user c.User,
basePage.AddNotice("panel_forum_perms_updated") basePage.AddNotice("panel_forum_perms_updated")
} }
pi := c.PanelEditForumGroupPage{basePage, forum.ID, gid, forum.Name, forum.Desc, forum.Active, forum.Preset, formattedPermList} pi := c.PanelEditForumGroupPage{basePage, f.ID, gid, f.Name, f.Desc, f.Active, f.Preset, formattedPermList}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forum_edit_perms", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_forum_edit_perms", &pi})
} }
func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, user c.User, paramList string) c.RouteError { func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, user *c.User, paramList string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -416,7 +416,7 @@ func ForumsEditPermsAdvanceSubmit(w http.ResponseWriter, r *http.Request, user c
} }
extractPerm := func(name string) bool { extractPerm := func(name string) bool {
pvalue := r.PostFormValue("forum-perm-" + name) pvalue := r.PostFormValue("perm-" + name)
return (pvalue == "1") return (pvalue == "1")
} }

View File

@ -10,8 +10,8 @@ import (
p "github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
func Groups(w http.ResponseWriter, r *http.Request, u c.User) c.RouteError { func Groups(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
bPage, ferr := buildBasePage(w, r, &u, "groups", "groups") bPage, ferr := buildBasePage(w, r, u, "groups", "groups")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -61,8 +61,8 @@ func Groups(w http.ResponseWriter, r *http.Request, u c.User) c.RouteError {
return renderTemplate("panel", w, r, bPage.Header, c.Panel{bPage, "", "", "panel_groups", &pi}) return renderTemplate("panel", w, r, bPage.Header, c.Panel{bPage, "", "", "panel_groups", &pi})
} }
func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError { func GroupsEdit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_group", "groups") basePage, ferr := buildBasePage(w, r, user, "edit_group", "groups")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -103,8 +103,8 @@ func GroupsEdit(w http.ResponseWriter, r *http.Request, user c.User, sgid string
return renderTemplate("panel_group_edit", w, r, basePage.Header, pi) return renderTemplate("panel_group_edit", w, r, basePage.Header, pi)
} }
func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError { func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_group", "groups") basePage, ferr := buildBasePage(w, r, user, "edit_group", "groups")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -168,22 +168,22 @@ func GroupsEditPromotions(w http.ResponseWriter, r *http.Request, user c.User, s
return renderTemplate("panel_group_edit_promotions", w, r, basePage.Header, pi) return renderTemplate("panel_group_edit_promotions", w, r, basePage.Header, pi)
} }
func groupCheck(w http.ResponseWriter, r *http.Request, user c.User, g *c.Group, err error) c.RouteError { func groupCheck(w http.ResponseWriter, r *http.Request, u *c.User, g *c.Group, err error) c.RouteError {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.LocalError("No such group.", w, r, user) return c.LocalError("No such group.", w, r, u)
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
if g.IsAdmin && !user.Perms.EditGroupAdmin { if g.IsAdmin && !u.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, user) return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_admin"), w, r, u)
} }
if g.IsMod && !user.Perms.EditGroupSuperMod { if g.IsMod && !u.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, user) return c.LocalError(p.GetErrorPhrase("panel_groups_cannot_edit_supermod"), w, r, u)
} }
return nil return nil
} }
func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError { func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
if !user.Perms.EditGroup { if !user.Perms.EditGroup {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -251,7 +251,7 @@ func GroupsPromotionsCreateSubmit(w http.ResponseWriter, r *http.Request, user c
return nil return nil
} }
func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sspl string) c.RouteError { func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sspl string) c.RouteError {
if !user.Perms.EditGroup { if !user.Perms.EditGroup {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -298,8 +298,8 @@ func GroupsPromotionsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c
return nil return nil
} }
func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError { func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_group", "groups") basePage, ferr := buildBasePage(w, r, user, "edit_group", "groups")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -385,8 +385,8 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi) return renderTemplate("panel_group_edit_perms", w, r, basePage.Header, pi)
} }
func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError { func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -471,8 +471,8 @@ func GroupsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid
return nil return nil
} }
func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User, sgid string) c.RouteError { func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sgid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -520,8 +520,8 @@ func GroupsEditPermsSubmit(w http.ResponseWriter, r *http.Request, user c.User,
return nil return nil
} }
func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -529,32 +529,32 @@ func GroupsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
groupName := r.PostFormValue("name") name := r.PostFormValue("name")
if groupName == "" { if name == "" {
return c.LocalError(p.GetErrorPhrase("panel_groups_need_name"), w, r, user) return c.LocalError(p.GetErrorPhrase("panel_groups_need_name"), w, r, user)
} }
groupTag := r.PostFormValue("tag") tag := r.PostFormValue("tag")
var isAdmin, isMod, isBanned bool var admin, mod, banned bool
if user.Perms.EditGroupGlobalPerms { if user.Perms.EditGroupGlobalPerms {
switch r.PostFormValue("type") { switch r.PostFormValue("type") {
case "Admin": case "Admin":
if !user.Perms.EditGroupAdmin { if !user.Perms.EditGroupAdmin {
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user) return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_admin"), w, r, user)
} }
isAdmin = true admin = true
isMod = true mod = true
case "Mod": case "Mod":
if !user.Perms.EditGroupSuperMod { if !user.Perms.EditGroupSuperMod {
return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user) return c.LocalError(p.GetErrorPhrase("panel_groups_create_cannot_designate_supermod"), w, r, user)
} }
isMod = true mod = true
case "Banned": case "Banned":
isBanned = true banned = true
} }
} }
gid, err := c.Groups.Create(groupName, groupTag, isAdmin, isMod, isBanned) gid, err := c.Groups.Create(name, tag, admin, mod, banned)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }

View File

@ -12,8 +12,8 @@ import (
) )
// TODO: Link the usernames for successful registrations to the profiles // TODO: Link the usernames for successful registrations to the profiles
func LogsRegs(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func LogsRegs(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "registration_logs", "logs") basePage, ferr := buildBasePage(w, r, user, "registration_logs", "logs")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -168,8 +168,8 @@ func adminlogsElementType(action, elementType string, elementID int, actor *c.Us
return out return out
} }
func LogsMod(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func LogsMod(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "mod_logs", "logs") basePage, ferr := buildBasePage(w, r, user, "mod_logs", "logs")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -193,8 +193,8 @@ func LogsMod(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_modlogs", pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_modlogs", pi})
} }
func LogsAdmin(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func LogsAdmin(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "admin_logs", "logs") basePage, ferr := buildBasePage(w, r, user, "admin_logs", "logs")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -8,12 +8,11 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
) )
func Pages(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Pages(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "pages", "pages") basePage, ferr := buildBasePage(w, r, user, "pages", "pages")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if r.FormValue("created") == "1" { if r.FormValue("created") == "1" {
basePage.AddNotice("panel_page_created") basePage.AddNotice("panel_page_created")
} else if r.FormValue("deleted") == "1" { } else if r.FormValue("deleted") == "1" {
@ -36,8 +35,8 @@ func Pages(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_list", "", "panel_pages", &pi})
} }
func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -72,8 +71,8 @@ func PagesCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return nil return nil
} }
func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { func PagesEdit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "pages_edit", "pages") basePage, ferr := buildBasePage(w, r, user, "pages_edit", "pages")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -96,8 +95,8 @@ func PagesEdit(w http.ResponseWriter, r *http.Request, user c.User, spid string)
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_page_edit", "", "panel_pages_edit", &pi})
} }
func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -139,8 +138,8 @@ func PagesEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid s
return nil return nil
} }
func PagesDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { func PagesDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, spid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -8,8 +8,8 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
) )
func Plugins(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Plugins(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "plugins", "plugins") basePage, ferr := buildBasePage(w, r, user, "plugins", "plugins")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -26,8 +26,8 @@ func Plugins(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
} }
// TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily // TODO: Abstract more of the plugin activation / installation / deactivation logic, so we can test all that more reliably and easily
func PluginsActivate(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError { func PluginsActivate(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -82,8 +82,8 @@ func PluginsActivate(w http.ResponseWriter, r *http.Request, user c.User, uname
return nil return nil
} }
func PluginsDeactivate(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError { func PluginsDeactivate(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -120,8 +120,8 @@ func PluginsDeactivate(w http.ResponseWriter, r *http.Request, user c.User, unam
return nil return nil
} }
func PluginsInstall(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError { func PluginsInstall(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -10,8 +10,8 @@ import (
p "github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
func Settings(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Settings(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "settings", "settings") basePage, ferr := buildBasePage(w, r, user, "settings", "settings")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -54,8 +54,8 @@ func Settings(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_settings", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_settings", &pi})
} }
func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname string) c.RouteError { func SettingEdit(w http.ResponseWriter, r *http.Request, user *c.User, sname string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_setting", "settings") basePage, ferr := buildBasePage(w, r, user, "edit_setting", "settings")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -93,8 +93,8 @@ func SettingEdit(w http.ResponseWriter, r *http.Request, user c.User, sname stri
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_setting", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_setting", &pi})
} }
func SettingEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, name string) c.RouteError { func SettingEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, name string) c.RouteError {
headerLite, ferr := c.SimplePanelUserCheck(w, r, &user) headerLite, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -12,8 +12,8 @@ import (
p "github.com/Azareal/Gosora/common/phrases" p "github.com/Azareal/Gosora/common/phrases"
) )
func Themes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Themes(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "themes", "themes") basePage, ferr := buildBasePage(w, r, user, "themes", "themes")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -37,8 +37,8 @@ func Themes(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_themes", "", "panel_themes", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_themes", "", "panel_themes", &pi})
} }
func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user c.User, uname string) c.RouteError { func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user *c.User, uname string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -67,8 +67,8 @@ func ThemesSetDefault(w http.ResponseWriter, r *http.Request, user c.User, uname
return nil return nil
} }
func ThemesMenus(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ThemesMenus(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "themes_menus", "themes") basePage, ferr := buildBasePage(w, r, user, "themes_menus", "themes")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -92,9 +92,9 @@ func ThemesMenus(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus", &c.PanelMenuListPage{basePage, menuList}})
} }
func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError { func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user *c.User, smid string) c.RouteError {
// TODO: Something like Menu #1 for the title? // TODO: Something like Menu #1 for the title?
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes") basePage, ferr := buildBasePage(w, r, user, "themes_menus_edit", "themes")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -138,9 +138,9 @@ func ThemesMenusEdit(w http.ResponseWriter, r *http.Request, user c.User, smid s
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_themes_menus_items", &c.PanelMenuPage{basePage, mid, menuList}})
} }
func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError { func ThemesMenuItemEdit(w http.ResponseWriter, r *http.Request, user *c.User, sitemID string) c.RouteError {
// TODO: Something like Menu #1 for the title? // TODO: Something like Menu #1 for the title?
basePage, ferr := buildBasePage(w, r, &user, "themes_menus_edit", "themes") basePage, ferr := buildBasePage(w, r, user, "themes_menus_edit", "themes")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -205,8 +205,8 @@ func themesMenuItemSetters(r *http.Request, i c.MenuItem) c.MenuItem {
return i return i
} }
func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError { func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sitemID string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -219,7 +219,6 @@ func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.Use
if err != nil { if err != nil {
return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js) return c.LocalErrorJSQ(p.GetErrorPhrase("id_must_be_integer"), w, r, user, js)
} }
menuItem, err := c.Menus.ItemStore().Get(itemID) menuItem, err := c.Menus.ItemStore().Get(itemID)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.LocalErrorJSQ("This item doesn't exist.", w, r, user, js) return c.LocalErrorJSQ("This item doesn't exist.", w, r, user, js)
@ -241,8 +240,8 @@ func ThemesMenuItemEditSubmit(w http.ResponseWriter, r *http.Request, user c.Use
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js) return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js)
} }
func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -274,8 +273,8 @@ func ThemesMenuItemCreateSubmit(w http.ResponseWriter, r *http.Request, user c.U
return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js) return successRedirect("/panel/themes/menus/item/edit/"+strconv.Itoa(itemID), w, r, js)
} }
func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, sitemID string) c.RouteError { func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sitemID string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -308,8 +307,8 @@ func ThemesMenuItemDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.U
return successRedirect("/panel/themes/menus/", w, r, js) return successRedirect("/panel/themes/menus/", w, r, js)
} }
func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user c.User, smid string) c.RouteError { func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user *c.User, smid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -350,8 +349,8 @@ func ThemesMenuItemOrderSubmit(w http.ResponseWriter, r *http.Request, user c.Us
return successRedirect("/panel/themes/menus/edit/"+strconv.Itoa(mid), w, r, js) return successRedirect("/panel/themes/menus/edit/"+strconv.Itoa(mid), w, r, js)
} }
func ThemesWidgets(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ThemesWidgets(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "themes_widgets", "themes") basePage, ferr := buildBasePage(w, r, user, "themes_widgets", "themes")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -415,9 +414,9 @@ func widgetsParseInputs(r *http.Request, widget *c.Widget) (*c.WidgetEdit, error
} }
// ThemesWidgetsEditSubmit is an action which is triggered when someone sends an update request for a widget // ThemesWidgetsEditSubmit is an action which is triggered when someone sends an update request for a widget
func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, swid string) c.RouteError { func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, swid string) c.RouteError {
//fmt.Println("in ThemesWidgetsEditSubmit") //fmt.Println("in ThemesWidgetsEditSubmit")
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -455,9 +454,9 @@ func ThemesWidgetsEditSubmit(w http.ResponseWriter, r *http.Request, user c.User
} }
// ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget // ThemesWidgetsCreateSubmit is an action which is triggered when someone sends a create request for a widget
func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -469,7 +468,6 @@ func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.Us
if err != nil { if err != nil {
return c.LocalErrorJSQ(err.Error(), w, r, user, js) return c.LocalErrorJSQ(err.Error(), w, r, user, js)
} }
wid, err := ewidget.Create() wid, err := ewidget.Create()
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
@ -482,8 +480,8 @@ func ThemesWidgetsCreateSubmit(w http.ResponseWriter, r *http.Request, user c.Us
return successRedirect("/panel/themes/widgets/", w, r, js) return successRedirect("/panel/themes/widgets/", w, r, js)
} }
func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, swid string) c.RouteError { func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, swid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -502,7 +500,6 @@ func ThemesWidgetsDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.Us
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
err = widget.Delete() err = widget.Delete()
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)

View File

@ -8,8 +8,8 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
) )
func Users(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func Users(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "users", "users") basePage, ferr := buildBasePage(w, r, user, "users", "users")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -27,8 +27,8 @@ func Users(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError {
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_users", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_users", &pi})
} }
func UsersEdit(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func UsersEdit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_user", "users") basePage, ferr := buildBasePage(w, r, user, "edit_user", "users")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -76,8 +76,8 @@ func UsersEdit(w http.ResponseWriter, r *http.Request, user c.User, suid string)
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_user_edit", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_user_edit", &pi})
} }
func UsersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func UsersEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -183,8 +183,8 @@ func UsersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid s
return nil return nil
} }
func UsersAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func UsersAvatarSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -211,7 +211,7 @@ func UsersAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
ferr = c.ChangeAvatar("."+ext, w, r, *targetUser) ferr = c.ChangeAvatar("."+ext, w, r, targetUser)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -234,8 +234,8 @@ func UsersAvatarSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid
return nil return nil
} }
func UsersAvatarRemoveSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func UsersAvatarRemoveSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -256,7 +256,7 @@ func UsersAvatarRemoveSubmit(w http.ResponseWriter, r *http.Request, user c.User
if targetUser.IsAdmin && !user.IsAdmin { if targetUser.IsAdmin && !user.IsAdmin {
return c.LocalError("Only administrators can edit the account of other administrators.", w, r, user) return c.LocalError("Only administrators can edit the account of other administrators.", w, r, user)
} }
ferr = c.ChangeAvatar("", w, r, *targetUser) ferr = c.ChangeAvatar("", w, r, targetUser)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -10,8 +10,8 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
) )
func WordFilters(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func WordFilters(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "word_filters", "word-filters") basePage, ferr := buildBasePage(w, r, user, "word_filters", "word-filters")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -29,8 +29,8 @@ func WordFilters(w http.ResponseWriter, r *http.Request, user c.User) c.RouteErr
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters", &pi})
} }
func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -61,8 +61,8 @@ func WordFiltersCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User
} }
// TODO: Implement this as a non-JS fallback // TODO: Implement this as a non-JS fallback
func WordFiltersEdit(w http.ResponseWriter, r *http.Request, user c.User, wfid string) c.RouteError { func WordFiltersEdit(w http.ResponseWriter, r *http.Request, user *c.User, wfid string) c.RouteError {
basePage, ferr := buildBasePage(w, r, &user, "edit_word_filter", "word-filters") basePage, ferr := buildBasePage(w, r, user, "edit_word_filter", "word-filters")
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -75,8 +75,8 @@ func WordFiltersEdit(w http.ResponseWriter, r *http.Request, user c.User, wfid s
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters_edit", &pi}) return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "", "", "panel_word_filters_edit", &pi})
} }
func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, swfid string) c.RouteError { func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, swfid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -120,8 +120,8 @@ func WordFiltersEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
return nil return nil
} }
func WordFiltersDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, swfid string) c.RouteError { func WordFiltersDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, swfid string) c.RouteError {
_, ferr := c.SimplePanelUserCheck(w, r, &user) _, ferr := c.SimplePanelUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }

View File

@ -10,7 +10,7 @@ import (
qgen "github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
func PollVote(w http.ResponseWriter, r *http.Request, user c.User, sPollID string) c.RouteError { func PollVote(w http.ResponseWriter, r *http.Request, user *c.User, sPollID string) c.RouteError {
pollID, err := strconv.Atoi(sPollID) pollID, err := strconv.Atoi(sPollID)
if err != nil { if err != nil {
return c.PreError("The provided PollID is not a valid number.", w, r) return c.PreError("The provided PollID is not a valid number.", w, r)
@ -44,7 +44,7 @@ func PollVote(w http.ResponseWriter, r *http.Request, user c.User, sPollID strin
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
_, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) _, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -65,7 +65,7 @@ func PollVote(w http.ResponseWriter, r *http.Request, user c.User, sPollID strin
return nil return nil
} }
func PollResults(w http.ResponseWriter, r *http.Request, user c.User, sPollID string) c.RouteError { func PollResults(w http.ResponseWriter, r *http.Request, user *c.User, sPollID string) c.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 {

View File

@ -27,7 +27,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 c.User, header *c.Header) c.RouteError { func ViewProfile(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header) c.RouteError {
var reCreatedAt time.Time var reCreatedAt time.Time
var reContent, reCreatedByName, reAvatar string var reContent, reCreatedByName, reAvatar string
var rid, reCreatedBy, reLastEdit, reLastEditBy, reGroup int var rid, reCreatedBy, reLastEdit, reLastEditBy, reGroup int
@ -48,7 +48,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c.
var puser *c.User var puser *c.User
if pid == user.ID { if pid == user.ID {
user.IsMod = true user.IsMod = true
puser = &user puser = user
} else { } else {
// Fetch the user data // Fetch the user data
// TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case? // TODO: Add a shared function for checking for ErrNoRows and internal erroring if it's not that case?
@ -77,7 +77,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c.
reLiked := false reLiked := false
reLikeCount := 0 reLikeCount := 0
ru := &c.ReplyUser{Reply: c.Reply{rid, puser.ID, reContent, reCreatedBy, reGroup, reCreatedAt, reLastEdit, reLastEditBy, 0, "", reLiked, reLikeCount, 0, ""}, ContentHtml: c.ParseMessage(reContent, 0, "", user.ParseSettings, &user), CreatedByName: reCreatedByName, Avatar: reAvatar, Level: 0} ru := &c.ReplyUser{Reply: c.Reply{rid, puser.ID, reContent, reCreatedBy, reGroup, reCreatedAt, reLastEdit, reLastEditBy, 0, "", reLiked, reLikeCount, 0, ""}, ContentHtml: c.ParseMessage(reContent, 0, "", user.ParseSettings, user), CreatedByName: reCreatedByName, Avatar: reAvatar, Level: 0}
_, err = ru.Init() _, err = ru.Init()
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)

View File

@ -9,7 +9,7 @@ import (
"github.com/Azareal/Gosora/common/counters" "github.com/Azareal/Gosora/common/counters"
) )
func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
if !user.Perms.CreateProfileReply { if !user.Perms.CreateProfileReply {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -44,8 +44,8 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user c.Use
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
// ! Be careful about leaking per-route permission state with &user // ! Be careful about leaking per-route permission state with user ptr
alert := c.Alert{ActorID: user.ID, TargetUserID: profileOwner.ID, Event: "reply", ElementType: "user", ElementID: profileOwner.ID, Actor: &user, Extra: strconv.Itoa(prid)} alert := c.Alert{ActorID: user.ID, TargetUserID: profileOwner.ID, Event: "reply", ElementType: "user", ElementID: profileOwner.ID, Actor: user, Extra: strconv.Itoa(prid)}
err = c.AddActivityAndNotifyTarget(alert) err = c.AddActivityAndNotifyTarget(alert)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
@ -56,7 +56,7 @@ func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user c.Use
return nil return nil
} }
func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
@ -97,7 +97,7 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User,
return nil return nil
} }
func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {

View File

@ -34,7 +34,7 @@ type JsonReply struct {
Content string Content string
} }
func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
// TODO: Use this // TODO: Use this
js := r.FormValue("js") == "1" js := r.FormValue("js") == "1"
tid, err := strconv.Atoi(r.PostFormValue("tid")) tid, err := strconv.Atoi(r.PostFormValue("tid"))
@ -50,7 +50,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -185,14 +185,14 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
} }
counters.PostCounter.Bump() counters.PostCounter.Bump()
skip, rerr := lite.Hooks.VhookSkippable("action_end_create_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_create_reply", reply.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
prid, _ := strconv.Atoi(r.FormValue("prid")) prid, _ := strconv.Atoi(r.FormValue("prid"))
if js && (prid == 0 || rids[0] == prid) { if js && (prid == 0 || rids[0] == prid) {
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(reply.Content, topic.ParentID, "forums", user.ParseSettings, &user)}) outBytes, err := json.Marshal(JsonReply{c.ParseMessage(reply.Content, topic.ParentID, "forums", user.ParseSettings, user)})
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
@ -209,7 +209,7 @@ func CreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
// TODO: Disable stat updates in posts handled by plugin_guilds // TODO: Disable stat updates in posts handled by plugin_guilds
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes // TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
@ -231,7 +231,7 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -257,7 +257,7 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_reply", reply.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -265,7 +265,7 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
if !js { if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther) http.Redirect(w, r, "/topic/"+strconv.Itoa(topic.ID)+"#reply-"+strconv.Itoa(rid), http.StatusSeeOther)
} else { } else {
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(reply.Content, topic.ParentID, "forums", user.ParseSettings, &user)}) outBytes, err := json.Marshal(JsonReply{c.ParseMessage(reply.Content, topic.ParentID, "forums", user.ParseSettings, user)})
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
@ -277,7 +277,7 @@ func ReplyEditSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
// TODO: Refactor this // TODO: Refactor this
// TODO: Disable stat updates in posts handled by plugin_guilds // TODO: Disable stat updates in posts handled by plugin_guilds
func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
@ -290,7 +290,6 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
} else if err != nil { } else if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
topic, err := c.Topics.Get(reply.ParentID) topic, err := c.Topics.Get(reply.ParentID)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js) return c.PreErrorJSQ("The parent topic doesn't exist.", w, r, js)
@ -299,7 +298,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -312,7 +311,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_reply", reply.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -345,7 +344,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
// TODO: Avoid uploading this again if the attachment already exists? They'll resolve to the same hash either way, but we could save on some IO / bandwidth here // TODO: Avoid uploading this again if the attachment already exists? They'll resolve to the same hash either way, but we could save on some IO / bandwidth here
// TODO: Enforce the max request limit on all of this topic's attachments // TODO: Enforce the max request limit on all of this topic's attachments
// TODO: Test this route // TODO: Test this route
func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r) return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
@ -363,19 +362,19 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
return c.NotFoundJS(w, r) return c.NotFoundJS(w, r)
} }
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, u, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.ViewTopic || !user.Perms.EditReply || !user.Perms.UploadFiles { if !u.Perms.ViewTopic || !u.Perms.EditReply || !u.Perms.UploadFiles {
return c.NoPermissionsJS(w, r, user) return c.NoPermissionsJS(w, r, u)
} }
if topic.IsClosed && !user.Perms.CloseTopic { if topic.IsClosed && !u.Perms.CloseTopic {
return c.NoPermissionsJS(w, r, user) return c.NoPermissionsJS(w, r, u)
} }
// Handle the file attachments // Handle the file attachments
pathMap, rerr := uploadAttachment(w, r, user, topic.ParentID, "forums", rid, "replies", strconv.Itoa(topic.ID)) pathMap, rerr := uploadAttachment(w, r, u, topic.ParentID, "forums", rid, "replies", strconv.Itoa(topic.ID))
if rerr != nil { if rerr != nil {
// TODO: This needs to be a JS error... // TODO: This needs to be a JS error...
return rerr return rerr
@ -384,7 +383,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
return c.InternalErrorJS(errors.New("no paths for attachment add"), w, r) return c.InternalErrorJS(errors.New("no paths for attachment add"), w, r)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_add_attach_to_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_add_attach_to_reply", reply.ID, u)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -402,7 +401,7 @@ func AddAttachToReplySubmit(w http.ResponseWriter, r *http.Request, user c.User,
} }
// TODO: Reduce the amount of duplication between this and RemoveAttachFromTopicSubmit // TODO: Reduce the amount of duplication between this and RemoveAttachFromTopicSubmit
func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, u *c.User, srid string) c.RouteError {
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r) return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
@ -420,15 +419,15 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.
return c.NotFoundJS(w, r) return c.NotFoundJS(w, r)
} }
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, u, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.ViewTopic || !user.Perms.EditReply { if !u.Perms.ViewTopic || !u.Perms.EditReply {
return c.NoPermissionsJS(w, r, user) return c.NoPermissionsJS(w, r, u)
} }
if topic.IsClosed && !user.Perms.CloseTopic { if topic.IsClosed && !u.Perms.CloseTopic {
return c.NoPermissionsJS(w, r, user) return c.NoPermissionsJS(w, r, u)
} }
saids := strings.Split(r.PostFormValue("aids"), ",") saids := strings.Split(r.PostFormValue("aids"), ",")
@ -440,14 +439,14 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.
if err != nil { if err != nil {
return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r) return c.LocalErrorJS(p.GetErrorPhrase("id_must_be_integer"), w, r)
} }
rerr := deleteAttachment(w, r, user, aid, true) rerr := deleteAttachment(w, r, u, aid, true)
if rerr != nil { if rerr != nil {
// TODO: This needs to be a JS error... // TODO: This needs to be a JS error...
return rerr return rerr
} }
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_remove_attach_from_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_remove_attach_from_reply", reply.ID, u)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -456,7 +455,7 @@ func RemoveAttachFromReplySubmit(w http.ResponseWriter, r *http.Request, user c.
return nil return nil
} }
func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
@ -478,7 +477,7 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -503,14 +502,14 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
// ! Be careful about leaking per-route permission state with &user // ! Be careful about leaking per-route permission state with user ptr
alert := c.Alert{ActorID: user.ID, TargetUserID: reply.CreatedBy, Event: "like", ElementType: "post", ElementID: rid, Actor: &user} alert := c.Alert{ActorID: user.ID, TargetUserID: reply.CreatedBy, Event: "like", ElementType: "post", ElementID: rid, Actor: user}
err = c.AddActivityAndNotifyTarget(alert) err = c.AddActivityAndNotifyTarget(alert)
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_like_reply", reply.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -523,7 +522,7 @@ func ReplyLikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid s
return nil return nil
} }
func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid string) c.RouteError { func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, user *c.User, srid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
rid, err := strconv.Atoi(srid) rid, err := strconv.Atoi(srid)
if err != nil { if err != nil {
@ -545,7 +544,7 @@ func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -578,7 +577,7 @@ func ReplyUnlikeSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_unlike_reply", reply.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_unlike_reply", reply.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }

View File

@ -9,8 +9,8 @@ import (
"github.com/Azareal/Gosora/common/counters" "github.com/Azareal/Gosora/common/counters"
) )
func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sItemID string) c.RouteError { func ReportSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sItemID string) c.RouteError {
headerLite, ferr := c.SimpleUserCheck(w, r, &user) headerLite, ferr := c.SimpleUserCheck(w, r, user)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -85,7 +85,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sItemID s
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
title = "Convo Post: " + user.Name title = "Convo: " + user.Name
content = post.Body + "\n\nOriginal Post: #cpid-" + strconv.Itoa(itemID) content = post.Body + "\n\nOriginal Post: #cpid-" + strconv.Itoa(itemID)
default: default:
_, hasHook := headerLite.Hooks.VhookNeedHook("report_preassign", &itemID, &itemType) _, hasHook := headerLite.Hooks.VhookNeedHook("report_preassign", &itemID, &itemType)
@ -98,7 +98,7 @@ func ReportSubmit(w http.ResponseWriter, r *http.Request, user c.User, sItemID s
} }
// TODO: Repost attachments in the reports forum, so that the mods can see them // TODO: Repost attachments in the reports forum, so that the mods can see them
_, err = c.Reports.Create(title, content, &user, itemType, itemID) _, err = c.Reports.Create(title, content, user, itemType, itemID)
if err == c.ErrAlreadyReported { if err == c.ErrAlreadyReported {
return c.LocalError("Someone has already reported this!", w, r, user) return c.LocalError("Someone has already reported this!", w, r, user)
} }

View File

@ -44,7 +44,7 @@ func init() {
}) })
} }
func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header, urlBit string) c.RouteError { func ViewTopic(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header, urlBit string) c.RouteError {
page, _ := strconv.Atoi(r.FormValue("page")) page, _ := strconv.Atoi(r.FormValue("page"))
_, tid, err := ParseSEOURL(urlBit) _, tid, err := ParseSEOURL(urlBit)
if err != nil { if err != nil {
@ -52,14 +52,14 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
} }
// Get the topic... // Get the topic...
topic, err := c.GetTopicUser(&user, tid) topic, err := c.GetTopicUser(user, tid)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.NotFound(w, r, nil) // TODO: Can we add a simplified invocation of header here? This is likely to be an extremely common NotFound return c.NotFound(w, r, nil) // TODO: Can we add a simplified invocation of header here? This is likely to be an extremely common NotFound
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
ferr := c.ForumUserCheck(header, w, r, &user, topic.ParentID) ferr := c.ForumUserCheck(header, w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -92,7 +92,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
} }
// TODO: Cache ContentHTML when possible? // TODO: Cache ContentHTML when possible?
topic.ContentHTML = c.ParseMessage(topic.Content, topic.ParentID, "forums", parseSettings, &user) topic.ContentHTML = c.ParseMessage(topic.Content, topic.ParentID, "forums", parseSettings, user)
// TODO: Do this more efficiently by avoiding the allocations entirely in ParseMessage, if there's nothing to do. // TODO: Do this more efficiently by avoiding the allocations entirely in ParseMessage, if there's nothing to do.
if topic.ContentHTML == topic.Content { if topic.ContentHTML == topic.Content {
topic.ContentHTML = topic.Content topic.ContentHTML = topic.Content
@ -149,7 +149,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
if strings.HasPrefix(r.URL.Fragment, "post-") { if strings.HasPrefix(r.URL.Fragment, "post-") {
pFrag, _ = strconv.Atoi(strings.TrimPrefix(r.URL.Fragment, "post-")) pFrag, _ = strconv.Atoi(strings.TrimPrefix(r.URL.Fragment, "post-"))
} }
rlist, ogdesc, err := topic.Replies(offset, pFrag, &user) rlist, ogdesc, err := topic.Replies(offset, pFrag, user)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
return c.LocalError("Bad Page. Some of the posts may have been deleted or you got here by directly typing in the page number.", w, r, user) return c.LocalError("Bad Page. Some of the posts may have been deleted or you got here by directly typing in the page number.", w, r, user)
} else if err != nil { } else if err != nil {
@ -201,7 +201,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
// TODO: Avoid uploading this again if the attachment already exists? They'll resolve to the same hash either way, but we could save on some IO / bandwidth here // TODO: Avoid uploading this again if the attachment already exists? They'll resolve to the same hash either way, but we could save on some IO / bandwidth here
// TODO: Enforce the max request limit on all of this topic's attachments // TODO: Enforce the max request limit on all of this topic's attachments
// TODO: Test this route // TODO: Test this route
func AddAttachToTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func AddAttachToTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { if err != nil {
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r) return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
@ -211,7 +211,7 @@ func AddAttachToTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User,
return c.NotFoundJS(w, r) return c.NotFoundJS(w, r)
} }
_, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) _, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -244,7 +244,7 @@ func AddAttachToTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User,
return nil return nil
} }
func RemoveAttachFromTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func RemoveAttachFromTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { if err != nil {
return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r) return c.LocalErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
@ -254,7 +254,7 @@ func RemoveAttachFromTopicSubmit(w http.ResponseWriter, r *http.Request, user c.
return c.NotFoundJS(w, r) return c.NotFoundJS(w, r)
} }
_, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) _, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -287,7 +287,7 @@ func RemoveAttachFromTopicSubmit(w http.ResponseWriter, r *http.Request, user c.
// ? - 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 c.User, header *c.Header, sfid string) c.RouteError { func CreateTopic(w http.ResponseWriter, r *http.Request, user *c.User, header *c.Header, sfid string) c.RouteError {
var fid int var fid int
var err error var err error
if sfid != "" { if sfid != "" {
@ -300,7 +300,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
fid = c.Config.DefaultForum fid = c.Config.DefaultForum
} }
ferr := c.ForumUserCheck(header, w, r, &user, fid) ferr := c.ForumUserCheck(header, w, r, user, fid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -314,7 +314,7 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
// Lock this to the forum being linked? // Lock this to the forum being linked?
// Should we always put it in strictmode when it's linked from another forum? Well, the user might end up changing their mind on what forum they want to post in and it would be a hassle, if they had to switch pages, even if it is a single click for many (exc. mobile) // Should we always put it in strictmode when it's linked from another forum? Well, the user might end up changing their mind on what forum they want to post in and it would be a hassle, if they had to switch pages, even if it is a single click for many (exc. mobile)
var strict bool var strict bool
header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, &user, &strict) header.Hooks.VhookNoRet("topic_create_pre_loop", w, r, fid, &header, user, &strict)
// TODO: Re-add support for plugin_guilds // TODO: Re-add support for plugin_guilds
var forumList []c.Forum var forumList []c.Forum
@ -357,13 +357,13 @@ func CreateTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.
return renderTemplate("create_topic", w, r, header, c.CreateTopicPage{header, forumList, fid}) return renderTemplate("create_topic", w, r, header, c.CreateTopicPage{header, forumList, fid})
} }
func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
fid, err := strconv.Atoi(r.PostFormValue("board")) fid, err := strconv.Atoi(r.PostFormValue("board"))
if err != nil { if err != nil {
return c.LocalError(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user) return c.LocalError(phrases.GetErrorPhrase("id_must_be_integer"), w, r, user)
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, fid) lite, ferr := c.SimpleForumUserCheck(w, r, user, fid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -460,7 +460,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
counters.PostCounter.Bump() counters.PostCounter.Bump()
counters.TopicCounter.Bump() counters.TopicCounter.Bump()
// TODO: Pass more data to this hook? // TODO: Pass more data to this hook?
skip, rerr := lite.Hooks.VhookSkippable("action_end_create_topic", tid, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_create_topic", tid, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -469,7 +469,7 @@ func CreateTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
} }
// TODO: Move this function // TODO: Move this function
func uploadFilesWithHash(w http.ResponseWriter, r *http.Request, user c.User, dir string) (filenames []string, rerr c.RouteError) { func uploadFilesWithHash(w http.ResponseWriter, r *http.Request, user *c.User, dir string) (filenames []string, rerr c.RouteError) {
files, ok := r.MultipartForm.File["upload_files"] files, ok := r.MultipartForm.File["upload_files"]
if !ok { if !ok {
return nil, nil return nil, nil
@ -569,7 +569,7 @@ func uploadFilesWithHash(w http.ResponseWriter, r *http.Request, user c.User, di
// TODO: Update the stats after edits so that we don't under or over decrement stats during deletes // TODO: Update the stats after edits so that we don't under or over decrement stats during deletes
// TODO: Disable stat updates in posts handled by plugin_guilds // TODO: Disable stat updates in posts handled by plugin_guilds
func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
js := (r.PostFormValue("js") == "1") js := (r.PostFormValue("js") == "1")
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { if err != nil {
@ -584,7 +584,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -622,7 +622,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_edit_topic", topic.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -630,7 +630,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
if !js { if !js {
http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther) http.Redirect(w, r, "/topic/"+strconv.Itoa(tid), http.StatusSeeOther)
} else { } else {
outBytes, err := json.Marshal(JsonReply{c.ParseMessage(topic.Content, topic.ParentID, "forums", user.ParseSettings, &user)}) outBytes, err := json.Marshal(JsonReply{c.ParseMessage(topic.Content, topic.ParentID, "forums", user.ParseSettings, user)})
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
@ -641,7 +641,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
// TODO: Add support for soft-deletion and add a permission for hard delete in addition to the usual // TODO: Add support for soft-deletion and add a permission for hard delete in addition to the usual
// TODO: Disable stat updates in posts handled by plugin_guilds // TODO: Disable stat updates in posts handled by plugin_guilds
func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
// TODO: Move this to some sort of middleware // TODO: Move this to some sort of middleware
var tids []int var tids []int
js := false js := false
@ -674,7 +674,7 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -702,7 +702,7 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
}*/ }*/
// TODO: Do a bulk delete action hook? // TODO: Do a bulk delete action hook?
skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_delete_topic", topic.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -713,7 +713,7 @@ func DeleteTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Ro
return nil return nil
} }
func StickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func StickTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
topic, lite, rerr := topicActionPre(stid, "pin", w, r, user) topic, lite, rerr := topicActionPre(stid, "pin", w, r, user)
if rerr != nil { if rerr != nil {
return rerr return rerr
@ -724,7 +724,7 @@ func StickTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid
return topicActionPost(topic.Stick(), "stick", w, r, lite, topic, user) return topicActionPost(topic.Stick(), "stick", w, r, lite, topic, user)
} }
func topicActionPre(stid, action string, w http.ResponseWriter, r *http.Request, user c.User) (*c.Topic, *c.HeaderLite, c.RouteError) { func topicActionPre(stid, action string, w http.ResponseWriter, r *http.Request, u *c.User) (*c.Topic, *c.HeaderLite, c.RouteError) {
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { if err != nil {
return nil, nil, c.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r) return nil, nil, c.PreError(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
@ -738,22 +738,22 @@ func topicActionPre(stid, action string, w http.ResponseWriter, r *http.Request,
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, t.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, u, t.ParentID)
if ferr != nil { if ferr != nil {
return nil, nil, ferr return nil, nil, ferr
} }
return t, lite, nil return t, lite, nil
} }
func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Request, lite *c.HeaderLite, topic *c.Topic, user c.User) c.RouteError { func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Request, lite *c.HeaderLite, topic *c.Topic, u *c.User) c.RouteError {
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
err = addTopicAction(action, topic, user) err = addTopicAction(action, topic, u)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_"+action+"_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_"+action+"_topic", topic.ID, u)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -761,7 +761,7 @@ func topicActionPost(err error, action string, w http.ResponseWriter, r *http.Re
return nil return nil
} }
func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError { func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, u *c.User, stid string) c.RouteError {
t, lite, rerr := topicActionPre(stid, "unpin", w, r, u) t, lite, rerr := topicActionPre(stid, "unpin", w, r, u)
if rerr != nil { if rerr != nil {
return rerr return rerr
@ -772,7 +772,7 @@ func UnstickTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid s
return topicActionPost(t.Unstick(), "unstick", w, r, lite, t, u) return topicActionPost(t.Unstick(), "unstick", w, r, lite, t, u)
} }
func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError { func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
// TODO: Move this to some sort of middleware // TODO: Move this to some sort of middleware
var tids []int var tids []int
js := false js := false
@ -805,7 +805,7 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -824,7 +824,7 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
} }
// TODO: Do a bulk lock action hook? // TODO: Do a bulk lock action hook?
skip, rerr := lite.Hooks.VhookSkippable("action_end_lock_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_lock_topic", topic.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -836,7 +836,7 @@ func LockTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.Rout
return nil return nil
} }
func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid string) c.RouteError { func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, u *c.User, stid string) c.RouteError {
t, lite, rerr := topicActionPre(stid, "unlock", w, r, u) t, lite, rerr := topicActionPre(stid, "unlock", w, r, u)
if rerr != nil { if rerr != nil {
return rerr return rerr
@ -849,7 +849,7 @@ func UnlockTopicSubmit(w http.ResponseWriter, r *http.Request, u c.User, stid st
// ! JS only route // ! JS only route
// TODO: Figure a way to get this route to work without JS // TODO: Figure a way to get this route to work without JS
func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid string) c.RouteError { func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, sfid string) c.RouteError {
fid, err := strconv.Atoi(sfid) fid, err := strconv.Atoi(sfid)
if err != nil { if err != nil {
return c.PreErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r) return c.PreErrorJS(phrases.GetErrorPhrase("id_must_be_integer"), w, r)
@ -877,14 +877,14 @@ func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid s
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
_, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) _, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.ViewTopic || !user.Perms.MoveTopic { if !user.Perms.ViewTopic || !user.Perms.MoveTopic {
return c.NoPermissionsJS(w, r, user) return c.NoPermissionsJS(w, r, user)
} }
lite, ferr := c.SimpleForumUserCheck(w, r, &user, fid) lite, ferr := c.SimpleForumUserCheck(w, r, user, fid)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -904,7 +904,7 @@ func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid s
} }
// TODO: Do a bulk move action hook? // TODO: Do a bulk move action hook?
skip, rerr := lite.Hooks.VhookSkippable("action_end_move_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_move_topic", topic.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -916,7 +916,7 @@ func MoveTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, sfid s
return nil return nil
} }
func addTopicAction(action string, t *c.Topic, u c.User) error { func addTopicAction(action string, t *c.Topic, u *c.User) error {
err := c.ModLogs.Create(action, t.ID, "topic", u.GetIP(), u.ID) err := c.ModLogs.Create(action, t.ID, "topic", u.GetIP(), u.ID)
if err != nil { if err != nil {
return err return err
@ -925,7 +925,7 @@ func addTopicAction(action string, t *c.Topic, u c.User) error {
} }
// TODO: Refactor this // TODO: Refactor this
func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { if err != nil {
@ -940,7 +940,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -966,14 +966,14 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
// ! Be careful about leaking per-route permission state with &user // ! Be careful about leaking per-route permission state with user ptr
alert := c.Alert{ActorID: user.ID, TargetUserID: topic.CreatedBy, Event: "like", ElementType: "topic", ElementID: tid, Actor: &user} alert := c.Alert{ActorID: user.ID, TargetUserID: topic.CreatedBy, Event: "like", ElementType: "topic", ElementID: tid, Actor: user}
err = c.AddActivityAndNotifyTarget(alert) err = c.AddActivityAndNotifyTarget(alert)
if err != nil { if err != nil {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_like_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_like_topic", topic.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -985,7 +985,7 @@ func LikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
} }
return nil return nil
} }
func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid string) c.RouteError { func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user *c.User, stid string) c.RouteError {
js := r.PostFormValue("js") == "1" js := r.PostFormValue("js") == "1"
tid, err := strconv.Atoi(stid) tid, err := strconv.Atoi(stid)
if err != nil { if err != nil {
@ -1000,7 +1000,7 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid
} }
// TODO: Add hooks to make use of headerLite // TODO: Add hooks to make use of headerLite
lite, ferr := c.SimpleForumUserCheck(w, r, &user, topic.ParentID) lite, ferr := c.SimpleForumUserCheck(w, r, user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
@ -1033,7 +1033,7 @@ func UnlikeTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }
skip, rerr := lite.Hooks.VhookSkippable("action_end_unlike_topic", topic.ID, &user) skip, rerr := lite.Hooks.VhookSkippable("action_end_unlike_topic", topic.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }

View File

@ -19,20 +19,20 @@ func wsTopicList(topicList []*c.TopicsRow, lastPage int) *c.WsTopicList {
return &c.WsTopicList{wsTopicList, lastPage, 0} return &c.WsTopicList{wsTopicList, lastPage, 0}
} }
func TopicList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func TopicList(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
skip, rerr := h.Hooks.VhookSkippable("route_topic_list_start", w, r, &user, h) skip, rerr := h.Hooks.VhookSkippable("route_topic_list_start", w, r, user, h)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
return TopicListCommon(w, r, user, h, "lastupdated", 0) return TopicListCommon(w, r, user, h, "lastupdated", 0)
} }
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header) c.RouteError {
return TopicListCommon(w, r, user, h, "mostviewed", c.TopicListMostViewed) return TopicListCommon(w, r, user, h, "mostviewed", c.TopicListMostViewed)
} }
// TODO: Implement search // TODO: Implement search
func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, torder string, tsorder int) c.RouteError { func TopicListCommon(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Header, torder string, tsorder int) c.RouteError {
h.Title = phrases.GetTitlePhrase("topics") h.Title = phrases.GetTitlePhrase("topics")
h.Zone = "topics" h.Zone = "topics"
h.Path = "/topics/" h.Path = "/topics/"

View File

@ -9,7 +9,7 @@ import (
c "github.com/Azareal/Gosora/common" c "github.com/Azareal/Gosora/common"
) )
func BanUserSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func BanUserSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
if !user.Perms.BanUsers { if !user.Perms.BanUsers {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -93,7 +93,7 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid str
// TODO: Trickle the hookTable down from the router // TODO: Trickle the hookTable down from the router
hTbl := c.GetHookTable() hTbl := c.GetHookTable()
skip, rerr := hTbl.VhookSkippable("action_end_ban_user", targetUser.ID, &user) skip, rerr := hTbl.VhookSkippable("action_end_ban_user", targetUser.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -102,7 +102,7 @@ func BanUserSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid str
return nil return nil
} }
func UnbanUser(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func UnbanUser(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
if !user.Perms.BanUsers { if !user.Perms.BanUsers {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -137,7 +137,7 @@ func UnbanUser(w http.ResponseWriter, r *http.Request, user c.User, suid string)
// TODO: Trickle the hookTable down from the router // TODO: Trickle the hookTable down from the router
hTbl := c.GetHookTable() hTbl := c.GetHookTable()
skip, rerr := hTbl.VhookSkippable("action_end_unban_user", targetUser.ID, &user) skip, rerr := hTbl.VhookSkippable("action_end_unban_user", targetUser.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -146,7 +146,7 @@ func UnbanUser(w http.ResponseWriter, r *http.Request, user c.User, suid string)
return nil return nil
} }
func ActivateUser(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func ActivateUser(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
if !user.Perms.ActivateUsers { if !user.Perms.ActivateUsers {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -188,7 +188,7 @@ func ActivateUser(w http.ResponseWriter, r *http.Request, user c.User, suid stri
// TODO: Trickle the hookTable down from the router // TODO: Trickle the hookTable down from the router
hTbl := c.GetHookTable() hTbl := c.GetHookTable()
skip, rerr := hTbl.VhookSkippable("action_end_activate_user", targetUser.ID, &user) skip, rerr := hTbl.VhookSkippable("action_end_activate_user", targetUser.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
@ -197,7 +197,7 @@ func ActivateUser(w http.ResponseWriter, r *http.Request, user c.User, suid stri
return nil return nil
} }
func DeletePostsSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid string) c.RouteError { func DeletePostsSubmit(w http.ResponseWriter, r *http.Request, user *c.User, suid string) c.RouteError {
if !user.Perms.BanUsers { if !user.Perms.BanUsers {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -230,7 +230,7 @@ func DeletePostsSubmit(w http.ResponseWriter, r *http.Request, user c.User, suid
// TODO: Trickle the hookTable down from the router // TODO: Trickle the hookTable down from the router
hTbl := c.GetHookTable() hTbl := c.GetHookTable()
skip, rerr := hTbl.VhookSkippable("action_end_delete_posts", targetUser.ID, &user) skip, rerr := hTbl.VhookSkippable("action_end_delete_posts", targetUser.ID, user)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }

View File

@ -8,7 +8,7 @@
<div class="formitem"> <div class="formitem">
<a>{{.LangStr}}</a> <a>{{.LangStr}}</a>
<div class="to_right"> <div class="to_right">
<select name="forum-perm-{{.Name}}"> <select name="perm-{{.Name}}">
<option{{if .Toggle}} selected{{end}} value=1>{{lang "option_yes"}}</option> <option{{if .Toggle}} selected{{end}} value=1>{{lang "option_yes"}}</option>
<option{{if not .Toggle}} selected{{end}} value=0>{{lang "option_no"}}</option> <option{{if not .Toggle}} selected{{end}} value=0>{{lang "option_no"}}</option>
</select> </select>