From 430df1e325afde59a284161128ed08d5ed3839e1 Mon Sep 17 00:00:00 2001 From: Azareal Date: Tue, 12 Nov 2019 16:17:46 +1000 Subject: [PATCH] Add blocklist page. Add account_blocked phrase. Add account_menu_blocked phrase. Add account_blocked_head phrase. Add account_blocked_remove phrase. Add account_blocked_no_users phrase. --- common/pages.go | 6 + common/relations.go | 45 +++- gen_router.go | 369 +++++++++++++++++---------------- langs/english.json | 6 + router_gen/routes.go | 1 + routes/account.go | 24 +++ templates/account_blocked.html | 17 ++ templates/account_menu.html | 1 + 8 files changed, 286 insertions(+), 183 deletions(-) create mode 100644 templates/account_blocked.html diff --git a/common/pages.go b/common/pages.go index ded11a8b..321e35e4 100644 --- a/common/pages.go +++ b/common/pages.go @@ -242,6 +242,12 @@ type AccountLoginsPage struct { Paginator } +type AccountBlocksPage struct { + *Header + Users []*User + Paginator +} + type AccountDashPage struct { *Header MFASetup bool diff --git a/common/relations.go b/common/relations.go index 9307582f..ad629644 100644 --- a/common/relations.go +++ b/common/relations.go @@ -14,20 +14,26 @@ type BlockStore interface { IsBlockedBy(blocker, blockee int) (bool, error) Add(blocker, blockee int) error Remove(blocker, blockee int) error + BlockedByOffset(blocker, offset, perPage int) ([]int, error) + BlockedByCount(blocker int) int } type DefaultBlockStore struct { - isBlocked *sql.Stmt - add *sql.Stmt - remove *sql.Stmt + isBlocked *sql.Stmt + add *sql.Stmt + remove *sql.Stmt + blockedBy *sql.Stmt + blockedByCount *sql.Stmt } func NewDefaultBlockStore(acc *qgen.Accumulator) (*DefaultBlockStore, error) { ub := "users_blocks" return &DefaultBlockStore{ - isBlocked: acc.Select(ub).Cols("blocker").Where("blocker = ? AND blockedUser = ?").Prepare(), - add: acc.Insert(ub).Columns("blocker,blockedUser").Fields("?,?").Prepare(), - remove: acc.Delete(ub).Where("blocker = ? AND blockedUser = ?").Prepare(), + isBlocked: acc.Select(ub).Cols("blocker").Where("blocker = ? AND blockedUser = ?").Prepare(), + add: acc.Insert(ub).Columns("blocker,blockedUser").Fields("?,?").Prepare(), + remove: acc.Delete(ub).Where("blocker = ? AND blockedUser = ?").Prepare(), + blockedBy: acc.Select(ub).Columns("blockedUser").Where("blocker = ?").Limit("?,?").Prepare(), + blockedByCount: acc.Count(ub).Where("blocker = ?").Prepare(), }, acc.FirstError() } @@ -49,6 +55,33 @@ func (s *DefaultBlockStore) Remove(blocker, blockee int) error { return err } +func (s *DefaultBlockStore) BlockedByOffset(blocker, offset, perPage int) (uids []int, err error) { + rows, err := s.blockedBy.Query(blocker, offset, perPage) + if err != nil { + return nil, err + } + defer rows.Close() + + for rows.Next() { + var uid int + err := rows.Scan(&uid) + if err != nil { + return nil, err + } + uids = append(uids, uid) + } + + return uids, rows.Err() +} + +func (s *DefaultBlockStore) BlockedByCount(blocker int) (count int) { + err := s.blockedByCount.QueryRow(blocker).Scan(&count) + if err != nil { + LogError(err) + } + return count +} + type FriendInvite struct { Requester int Target int diff --git a/gen_router.go b/gen_router.go index c0305854..cc0c98c4 100644 --- a/gen_router.go +++ b/gen_router.go @@ -128,6 +128,7 @@ var RouteMap = map[string]interface{}{ "routes.AccountEditEmail": routes.AccountEditEmail, "routes.AccountEditEmailTokenSubmit": routes.AccountEditEmailTokenSubmit, "routes.AccountLogins": routes.AccountLogins, + "routes.AccountBlocked": routes.AccountBlocked, "routes.LevelList": routes.LevelList, "routes.Convos": routes.Convos, "routes.ConvosCreate": routes.ConvosCreate, @@ -296,65 +297,66 @@ var routeMapEnum = map[string]int{ "routes.AccountEditEmail": 102, "routes.AccountEditEmailTokenSubmit": 103, "routes.AccountLogins": 104, - "routes.LevelList": 105, - "routes.Convos": 106, - "routes.ConvosCreate": 107, - "routes.Convo": 108, - "routes.ConvosCreateSubmit": 109, - "routes.ConvosCreateReplySubmit": 110, - "routes.ConvosDeleteReplySubmit": 111, - "routes.ConvosEditReplySubmit": 112, - "routes.RelationsBlockCreate": 113, - "routes.RelationsBlockCreateSubmit": 114, - "routes.RelationsBlockRemove": 115, - "routes.RelationsBlockRemoveSubmit": 116, - "routes.ViewProfile": 117, - "routes.BanUserSubmit": 118, - "routes.UnbanUser": 119, - "routes.ActivateUser": 120, - "routes.IPSearch": 121, - "routes.CreateTopicSubmit": 122, - "routes.EditTopicSubmit": 123, - "routes.DeleteTopicSubmit": 124, - "routes.StickTopicSubmit": 125, - "routes.UnstickTopicSubmit": 126, - "routes.LockTopicSubmit": 127, - "routes.UnlockTopicSubmit": 128, - "routes.MoveTopicSubmit": 129, - "routes.LikeTopicSubmit": 130, - "routes.AddAttachToTopicSubmit": 131, - "routes.RemoveAttachFromTopicSubmit": 132, - "routes.ViewTopic": 133, - "routes.CreateReplySubmit": 134, - "routes.ReplyEditSubmit": 135, - "routes.ReplyDeleteSubmit": 136, - "routes.ReplyLikeSubmit": 137, - "routes.AddAttachToReplySubmit": 138, - "routes.RemoveAttachFromReplySubmit": 139, - "routes.ProfileReplyCreateSubmit": 140, - "routes.ProfileReplyEditSubmit": 141, - "routes.ProfileReplyDeleteSubmit": 142, - "routes.PollVote": 143, - "routes.PollResults": 144, - "routes.AccountLogin": 145, - "routes.AccountRegister": 146, - "routes.AccountLogout": 147, - "routes.AccountLoginSubmit": 148, - "routes.AccountLoginMFAVerify": 149, - "routes.AccountLoginMFAVerifySubmit": 150, - "routes.AccountRegisterSubmit": 151, - "routes.AccountPasswordReset": 152, - "routes.AccountPasswordResetSubmit": 153, - "routes.AccountPasswordResetToken": 154, - "routes.AccountPasswordResetTokenSubmit": 155, - "routes.DynamicRoute": 156, - "routes.UploadedFile": 157, - "routes.StaticFile": 158, - "routes.RobotsTxt": 159, - "routes.SitemapXml": 160, - "routes.OpenSearchXml": 161, - "routes.BadRoute": 162, - "routes.HTTPSRedirect": 163, + "routes.AccountBlocked": 105, + "routes.LevelList": 106, + "routes.Convos": 107, + "routes.ConvosCreate": 108, + "routes.Convo": 109, + "routes.ConvosCreateSubmit": 110, + "routes.ConvosCreateReplySubmit": 111, + "routes.ConvosDeleteReplySubmit": 112, + "routes.ConvosEditReplySubmit": 113, + "routes.RelationsBlockCreate": 114, + "routes.RelationsBlockCreateSubmit": 115, + "routes.RelationsBlockRemove": 116, + "routes.RelationsBlockRemoveSubmit": 117, + "routes.ViewProfile": 118, + "routes.BanUserSubmit": 119, + "routes.UnbanUser": 120, + "routes.ActivateUser": 121, + "routes.IPSearch": 122, + "routes.CreateTopicSubmit": 123, + "routes.EditTopicSubmit": 124, + "routes.DeleteTopicSubmit": 125, + "routes.StickTopicSubmit": 126, + "routes.UnstickTopicSubmit": 127, + "routes.LockTopicSubmit": 128, + "routes.UnlockTopicSubmit": 129, + "routes.MoveTopicSubmit": 130, + "routes.LikeTopicSubmit": 131, + "routes.AddAttachToTopicSubmit": 132, + "routes.RemoveAttachFromTopicSubmit": 133, + "routes.ViewTopic": 134, + "routes.CreateReplySubmit": 135, + "routes.ReplyEditSubmit": 136, + "routes.ReplyDeleteSubmit": 137, + "routes.ReplyLikeSubmit": 138, + "routes.AddAttachToReplySubmit": 139, + "routes.RemoveAttachFromReplySubmit": 140, + "routes.ProfileReplyCreateSubmit": 141, + "routes.ProfileReplyEditSubmit": 142, + "routes.ProfileReplyDeleteSubmit": 143, + "routes.PollVote": 144, + "routes.PollResults": 145, + "routes.AccountLogin": 146, + "routes.AccountRegister": 147, + "routes.AccountLogout": 148, + "routes.AccountLoginSubmit": 149, + "routes.AccountLoginMFAVerify": 150, + "routes.AccountLoginMFAVerifySubmit": 151, + "routes.AccountRegisterSubmit": 152, + "routes.AccountPasswordReset": 153, + "routes.AccountPasswordResetSubmit": 154, + "routes.AccountPasswordResetToken": 155, + "routes.AccountPasswordResetTokenSubmit": 156, + "routes.DynamicRoute": 157, + "routes.UploadedFile": 158, + "routes.StaticFile": 159, + "routes.RobotsTxt": 160, + "routes.SitemapXml": 161, + "routes.OpenSearchXml": 162, + "routes.BadRoute": 163, + "routes.HTTPSRedirect": 164, } var reverseRouteMapEnum = map[int]string{ 0: "routes.Overview", @@ -462,65 +464,66 @@ var reverseRouteMapEnum = map[int]string{ 102: "routes.AccountEditEmail", 103: "routes.AccountEditEmailTokenSubmit", 104: "routes.AccountLogins", - 105: "routes.LevelList", - 106: "routes.Convos", - 107: "routes.ConvosCreate", - 108: "routes.Convo", - 109: "routes.ConvosCreateSubmit", - 110: "routes.ConvosCreateReplySubmit", - 111: "routes.ConvosDeleteReplySubmit", - 112: "routes.ConvosEditReplySubmit", - 113: "routes.RelationsBlockCreate", - 114: "routes.RelationsBlockCreateSubmit", - 115: "routes.RelationsBlockRemove", - 116: "routes.RelationsBlockRemoveSubmit", - 117: "routes.ViewProfile", - 118: "routes.BanUserSubmit", - 119: "routes.UnbanUser", - 120: "routes.ActivateUser", - 121: "routes.IPSearch", - 122: "routes.CreateTopicSubmit", - 123: "routes.EditTopicSubmit", - 124: "routes.DeleteTopicSubmit", - 125: "routes.StickTopicSubmit", - 126: "routes.UnstickTopicSubmit", - 127: "routes.LockTopicSubmit", - 128: "routes.UnlockTopicSubmit", - 129: "routes.MoveTopicSubmit", - 130: "routes.LikeTopicSubmit", - 131: "routes.AddAttachToTopicSubmit", - 132: "routes.RemoveAttachFromTopicSubmit", - 133: "routes.ViewTopic", - 134: "routes.CreateReplySubmit", - 135: "routes.ReplyEditSubmit", - 136: "routes.ReplyDeleteSubmit", - 137: "routes.ReplyLikeSubmit", - 138: "routes.AddAttachToReplySubmit", - 139: "routes.RemoveAttachFromReplySubmit", - 140: "routes.ProfileReplyCreateSubmit", - 141: "routes.ProfileReplyEditSubmit", - 142: "routes.ProfileReplyDeleteSubmit", - 143: "routes.PollVote", - 144: "routes.PollResults", - 145: "routes.AccountLogin", - 146: "routes.AccountRegister", - 147: "routes.AccountLogout", - 148: "routes.AccountLoginSubmit", - 149: "routes.AccountLoginMFAVerify", - 150: "routes.AccountLoginMFAVerifySubmit", - 151: "routes.AccountRegisterSubmit", - 152: "routes.AccountPasswordReset", - 153: "routes.AccountPasswordResetSubmit", - 154: "routes.AccountPasswordResetToken", - 155: "routes.AccountPasswordResetTokenSubmit", - 156: "routes.DynamicRoute", - 157: "routes.UploadedFile", - 158: "routes.StaticFile", - 159: "routes.RobotsTxt", - 160: "routes.SitemapXml", - 161: "routes.OpenSearchXml", - 162: "routes.BadRoute", - 163: "routes.HTTPSRedirect", + 105: "routes.AccountBlocked", + 106: "routes.LevelList", + 107: "routes.Convos", + 108: "routes.ConvosCreate", + 109: "routes.Convo", + 110: "routes.ConvosCreateSubmit", + 111: "routes.ConvosCreateReplySubmit", + 112: "routes.ConvosDeleteReplySubmit", + 113: "routes.ConvosEditReplySubmit", + 114: "routes.RelationsBlockCreate", + 115: "routes.RelationsBlockCreateSubmit", + 116: "routes.RelationsBlockRemove", + 117: "routes.RelationsBlockRemoveSubmit", + 118: "routes.ViewProfile", + 119: "routes.BanUserSubmit", + 120: "routes.UnbanUser", + 121: "routes.ActivateUser", + 122: "routes.IPSearch", + 123: "routes.CreateTopicSubmit", + 124: "routes.EditTopicSubmit", + 125: "routes.DeleteTopicSubmit", + 126: "routes.StickTopicSubmit", + 127: "routes.UnstickTopicSubmit", + 128: "routes.LockTopicSubmit", + 129: "routes.UnlockTopicSubmit", + 130: "routes.MoveTopicSubmit", + 131: "routes.LikeTopicSubmit", + 132: "routes.AddAttachToTopicSubmit", + 133: "routes.RemoveAttachFromTopicSubmit", + 134: "routes.ViewTopic", + 135: "routes.CreateReplySubmit", + 136: "routes.ReplyEditSubmit", + 137: "routes.ReplyDeleteSubmit", + 138: "routes.ReplyLikeSubmit", + 139: "routes.AddAttachToReplySubmit", + 140: "routes.RemoveAttachFromReplySubmit", + 141: "routes.ProfileReplyCreateSubmit", + 142: "routes.ProfileReplyEditSubmit", + 143: "routes.ProfileReplyDeleteSubmit", + 144: "routes.PollVote", + 145: "routes.PollResults", + 146: "routes.AccountLogin", + 147: "routes.AccountRegister", + 148: "routes.AccountLogout", + 149: "routes.AccountLoginSubmit", + 150: "routes.AccountLoginMFAVerify", + 151: "routes.AccountLoginMFAVerifySubmit", + 152: "routes.AccountRegisterSubmit", + 153: "routes.AccountPasswordReset", + 154: "routes.AccountPasswordResetSubmit", + 155: "routes.AccountPasswordResetToken", + 156: "routes.AccountPasswordResetTokenSubmit", + 157: "routes.DynamicRoute", + 158: "routes.UploadedFile", + 159: "routes.StaticFile", + 160: "routes.RobotsTxt", + 161: "routes.SitemapXml", + 162: "routes.OpenSearchXml", + 163: "routes.BadRoute", + 164: "routes.HTTPSRedirect", } var osMapEnum = map[string]int{ "unknown": 0, @@ -678,7 +681,7 @@ type HTTPSRedirect struct {} func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Header().Set("Connection", "close") - co.RouteViewCounter.Bump(163) + co.RouteViewCounter.Bump(164) dest := "https://" + req.Host + req.URL.String() http.Redirect(w, req, dest, http.StatusTemporaryRedirect) } @@ -886,7 +889,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { co.GlobalViewCounter.Bump() if prefix == "/s" { //old prefix: /static - co.RouteViewCounter.Bump(158) + co.RouteViewCounter.Bump(159) req.URL.Path += extraData routes.StaticFile(w, req) return @@ -1874,7 +1877,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } err = routes.AccountLogins(w,req,user,head) - case "/user/levels/": + case "/user/edit/blocked/": err = c.MemberOnly(w,req,user) if err != nil { return err @@ -1882,6 +1885,18 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c co.RouteViewCounter.Bump(105) head, err := c.UserCheck(w,req,&user) + if err != nil { + return err + } + err = routes.AccountBlocked(w,req,user,head) + case "/user/levels/": + err = c.MemberOnly(w,req,user) + if err != nil { + return err + } + + co.RouteViewCounter.Bump(106) + head, err := c.UserCheck(w,req,&user) if err != nil { return err } @@ -1892,7 +1907,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(106) + co.RouteViewCounter.Bump(107) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -1904,7 +1919,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(107) + co.RouteViewCounter.Bump(108) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -1916,7 +1931,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(108) + co.RouteViewCounter.Bump(109) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -1933,7 +1948,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(109) + co.RouteViewCounter.Bump(110) err = routes.ConvosCreateSubmit(w,req,user) case "/user/convo/create/submit/": err = c.NoSessionMismatch(w,req,user) @@ -1946,7 +1961,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(110) + co.RouteViewCounter.Bump(111) err = routes.ConvosCreateReplySubmit(w,req,user,extraData) case "/user/convo/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -1959,7 +1974,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(111) + co.RouteViewCounter.Bump(112) err = routes.ConvosDeleteReplySubmit(w,req,user,extraData) case "/user/convo/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -1972,7 +1987,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(112) + co.RouteViewCounter.Bump(113) err = routes.ConvosEditReplySubmit(w,req,user,extraData) case "/user/block/create/": err = c.MemberOnly(w,req,user) @@ -1980,7 +1995,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(113) + co.RouteViewCounter.Bump(114) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -1997,7 +2012,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(114) + co.RouteViewCounter.Bump(115) err = routes.RelationsBlockCreateSubmit(w,req,user,extraData) case "/user/block/remove/": err = c.MemberOnly(w,req,user) @@ -2005,7 +2020,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(115) + co.RouteViewCounter.Bump(116) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2022,11 +2037,11 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(116) + co.RouteViewCounter.Bump(117) err = routes.RelationsBlockRemoveSubmit(w,req,user,extraData) default: req.URL.Path += extraData - co.RouteViewCounter.Bump(117) + co.RouteViewCounter.Bump(118) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2046,7 +2061,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(118) + co.RouteViewCounter.Bump(119) err = routes.BanUserSubmit(w,req,user,extraData) case "/users/unban/": err = c.NoSessionMismatch(w,req,user) @@ -2059,7 +2074,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(119) + co.RouteViewCounter.Bump(120) err = routes.UnbanUser(w,req,user,extraData) case "/users/activate/": err = c.NoSessionMismatch(w,req,user) @@ -2072,7 +2087,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(120) + co.RouteViewCounter.Bump(121) err = routes.ActivateUser(w,req,user,extraData) case "/users/ips/": err = c.MemberOnly(w,req,user) @@ -2080,7 +2095,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(121) + co.RouteViewCounter.Bump(122) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2104,7 +2119,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(122) + co.RouteViewCounter.Bump(123) err = routes.CreateTopicSubmit(w,req,user) case "/topic/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2117,7 +2132,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(123) + co.RouteViewCounter.Bump(124) err = routes.EditTopicSubmit(w,req,user,extraData) case "/topic/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2131,7 +2146,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c } req.URL.Path += extraData - co.RouteViewCounter.Bump(124) + co.RouteViewCounter.Bump(125) err = routes.DeleteTopicSubmit(w,req,user) case "/topic/stick/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2144,7 +2159,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(125) + co.RouteViewCounter.Bump(126) err = routes.StickTopicSubmit(w,req,user,extraData) case "/topic/unstick/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2157,7 +2172,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(126) + co.RouteViewCounter.Bump(127) err = routes.UnstickTopicSubmit(w,req,user,extraData) case "/topic/lock/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2171,7 +2186,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c } req.URL.Path += extraData - co.RouteViewCounter.Bump(127) + co.RouteViewCounter.Bump(128) err = routes.LockTopicSubmit(w,req,user) case "/topic/unlock/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2184,7 +2199,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(128) + co.RouteViewCounter.Bump(129) err = routes.UnlockTopicSubmit(w,req,user,extraData) case "/topic/move/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2197,7 +2212,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(129) + co.RouteViewCounter.Bump(130) err = routes.MoveTopicSubmit(w,req,user,extraData) case "/topic/like/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2210,7 +2225,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(130) + co.RouteViewCounter.Bump(131) err = routes.LikeTopicSubmit(w,req,user,extraData) case "/topic/attach/add/submit/": err = c.MemberOnly(w,req,user) @@ -2227,7 +2242,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(131) + co.RouteViewCounter.Bump(132) err = routes.AddAttachToTopicSubmit(w,req,user,extraData) case "/topic/attach/remove/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2240,10 +2255,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(132) + co.RouteViewCounter.Bump(133) err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData) default: - co.RouteViewCounter.Bump(133) + co.RouteViewCounter.Bump(134) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2267,7 +2282,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(134) + co.RouteViewCounter.Bump(135) err = routes.CreateReplySubmit(w,req,user) case "/reply/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2280,7 +2295,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(135) + co.RouteViewCounter.Bump(136) err = routes.ReplyEditSubmit(w,req,user,extraData) case "/reply/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2293,7 +2308,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(136) + co.RouteViewCounter.Bump(137) err = routes.ReplyDeleteSubmit(w,req,user,extraData) case "/reply/like/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2306,7 +2321,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(137) + co.RouteViewCounter.Bump(138) err = routes.ReplyLikeSubmit(w,req,user,extraData) case "/reply/attach/add/submit/": err = c.MemberOnly(w,req,user) @@ -2323,7 +2338,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(138) + co.RouteViewCounter.Bump(139) err = routes.AddAttachToReplySubmit(w,req,user,extraData) case "/reply/attach/remove/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2336,7 +2351,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(139) + co.RouteViewCounter.Bump(140) err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData) } case "/profile": @@ -2352,7 +2367,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(140) + co.RouteViewCounter.Bump(141) err = routes.ProfileReplyCreateSubmit(w,req,user) case "/profile/reply/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2365,7 +2380,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(141) + co.RouteViewCounter.Bump(142) err = routes.ProfileReplyEditSubmit(w,req,user,extraData) case "/profile/reply/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2378,7 +2393,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(142) + co.RouteViewCounter.Bump(143) err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData) } case "/poll": @@ -2394,23 +2409,23 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(143) + co.RouteViewCounter.Bump(144) err = routes.PollVote(w,req,user,extraData) case "/poll/results/": - co.RouteViewCounter.Bump(144) + co.RouteViewCounter.Bump(145) err = routes.PollResults(w,req,user,extraData) } case "/accounts": switch(req.URL.Path) { case "/accounts/login/": - co.RouteViewCounter.Bump(145) + co.RouteViewCounter.Bump(146) head, err := c.UserCheck(w,req,&user) if err != nil { return err } err = routes.AccountLogin(w,req,user,head) case "/accounts/create/": - co.RouteViewCounter.Bump(146) + co.RouteViewCounter.Bump(147) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2427,7 +2442,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(147) + co.RouteViewCounter.Bump(148) err = routes.AccountLogout(w,req,user) case "/accounts/login/submit/": err = c.ParseForm(w,req,user) @@ -2435,10 +2450,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(148) + co.RouteViewCounter.Bump(149) err = routes.AccountLoginSubmit(w,req,user) case "/accounts/mfa_verify/": - co.RouteViewCounter.Bump(149) + co.RouteViewCounter.Bump(150) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2450,7 +2465,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(150) + co.RouteViewCounter.Bump(151) err = routes.AccountLoginMFAVerifySubmit(w,req,user) case "/accounts/create/submit/": err = c.ParseForm(w,req,user) @@ -2458,10 +2473,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(151) + co.RouteViewCounter.Bump(152) err = routes.AccountRegisterSubmit(w,req,user) case "/accounts/password-reset/": - co.RouteViewCounter.Bump(152) + co.RouteViewCounter.Bump(153) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2473,10 +2488,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(153) + co.RouteViewCounter.Bump(154) err = routes.AccountPasswordResetSubmit(w,req,user) case "/accounts/password-reset/token/": - co.RouteViewCounter.Bump(154) + co.RouteViewCounter.Bump(155) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2488,7 +2503,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - co.RouteViewCounter.Bump(155) + co.RouteViewCounter.Bump(156) err = routes.AccountPasswordResetTokenSubmit(w,req,user) } /*case "/sitemaps": // TODO: Count these views @@ -2505,7 +2520,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c h.Del("Content-Type") h.Del("Content-Encoding") } - co.RouteViewCounter.Bump(157) + co.RouteViewCounter.Bump(158) req.URL.Path += extraData // TODO: Find a way to propagate errors up from this? r.UploadHandler(w,req) // TODO: Count these views @@ -2515,7 +2530,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c // TODO: Add support for favicons and robots.txt files switch(extraData) { case "robots.txt": - co.RouteViewCounter.Bump(159) + co.RouteViewCounter.Bump(160) return routes.RobotsTxt(w,req) case "favicon.ico": gzw, ok := w.(c.GzipResponseWriter) @@ -2529,10 +2544,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c routes.StaticFile(w,req) return nil case "opensearch.xml": - co.RouteViewCounter.Bump(161) + co.RouteViewCounter.Bump(162) return routes.OpenSearchXml(w,req) /*case "sitemap.xml": - co.RouteViewCounter.Bump(160) + co.RouteViewCounter.Bump(161) return routes.SitemapXml(w,req)*/ } return c.NotFound(w,req,nil) @@ -2543,7 +2558,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c r.RUnlock() if ok { - co.RouteViewCounter.Bump(156) // TODO: Be more specific about *which* dynamic route it is + co.RouteViewCounter.Bump(157) // TODO: Be more specific about *which* dynamic route it is req.URL.Path += extraData return handle(w,req,user) } @@ -2554,7 +2569,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c } else { r.DumpRequest(req,"Bad Route") } - co.RouteViewCounter.Bump(162) + co.RouteViewCounter.Bump(163) return c.NotFound(w,req,nil) } return err diff --git a/langs/english.json b/langs/english.json index 1c1a71ed..9b92fdea 100644 --- a/langs/english.json +++ b/langs/english.json @@ -144,6 +144,7 @@ "account_mfa_setup":"Setup 2FA", "account_email":"Email Manager", "account_logins":"Logins", + "account_blocked":"Blocked", "account_penalties":"Penalties", "account_level_list":"Level Progress", "convos":"Conversations", @@ -502,6 +503,7 @@ "account_menu_security":"Security", "account_menu_notifications":"Notifications", "account_menu_logins":"Logins", + "account_menu_blocked":"Blocked", "account_menu_penalties":"Penalties", "account_menu_messages":"Messages", @@ -546,6 +548,10 @@ "account_logins_success":"Successful Login", "account_logins_failure":"Failed Login", + "account_blocked_head":"Blocked Users", + "account_blocked_remove":"Remove", + "account_blocked_no_users":"You haven't blocked any users.", + "convos_head":"Conversations", "convos_create":"Create Convo", "convos_none":"You don't have any conversations yet.", diff --git a/router_gen/routes.go b/router_gen/routes.go index 86404caf..258089ee 100644 --- a/router_gen/routes.go +++ b/router_gen/routes.go @@ -80,6 +80,7 @@ func userRoutes() *RouteGroup { View("routes.AccountEditEmailTokenSubmit", "/user/edit/token/", "extraData").NoHeader(),*/ MView("routes.AccountLogins", "/user/edit/logins/"), + MView("routes.AccountBlocked", "/user/edit/blocked/"), MView("routes.LevelList", "/user/levels/"), //MView("routes.LevelRankings", "/user/rankings/"), diff --git a/routes/account.go b/routes/account.go index 8772e087..f2009dd5 100644 --- a/routes/account.go +++ b/routes/account.go @@ -715,6 +715,30 @@ func AccountLogins(w http.ResponseWriter, r *http.Request, user c.User, h *c.Hea return renderTemplate("account", w, r, h, pi) } +func AccountBlocked(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { + accountEditHead("account_blocked", w, r, &user, h) + page, _ := strconv.Atoi(r.FormValue("page")) + perPage := 12 + offset, page, lastPage := c.PageOffset(c.UserBlocks.BlockedByCount(user.ID), page, perPage) + + uids, err := c.UserBlocks.BlockedByOffset(user.ID, offset, perPage) + if err != nil { + return c.InternalError(err, w, r) + } + var blocks []*c.User + for _, uid := range uids { + u, err := c.Users.Get(uid) + if err != nil { + return c.InternalError(err,w,r) + } + blocks = append(blocks, u) + } + + pageList := c.Paginate(page, lastPage, 5) + pi := c.Account{h, "logins", "account_blocked", c.AccountBlocksPage{h, blocks, c.Paginator{pageList, page, lastPage}}} + return renderTemplate("account", w, r, h, pi) +} + func LevelList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { h.Title = p.GetTitlePhrase("account_level_list") diff --git a/templates/account_blocked.html b/templates/account_blocked.html new file mode 100644 index 00000000..783cfd0d --- /dev/null +++ b/templates/account_blocked.html @@ -0,0 +1,17 @@ +
+

{{lang "account_blocked_head"}}

+
+
+ {{range .Users}} + + {{else}} + + {{end}} +
+{{template "paginator.html" . }} \ No newline at end of file diff --git a/templates/account_menu.html b/templates/account_menu.html index d566dcd8..2e45290f 100644 --- a/templates/account_menu.html +++ b/templates/account_menu.html @@ -9,6 +9,7 @@
{{lang "account_menu_email"}}
{{lang "account_menu_logins"}}
+
{{lang "account_menu_blocked"}}
{{lang "account_menu_messages"}}
{{/** TODO: Add an alerts page with pagination to go through alerts which either don't fit in the alerts drop-down or which have already been dismissed. Bear in mind though that dismissed alerts older than two weeks might be purged to save space and to speed up the database **/}}