The moderation logs can now be localised.
Error pages which call CustomError should now stick on the theme the user chose rather than the global fallback theme. Move the theme fetching logic out of userCheck and panelUserCheck and into it's own function. Split prepResources out of userCheck, so that errors can make use of it. Fixed a bug where no scripts or stylesheets would run on error pages. Fixed a bug where unknown topics would point to /user/ rather than /topic/ Added the panel_logs_moderation_action_topic_stick phrase. Added the panel_logs_moderation_action_topic_unstick phrase. Added the panel_logs_moderation_action_topic_lock phrase. Added the panel_logs_moderation_action_topic_unlock phrase. Added the panel_logs_moderation_action_topic_delete phrase. Added the panel_logs_moderation_action_topic_move phrase. Added the panel_logs_moderation_action_topic_move_dest phrase. Added the panel_logs_moderation_action_topic_unknown phrase. Added the panel_logs_moderation_action_reply_delete phrase. Added the panel_logs_moderation_action_user_ban phrase. Added the panel_logs_moderation_action_user_unban phrase. Added the panel_logs_moderation_action_user_activate phrase. Added the panel_logs_moderation_action_unknown phrase. Added the user_unknown phrase.
This commit is contained in:
parent
2d366ce6a0
commit
9179eb9711
@ -129,12 +129,14 @@ func errorHeader(w http.ResponseWriter, user User, title string) *Header {
|
||||
header := DefaultHeader(w, user)
|
||||
header.Title = title
|
||||
header.Zone = "error"
|
||||
prepResources(&user, header, header.Theme)
|
||||
return header
|
||||
}
|
||||
|
||||
// TODO: Dump the request?
|
||||
// InternalError is the main function for handling internal errors, while simultaneously printing out a page for the end-user to let them know that *something* has gone wrong
|
||||
// ? - Add a user parameter?
|
||||
// ! Do not call CustomError here or we might get an error loop
|
||||
func InternalError(err error, w http.ResponseWriter, r *http.Request) RouteError {
|
||||
w.WriteHeader(500)
|
||||
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("internal_error_title")), phrases.GetErrorPhrase("internal_error_body")}
|
||||
@ -188,6 +190,7 @@ func SilentInternalErrorXML(err error, w http.ResponseWriter, r *http.Request) R
|
||||
return HandledRouteError()
|
||||
}
|
||||
|
||||
// ! Do not call CustomError here otherwise we might get an error loop
|
||||
func PreError(errmsg string, w http.ResponseWriter, r *http.Request) RouteError {
|
||||
w.WriteHeader(500)
|
||||
pi := ErrorPage{errorHeader(w, GuestUser, phrases.GetErrorPhrase("error_title")), errmsg}
|
||||
@ -342,9 +345,12 @@ func NotFoundJSQ(w http.ResponseWriter, r *http.Request, header *Header, js bool
|
||||
}
|
||||
|
||||
// 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) RouteError {
|
||||
func CustomError(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, header *Header, user User) (rerr RouteError) {
|
||||
if header == nil {
|
||||
header = DefaultHeader(w, user)
|
||||
header, rerr = UserCheck(w, r, &user)
|
||||
if rerr != nil {
|
||||
header = errorHeader(w, user, errtitle)
|
||||
}
|
||||
}
|
||||
header.Title = errtitle
|
||||
header.Zone = "error"
|
||||
|
@ -95,18 +95,7 @@ func cascadeForumPerms(fperms *ForumPerms, user *User) {
|
||||
// Even if they have the right permissions, the control panel is only open to supermods+. There are many areas without subpermissions which assume that the current user is a supermod+ and admins are extremely unlikely to give these permissions to someone who isn't at-least a supermod to begin with
|
||||
// TODO: Do a panel specific theme?
|
||||
func panelUserCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, stats PanelStats, rerr RouteError) {
|
||||
var theme = &Theme{Name: ""}
|
||||
cookie, err := r.Cookie("current_theme")
|
||||
if err == nil {
|
||||
inTheme, ok := Themes[html.EscapeString(cookie.Value)]
|
||||
if ok && !theme.HideFromThemes {
|
||||
theme = inTheme
|
||||
}
|
||||
}
|
||||
if theme.Name == "" {
|
||||
theme = Themes[DefaultThemeBox.Load().(string)]
|
||||
}
|
||||
|
||||
theme := getTheme(r)
|
||||
header = &Header{
|
||||
Site: Site,
|
||||
Settings: SettingBox.Load().(SettingMap),
|
||||
@ -186,8 +175,7 @@ func simpleUserCheck(w http.ResponseWriter, r *http.Request, user *User) (header
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TODO: Add the ability for admins to restrict certain themes to certain groups?
|
||||
func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) {
|
||||
func getTheme(r *http.Request) *Theme {
|
||||
var theme = &Theme{Name: ""}
|
||||
|
||||
cookie, err := r.Cookie("current_theme")
|
||||
@ -201,6 +189,13 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
|
||||
theme = Themes[DefaultThemeBox.Load().(string)]
|
||||
}
|
||||
|
||||
return theme
|
||||
}
|
||||
|
||||
// TODO: Add the ability for admins to restrict certain themes to certain groups?
|
||||
// ! Be careful about firing errors off here as CustomError uses this
|
||||
func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Header, rerr RouteError) {
|
||||
theme := getTheme(r)
|
||||
header = &Header{
|
||||
Site: Site,
|
||||
Settings: SettingBox.Load().(SettingMap),
|
||||
@ -220,13 +215,20 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
|
||||
if user.Loggedin && !user.Active {
|
||||
header.AddNotice("account_inactive")
|
||||
}
|
||||
|
||||
// An optimisation so we don't populate StartedAt for users who shouldn't see the stat anyway
|
||||
// ? - Should we only show this in debug mode? It might be useful for detecting issues in production, if we show it there as-well
|
||||
if user.IsAdmin {
|
||||
header.StartedAt = time.Now()
|
||||
}
|
||||
|
||||
prepResources(user,header,theme)
|
||||
return header, nil
|
||||
}
|
||||
|
||||
func prepResources(user *User, header *Header, theme *Theme) {
|
||||
header.AddSheet(theme.Name + "/main.css")
|
||||
|
||||
if len(theme.Resources) > 0 {
|
||||
rlist := theme.Resources
|
||||
for _, resource := range rlist {
|
||||
@ -269,8 +271,6 @@ func userCheck(w http.ResponseWriter, r *http.Request, user *User) (header *Head
|
||||
addPreScript("topic_c_edit_post")
|
||||
addPreScript("topic_c_attach_item")
|
||||
}
|
||||
|
||||
return header, nil
|
||||
}
|
||||
|
||||
func preRoute(w http.ResponseWriter, r *http.Request) (User, bool) {
|
||||
|
@ -903,7 +903,24 @@
|
||||
"panel_logs_registration_attempt":"Attempt",
|
||||
"panel_logs_registration_email":"email",
|
||||
"panel_logs_registration_reason":"reason",
|
||||
|
||||
"panel_logs_moderation_head":"Mod Action Logs",
|
||||
"panel_logs_moderation_action_topic_stick":"<a href='%s'>%s</a> was pinned by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_unstick":"<a href='%s'>%s</a> was unpinned by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_lock":"<a href='%s'>%s</a> was locked by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_unlock":"<a href='%s'>%s</a> was reopened by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_delete":"Topic #%d was deleted by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_move":"<a href='%s'>%s</a> was moved by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_move_dest":"<a href='%s'>%s</a> was moved to <a href='%s'>%s</a> by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_topic_unknown":"Unknown action '%s' on elementType '%s' by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_reply_delete":"A reply in <a href='%s'>%s</a> was deleted by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_user_ban":"<a href='%s'>%s</a> was banned by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_user_unban":"<a href='%s'>%s</a> was unbanned by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_user_activate":"<a href='%s'>%s</a> was activated by <a href='%s'>%s</a>",
|
||||
"panel_logs_moderation_action_unknown":"Unknown action '%s' on elementType '%s' by <a href='%s'>%s</a>",
|
||||
|
||||
"user_unknown":"Unknown",
|
||||
|
||||
"panel_logs_administration_head":"Admin Action Logs",
|
||||
|
||||
"panel_plugins_head":"Plugins",
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Azareal/Gosora/common"
|
||||
"github.com/Azareal/Gosora/common/phrases"
|
||||
)
|
||||
|
||||
// TODO: Link the usernames for successful registrations to the profiles
|
||||
@ -37,46 +38,44 @@ func LogsRegs(w http.ResponseWriter, r *http.Request, user common.User) common.R
|
||||
}
|
||||
|
||||
// TODO: Log errors when something really screwy is going on?
|
||||
// TODO: Base the slugs on the localised usernames?
|
||||
func handleUnknownUser(user *common.User, err error) *common.User {
|
||||
if err != nil {
|
||||
return &common.User{Name: "Unknown", Link: common.BuildProfileURL("unknown", 0)}
|
||||
return &common.User{Name: phrases.GetTmplPhrase("user_unknown"), Link: common.BuildProfileURL("unknown", 0)}
|
||||
}
|
||||
return user
|
||||
}
|
||||
func handleUnknownTopic(topic *common.Topic, err error) *common.Topic {
|
||||
if err != nil {
|
||||
return &common.Topic{Title: "Unknown", Link: common.BuildProfileURL("unknown", 0)}
|
||||
return &common.Topic{Title: phrases.GetTmplPhrase("user_unknown"), Link: common.BuildTopicURL("unknown", 0)}
|
||||
}
|
||||
return topic
|
||||
}
|
||||
|
||||
// TODO: Move the log building logic into /common/ and it's own abstraction
|
||||
// TODO: Localise this
|
||||
func topicElementTypeAction(action string, elementType string, elementID int, actor *common.User, topic *common.Topic) (out string) {
|
||||
if action == "delete" {
|
||||
return fmt.Sprintf("Topic #%d was deleted by <a href='%s'>%s</a>", elementID, actor.Link, actor.Name)
|
||||
return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_delete", elementID, actor.Link, actor.Name)
|
||||
}
|
||||
var tbit string
|
||||
aarr := strings.Split(action, "-")
|
||||
switch aarr[0] {
|
||||
case "lock":
|
||||
out = "<a href='%s'>%s</a> was locked by <a href='%s'>%s</a>"
|
||||
case "unlock":
|
||||
out = "<a href='%s'>%s</a> was reopened by <a href='%s'>%s</a>"
|
||||
case "stick":
|
||||
out = "<a href='%s'>%s</a> was pinned by <a href='%s'>%s</a>"
|
||||
case "unstick":
|
||||
out = "<a href='%s'>%s</a> was unpinned by <a href='%s'>%s</a>"
|
||||
case "lock","unlock","stick","unstick":
|
||||
tbit = aarr[0]
|
||||
case "move":
|
||||
if len(aarr) == 2 {
|
||||
fid, _ := strconv.Atoi(aarr[1])
|
||||
forum, err := common.Forums.Get(fid)
|
||||
if err == nil {
|
||||
return fmt.Sprintf("<a href='%s'>%s</a> was moved to <a href='%s'>%s</a> by <a href='%s'>%s</a>", topic.Link, topic.Title, forum.Link, forum.Name, actor.Link, actor.Name)
|
||||
return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_move_dest", topic.Link, topic.Title, forum.Link, forum.Name, actor.Link, actor.Name)
|
||||
}
|
||||
}
|
||||
out = "<a href='%s'>%s</a> was moved by <a href='%s'>%s</a>" // TODO: Add where it was moved to, we'll have to change the source data for that, most likely? Investigate that and try to work this in
|
||||
tbit = "move"
|
||||
default:
|
||||
return fmt.Sprintf("Unknown action '%s' on elementType '%s' by <a href='%s'>%s</a>", action, elementType, actor.Link, actor.Name)
|
||||
return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_unknown", action, elementType, actor.Link, actor.Name)
|
||||
}
|
||||
if tbit != "" {
|
||||
return phrases.GetTmplPhrasef("panel_logs_moderation_action_topic_"+tbit, topic.Link, topic.Title, actor.Link, actor.Name)
|
||||
}
|
||||
return fmt.Sprintf(out, topic.Link, topic.Title, actor.Link, actor.Name)
|
||||
}
|
||||
@ -88,24 +87,16 @@ func modlogsElementType(action string, elementType string, elementID int, actor
|
||||
out = topicElementTypeAction(action, elementType, elementID, actor, topic)
|
||||
case "user":
|
||||
targetUser := handleUnknownUser(common.Users.Get(elementID))
|
||||
switch action {
|
||||
case "ban":
|
||||
out = "<a href='%s'>%s</a> was banned by <a href='%s'>%s</a>"
|
||||
case "unban":
|
||||
out = "<a href='%s'>%s</a> was unbanned by <a href='%s'>%s</a>"
|
||||
case "activate":
|
||||
out = "<a href='%s'>%s</a> was activated by <a href='%s'>%s</a>"
|
||||
}
|
||||
out = fmt.Sprintf(out, targetUser.Link, targetUser.Name, actor.Link, actor.Name)
|
||||
out = phrases.GetTmplPhrasef("panel_logs_moderation_action_user_"+action, targetUser.Link, targetUser.Name, actor.Link, actor.Name)
|
||||
case "reply":
|
||||
if action == "delete" {
|
||||
topic := handleUnknownTopic(common.TopicByReplyID(elementID))
|
||||
out = fmt.Sprintf("A reply in <a href='%s'>%s</a> was deleted by <a href='%s'>%s</a>", topic.Link, topic.Title, actor.Link, actor.Name)
|
||||
out = phrases.GetTmplPhrasef("panel_logs_moderation_action_reply_delete", topic.Link, topic.Title, actor.Link, actor.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if out == "" {
|
||||
out = fmt.Sprintf("Unknown action '%s' on elementType '%s' by <a href='%s'>%s</a>", action, elementType, actor.Link, actor.Name)
|
||||
out = phrases.GetTmplPhrasef("panel_logs_moderation_action_unknown", action, elementType, actor.Link, actor.Name)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, header
|
||||
// Get the topic...
|
||||
topic, err := common.GetTopicUser(&user, tid)
|
||||
if err == sql.ErrNoRows {
|
||||
return common.NotFound(w, r, nil) // TODO: Can we add a simplified invocation of headerVars here? This is likely to be an extremely common NotFound
|
||||
return common.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 {
|
||||
return common.InternalError(err, w, r)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user