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  }