github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/routes/panel/logs.go (about) 1 package panel 2 3 import ( 4 "fmt" 5 "html/template" 6 "net/http" 7 "strconv" 8 "strings" 9 10 c "github.com/Azareal/Gosora/common" 11 p "github.com/Azareal/Gosora/common/phrases" 12 ) 13 14 // TODO: Link the usernames for successful registrations to the profiles 15 func LogsRegs(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { 16 bp, ferr := buildBasePage(w, r, u, "registration_logs", "logs") 17 if ferr != nil { 18 return ferr 19 } 20 logCount := c.RegLogs.Count() 21 page, _ := strconv.Atoi(r.FormValue("page")) 22 perPage := 12 23 offset, page, lastPage := c.PageOffset(logCount, page, perPage) 24 25 logs, err := c.RegLogs.GetOffset(offset, perPage) 26 if err != nil { 27 return c.InternalError(err, w, r) 28 } 29 llist := make([]c.PageRegLogItem, len(logs)) 30 for index, log := range logs { 31 llist[index] = c.PageRegLogItem{log, strings.Replace(strings.TrimSuffix(log.FailureReason, "|"), "|", " | ", -1)} 32 } 33 34 pageList := c.Paginate(page, lastPage, 5) 35 pi := c.PanelRegLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}} 36 return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_reglogs", pi}) 37 } 38 39 // TODO: Log errors when something really screwy is going on? 40 // TODO: Base the slugs on the localised usernames? 41 func handleUnknownUser(u *c.User, e error) *c.User { 42 if e != nil { 43 return &c.User{Name: p.GetTmplPhrase("user_unknown"), Link: c.BuildProfileURL("unknown", 0)} 44 } 45 return u 46 } 47 func handleUnknownTopic(t *c.Topic, e error) *c.Topic { 48 if e != nil { 49 return &c.Topic{Title: p.GetTmplPhrase("topic_unknown"), Link: c.BuildTopicURL("unknown", 0)} 50 } 51 return t 52 } 53 54 // TODO: Move the log building logic into /common/ and it's own abstraction 55 func topicElementTypeAction(action, elementType string, elementID int, actor *c.User, topic *c.Topic) (out string) { 56 if action == "delete" { 57 return p.GetTmplPhrasef("panel_logs_mod_action_topic_delete", elementID, actor.Link, actor.Name) 58 } 59 var tbit string 60 aarr := strings.Split(action, "-") 61 switch aarr[0] { 62 case "lock", "unlock", "stick", "unstick": 63 tbit = aarr[0] 64 case "move": 65 if len(aarr) == 2 { 66 fid, _ := strconv.Atoi(aarr[1]) 67 forum, err := c.Forums.Get(fid) 68 if err == nil { 69 return p.GetTmplPhrasef("panel_logs_mod_action_topic_move_dest", topic.Link, topic.Title, forum.Link, forum.Name, actor.Link, actor.Name) 70 } 71 } 72 tbit = "move" 73 default: 74 return p.GetTmplPhrasef("panel_logs_mod_action_topic_unknown", action, elementType, actor.Link, actor.Name) 75 } 76 if tbit != "" { 77 return p.GetTmplPhrasef("panel_logs_mod_action_topic_"+tbit, topic.Link, topic.Title, actor.Link, actor.Name) 78 } 79 return fmt.Sprintf(out, topic.Link, topic.Title, actor.Link, actor.Name) 80 } 81 82 func modlogsElementType(action, elementType string, elementID int, actor *c.User) (out string) { 83 switch elementType { 84 case "topic": 85 topic := handleUnknownTopic(c.Topics.Get(elementID)) 86 out = topicElementTypeAction(action, elementType, elementID, actor, topic) 87 case "user": 88 targetUser := handleUnknownUser(c.Users.Get(elementID)) 89 out = p.GetTmplPhrasef("panel_logs_mod_action_user_"+action, targetUser.Link, targetUser.Name, actor.Link, actor.Name) 90 case "reply": 91 if action == "delete" { 92 topic := handleUnknownTopic(c.TopicByReplyID(elementID)) 93 out = p.GetTmplPhrasef("panel_logs_mod_action_reply_delete", topic.Link, topic.Title, actor.Link, actor.Name) 94 } 95 case "profile-reply": 96 if action == "delete" { 97 // TODO: Optimise this 98 var profile *c.User 99 profileReply, err := c.Prstore.Get(elementID) 100 if err != nil { 101 profile = &c.User{Name: p.GetTmplPhrase("user_unknown"), Link: c.BuildProfileURL("unknown", 0)} 102 } else { 103 profile = handleUnknownUser(c.Users.Get(profileReply.ParentID)) 104 } 105 out = p.GetTmplPhrasef("panel_logs_mod_action_profile_reply_delete", profile.Link, profile.Name, actor.Link, actor.Name) 106 } 107 } 108 if out == "" { 109 out = p.GetTmplPhrasef("panel_logs_mod_action_unknown", action, elementType, actor.Link, actor.Name) 110 } 111 return out 112 } 113 114 func adminlogsElementType(action, elementType string, elementID int, actor *c.User, extra string) (out string) { 115 switch elementType { 116 // TODO: Record more detail for this, e.g. which field/s was changed 117 case "user": 118 tu := handleUnknownUser(c.Users.Get(elementID)) 119 out = p.GetTmplPhrasef("panel_logs_admin_action_user_"+action, tu.Link, tu.Name, actor.Link, actor.Name) 120 case "group": 121 g, err := c.Groups.Get(elementID) 122 if err != nil { 123 g = &c.Group{Name: p.GetTmplPhrase("group_unknown")} 124 } 125 out = p.GetTmplPhrasef("panel_logs_admin_action_group_"+action, "/panel/groups/edit/"+strconv.Itoa(g.ID), g.Name, actor.Link, actor.Name) 126 case "group_promotion": 127 out = p.GetTmplPhrasef("panel_logs_admin_action_group_promotion_"+action, actor.Link, actor.Name) 128 case "forum": 129 f, err := c.Forums.Get(elementID) 130 if err != nil { 131 f = &c.Forum{Name: p.GetTmplPhrase("forum_unknown")} 132 } 133 if action == "reorder" { 134 out = p.GetTmplPhrasef("panel_logs_admin_action_forum_reorder", actor.Link, actor.Name) 135 } else { 136 out = p.GetTmplPhrasef("panel_logs_admin_action_forum_"+action, "/panel/forums/edit/"+strconv.Itoa(f.ID), f.Name, actor.Link, actor.Name) 137 } 138 case "page": 139 pp, err := c.Pages.Get(elementID) 140 if err != nil { 141 pp = &c.CustomPage{Name: p.GetTmplPhrase("page_unknown")} 142 } 143 out = p.GetTmplPhrasef("panel_logs_admin_action_page_"+action, "/panel/pages/edit/"+strconv.Itoa(pp.ID), pp.Name, actor.Link, actor.Name) 144 case "setting": 145 s, err := c.SettingBox.Load().(c.SettingMap).BypassGet(action) 146 if err != nil { 147 s = &c.Setting{Name: p.GetTmplPhrase("setting_unknown")} 148 } 149 out = p.GetTmplPhrasef("panel_logs_admin_action_setting_edit", "/panel/settings/edit/"+s.Name, s.Name, actor.Link, actor.Name) 150 case "word_filter": 151 out = p.GetTmplPhrasef("panel_logs_admin_action_word_filter_"+action, actor.Link, actor.Name) 152 case "menu": 153 if action == "suborder" { 154 out = p.GetTmplPhrasef("panel_logs_admin_action_menu_suborder", elementID, actor.Link, actor.Name) 155 } 156 case "menu_item": 157 out = p.GetTmplPhrasef("panel_logs_admin_action_menu_item_"+action, "/panel/themes/menus/item/edit/"+strconv.Itoa(elementID), elementID, actor.Link, actor.Name) 158 case "widget": 159 out = p.GetTmplPhrasef("panel_logs_admin_action_widget_"+action, "/panel/themes/widgets/", elementID, actor.Link, actor.Name) 160 case "plugin": 161 out = p.GetTmplPhrasef("panel_logs_admin_action_plugin_"+action, extra, actor.Link, actor.Name) 162 case "backup": 163 out = p.GetTmplPhrasef("panel_logs_admin_action_backup_"+action, actor.Link, actor.Name) 164 } 165 if out == "" { 166 out = p.GetTmplPhrasef("panel_logs_admin_action_unknown", action, elementType, actor.Link, actor.Name) 167 } 168 return out 169 } 170 171 func LogsMod(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { 172 bp, ferr := buildBasePage(w, r, u, "mod_logs", "logs") 173 if ferr != nil { 174 return ferr 175 } 176 page, _ := strconv.Atoi(r.FormValue("page")) 177 perPage := 12 178 offset, page, lastPage := c.PageOffset(c.ModLogs.Count(), page, perPage) 179 180 logs, err := c.ModLogs.GetOffset(offset, perPage) 181 if err != nil { 182 return c.InternalError(err, w, r) 183 } 184 llist := make([]c.PageLogItem, len(logs)) 185 for index, log := range logs { 186 actor := handleUnknownUser(c.Users.Get(log.ActorID)) 187 action := modlogsElementType(log.Action, log.ElementType, log.ElementID, actor) 188 llist[index] = c.PageLogItem{Action: template.HTML(action), IP: log.IP, DoneAt: log.DoneAt} 189 } 190 191 pageList := c.Paginate(page, lastPage, 5) 192 pi := c.PanelLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}} 193 return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_modlogs", pi}) 194 } 195 196 func LogsAdmin(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError { 197 bp, ferr := buildBasePage(w, r, u, "admin_logs", "logs") 198 if ferr != nil { 199 return ferr 200 } 201 page, _ := strconv.Atoi(r.FormValue("page")) 202 perPage := 12 203 offset, page, lastPage := c.PageOffset(c.AdminLogs.Count(), page, perPage) 204 205 logs, err := c.AdminLogs.GetOffset(offset, perPage) 206 if err != nil { 207 return c.InternalError(err, w, r) 208 } 209 llist := make([]c.PageLogItem, len(logs)) 210 for index, log := range logs { 211 actor := handleUnknownUser(c.Users.Get(log.ActorID)) 212 action := adminlogsElementType(log.Action, log.ElementType, log.ElementID, actor, log.Extra) 213 llist[index] = c.PageLogItem{Action: template.HTML(action), IP: log.IP, DoneAt: log.DoneAt} 214 } 215 216 pageList := c.Paginate(page, lastPage, 5) 217 pi := c.PanelLogsPage{bp, llist, c.Paginator{pageList, page, lastPage}} 218 return renderTemplate("panel", w, r, bp.Header, c.Panel{bp, "", "", "panel_adminlogs", pi}) 219 }