From 8720de83d86d2ac8ca6372705e7b97e8b4759a8e Mon Sep 17 00:00:00 2001 From: Azareal Date: Fri, 18 Oct 2019 10:35:13 +1000 Subject: [PATCH] Rudimentary user convo blocking. Simplify some things. Add create_block title phrase. Add remove_block title phrase. Add create_block_msg phrase. Add remove_block_msg phrase. Add profile_unblock phrase. Add the users_blocks table. You will need to run the updater / patcher for this commit. --- cmd/query_gen/tables.go | 13 +- common/pages.go | 75 +++--- common/relations.go | 18 +- common/template_init.go | 20 +- gen_router.go | 344 ++++++++++++++++------------ langs/english.json | 6 + main.go | 7 +- patcher/patches.go | 73 +++--- router_gen/routes.go | 6 +- routes/convos.go | 77 ++++++- routes/profile.go | 13 +- schema/mssql/query_users_blocks.sql | 4 + schema/mysql/query_users_blocks.sql | 4 + schema/pgsql/query_users_blocks.sql | 4 + templates/are_you_sure.html | 4 +- templates/profile.html | 5 +- themes/nox/public/main.css | 4 + 17 files changed, 430 insertions(+), 247 deletions(-) create mode 100644 schema/mssql/query_users_blocks.sql create mode 100644 schema/mysql/query_users_blocks.sql create mode 100644 schema/pgsql/query_users_blocks.sql diff --git a/cmd/query_gen/tables.go b/cmd/query_gen/tables.go index 047c9d31..5da79925 100644 --- a/cmd/query_gen/tables.go +++ b/cmd/query_gen/tables.go @@ -431,14 +431,15 @@ func createTables(adapter qgen.Adapter) (err error) { tC{"target", "int", 0, false, false, ""}, }, nil, ) - createTable("users_blocks", "", "", - []tC{ - tC{"blocker", "int", 0, false, false, ""}, - tC{"blockedUser", "int", 0, false, false, ""}, - }, nil, - ) */ + createTable("users_blocks", "", "", + []tC{ + tC{"blocker", "int", 0, false, false, ""}, + tC{"blockedUser", "int", 0, false, false, ""}, + }, nil, + ) + createTable("activity_stream_matches", "", "", []tC{ tC{"watcher", "int", 0, false, false, ""}, // TODO: Make this a foreign key diff --git a/common/pages.go b/common/pages.go index f5be8801..00d56058 100644 --- a/common/pages.go +++ b/common/pages.go @@ -52,7 +52,7 @@ type Header struct { func (h *Header) AddScript(name string) { if name[0] == '/' && name[1] == '/' { - } else { + } else { // TODO: Use a secondary static file map to avoid this concatenation? file, ok := StaticFiles.Get("/s/" + name) if ok { @@ -65,7 +65,7 @@ func (h *Header) AddScript(name string) { func (h *Header) AddPreScriptAsync(name string) { if name[0] == '/' && name[1] == '/' { - } else { + } else { file, ok := StaticFiles.Get("/s/" + name) if ok { name = file.OName @@ -76,7 +76,7 @@ func (h *Header) AddPreScriptAsync(name string) { func (h *Header) AddScriptAsync(name string) { if name[0] == '/' && name[1] == '/' { - } else { + } else { file, ok := StaticFiles.Get("/s/" + name) if ok { name = file.OName @@ -207,6 +207,7 @@ type ProfilePage struct { ProfileOwner User CurrentScore int NextScore int + Blocked bool } type CreateTopicPage struct { @@ -275,10 +276,10 @@ type ConvoListPage struct { type ConvoViewRow struct { *ConversationPost - User *User - ClassName string + User *User + ClassName string ContentLines int - + CanModify bool } @@ -582,15 +583,15 @@ type PanelEditGroupPermsPage struct { type GroupPromotionExtend struct { *GroupPromotion FromGroup *Group - ToGroup *Group + ToGroup *Group } type PanelEditGroupPromotionsPage struct { *BasePanelPage - ID int - Name string + ID int + Name string Promotions []*GroupPromotionExtend - Groups []*Group + Groups []*Group } type BackupItem struct { @@ -607,9 +608,9 @@ type PanelBackupPage struct { } type PageLogItem struct { - Action template.HTML - IP string - DoneAt string + Action template.HTML + IP string + DoneAt string } type PanelLogsPage struct { @@ -630,8 +631,8 @@ type PanelRegLogsPage struct { } type DebugPageCache struct { - Topics int - Users int + Topics int + Users int Replies int TCap int @@ -642,37 +643,37 @@ type DebugPageCache struct { } type DebugPageDatabase struct { - Topics int - Users int - Replies int + Topics int + Users int + Replies int ProfileReplies int ActivityStream int - Likes int - Attachments int - Polls int + Likes int + Attachments int + Polls int LoginLogs int - RegLogs int - ModLogs int + RegLogs int + ModLogs int AdminLogs int - Views int - ViewsAgents int - ViewsForums int - ViewsLangs int + Views int + ViewsAgents int + ViewsForums int + ViewsLangs int ViewsReferrers int - ViewsSystems int - PostChunks int - TopicChunks int + ViewsSystems int + PostChunks int + TopicChunks int } type DebugPageDisk struct { - Static int + Static int Attachments int - Avatars int - Logs int - Backups int - Git int + Avatars int + Logs int + Backups int + Git int } type PanelDebugPage struct { @@ -688,9 +689,9 @@ type PanelDebugPage struct { CPUs int MemStats runtime.MemStats - Cache DebugPageCache + Cache DebugPageCache Database DebugPageDatabase - Disk DebugPageDisk + Disk DebugPageDisk } type PageSimple struct { diff --git a/common/relations.go b/common/relations.go index c770f66b..c1702165 100644 --- a/common/relations.go +++ b/common/relations.go @@ -6,20 +6,27 @@ import ( qgen "github.com/Azareal/Gosora/query_gen" ) +var UserBlocks BlockStore + +//var UserFriends FriendStore + type BlockStore interface { IsBlockedBy(blocker, blockee int) (bool, error) Add(blocker, blockee int) error + Remove(blocker, blockee int) error } type DefaultBlockStore struct { isBlocked *sql.Stmt add *sql.Stmt + remove *sql.Stmt } func NewDefaultBlockStore(acc *qgen.Accumulator) (*DefaultBlockStore, error) { return &DefaultBlockStore{ isBlocked: acc.Select("users_blocks").Cols("blocker").Where("blocker = ? AND blockedUser = ?").Prepare(), add: acc.Insert("users_blocks").Columns("blocker,blockedUser").Fields("?,?").Prepare(), + remove: acc.Delete("users_blocks").Where("blocker = ? AND blockedUser = ?").Prepare(), }, acc.FirstError() } @@ -36,6 +43,11 @@ func (s *DefaultBlockStore) Add(blocker, blockee int) error { return err } +func (s *DefaultBlockStore) Remove(blocker, blockee int) error { + _, err := s.remove.Exec(blocker, blockee) + return err +} + type FriendInvite struct { Requester int Target int @@ -57,10 +69,10 @@ type DefaultFriendStore struct { func NewDefaultFriendStore(acc *qgen.Accumulator) (*DefaultFriendStore, error) { return &DefaultFriendStore{ - addInvite: acc.Insert("users_friends_invites").Columns("requester, target").Fields("?,?").Prepare(), + addInvite: acc.Insert("users_friends_invites").Columns("requester,target").Fields("?,?").Prepare(), confirm: acc.Insert("users_friends").Columns("uid,uid2").Fields("?,?").Prepare(), - getOwnSentInvites: acc.Select("users_friends_invites").Cols("requester, target").Where("requester = ?").Prepare(), - getOwnRecvInvites: acc.Select("users_friends_invites").Cols("requester, target").Where("target = ?").Prepare(), + getOwnSentInvites: acc.Select("users_friends_invites").Cols("requester,target").Where("requester = ?").Prepare(), + getOwnRecvInvites: acc.Select("users_friends_invites").Cols("requester,target").Where("target = ?").Prepare(), }, acc.FirstError() } diff --git a/common/template_init.go b/common/template_init.go index ae2568ed..136c13e9 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -147,12 +147,12 @@ type TItem struct { type TItemHold map[string]TItem -func (hold TItemHold) Add(name string, expects string, expectsInt interface{}) { - hold[name] = TItem{expects, expectsInt, true} +func (h TItemHold) Add(name string, expects string, expectsInt interface{}) { + h[name] = TItem{expects, expectsInt, true} } -func (hold TItemHold) AddStd(name string, expects string, expectsInt interface{}) { - hold[name] = TItem{expects, expectsInt, false} +func (h TItemHold) AddStd(name string, expects string, expectsInt interface{}) { + h[name] = TItem{expects, expectsInt, false} } // ? - Add template hooks? @@ -169,11 +169,11 @@ func CompileTemplates() error { } log.Printf("overriden: %+v\n", overriden) - var config tmpl.CTemplateConfig - config.Minify = Config.MinifyTemplates - config.Debug = Dev.DebugMode - config.SuperDebug = Dev.TemplateDebug - + config := tmpl.CTemplateConfig{ + Minify: Config.MinifyTemplates, + Debug: Dev.DebugMode, + SuperDebug: Dev.TemplateDebug, + } c := tmpl.NewCTemplateSet("normal") c.SetConfig(config) c.SetBaseImportMap(map[string]string{ @@ -296,7 +296,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string return err } - ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0} // TODO: Use the score from user to generate the currentScore and nextScore + ppage := ProfilePage{htitle("User 526"), replyList, user, 0, 0, false} // TODO: Use the score from user to generate the currentScore and nextScore t.Add("profile", "c.ProfilePage", ppage) var topicsList []*TopicsRow diff --git a/gen_router.go b/gen_router.go index bbc84904..f3ce2e99 100644 --- a/gen_router.go +++ b/gen_router.go @@ -135,6 +135,10 @@ var RouteMap = map[string]interface{}{ "routes.ConvosCreateReplySubmit": routes.ConvosCreateReplySubmit, "routes.ConvosDeleteReplySubmit": routes.ConvosDeleteReplySubmit, "routes.ConvosEditReplySubmit": routes.ConvosEditReplySubmit, + "routes.RelationsBlockCreate": routes.RelationsBlockCreate, + "routes.RelationsBlockCreateSubmit": routes.RelationsBlockCreateSubmit, + "routes.RelationsBlockRemove": routes.RelationsBlockRemove, + "routes.RelationsBlockRemoveSubmit": routes.RelationsBlockRemoveSubmit, "routes.ViewProfile": routes.ViewProfile, "routes.BanUserSubmit": routes.BanUserSubmit, "routes.UnbanUser": routes.UnbanUser, @@ -298,53 +302,57 @@ var routeMapEnum = map[string]int{ "routes.ConvosCreateReplySubmit": 109, "routes.ConvosDeleteReplySubmit": 110, "routes.ConvosEditReplySubmit": 111, - "routes.ViewProfile": 112, - "routes.BanUserSubmit": 113, - "routes.UnbanUser": 114, - "routes.ActivateUser": 115, - "routes.IPSearch": 116, - "routes.CreateTopicSubmit": 117, - "routes.EditTopicSubmit": 118, - "routes.DeleteTopicSubmit": 119, - "routes.StickTopicSubmit": 120, - "routes.UnstickTopicSubmit": 121, - "routes.LockTopicSubmit": 122, - "routes.UnlockTopicSubmit": 123, - "routes.MoveTopicSubmit": 124, - "routes.LikeTopicSubmit": 125, - "routes.AddAttachToTopicSubmit": 126, - "routes.RemoveAttachFromTopicSubmit": 127, - "routes.ViewTopic": 128, - "routes.CreateReplySubmit": 129, - "routes.ReplyEditSubmit": 130, - "routes.ReplyDeleteSubmit": 131, - "routes.ReplyLikeSubmit": 132, - "routes.AddAttachToReplySubmit": 133, - "routes.RemoveAttachFromReplySubmit": 134, - "routes.ProfileReplyCreateSubmit": 135, - "routes.ProfileReplyEditSubmit": 136, - "routes.ProfileReplyDeleteSubmit": 137, - "routes.PollVote": 138, - "routes.PollResults": 139, - "routes.AccountLogin": 140, - "routes.AccountRegister": 141, - "routes.AccountLogout": 142, - "routes.AccountLoginSubmit": 143, - "routes.AccountLoginMFAVerify": 144, - "routes.AccountLoginMFAVerifySubmit": 145, - "routes.AccountRegisterSubmit": 146, - "routes.AccountPasswordReset": 147, - "routes.AccountPasswordResetSubmit": 148, - "routes.AccountPasswordResetToken": 149, - "routes.AccountPasswordResetTokenSubmit": 150, - "routes.DynamicRoute": 151, - "routes.UploadedFile": 152, - "routes.StaticFile": 153, - "routes.RobotsTxt": 154, - "routes.SitemapXml": 155, - "routes.OpenSearchXml": 156, - "routes.BadRoute": 157, - "routes.HTTPSRedirect": 158, + "routes.RelationsBlockCreate": 112, + "routes.RelationsBlockCreateSubmit": 113, + "routes.RelationsBlockRemove": 114, + "routes.RelationsBlockRemoveSubmit": 115, + "routes.ViewProfile": 116, + "routes.BanUserSubmit": 117, + "routes.UnbanUser": 118, + "routes.ActivateUser": 119, + "routes.IPSearch": 120, + "routes.CreateTopicSubmit": 121, + "routes.EditTopicSubmit": 122, + "routes.DeleteTopicSubmit": 123, + "routes.StickTopicSubmit": 124, + "routes.UnstickTopicSubmit": 125, + "routes.LockTopicSubmit": 126, + "routes.UnlockTopicSubmit": 127, + "routes.MoveTopicSubmit": 128, + "routes.LikeTopicSubmit": 129, + "routes.AddAttachToTopicSubmit": 130, + "routes.RemoveAttachFromTopicSubmit": 131, + "routes.ViewTopic": 132, + "routes.CreateReplySubmit": 133, + "routes.ReplyEditSubmit": 134, + "routes.ReplyDeleteSubmit": 135, + "routes.ReplyLikeSubmit": 136, + "routes.AddAttachToReplySubmit": 137, + "routes.RemoveAttachFromReplySubmit": 138, + "routes.ProfileReplyCreateSubmit": 139, + "routes.ProfileReplyEditSubmit": 140, + "routes.ProfileReplyDeleteSubmit": 141, + "routes.PollVote": 142, + "routes.PollResults": 143, + "routes.AccountLogin": 144, + "routes.AccountRegister": 145, + "routes.AccountLogout": 146, + "routes.AccountLoginSubmit": 147, + "routes.AccountLoginMFAVerify": 148, + "routes.AccountLoginMFAVerifySubmit": 149, + "routes.AccountRegisterSubmit": 150, + "routes.AccountPasswordReset": 151, + "routes.AccountPasswordResetSubmit": 152, + "routes.AccountPasswordResetToken": 153, + "routes.AccountPasswordResetTokenSubmit": 154, + "routes.DynamicRoute": 155, + "routes.UploadedFile": 156, + "routes.StaticFile": 157, + "routes.RobotsTxt": 158, + "routes.SitemapXml": 159, + "routes.OpenSearchXml": 160, + "routes.BadRoute": 161, + "routes.HTTPSRedirect": 162, } var reverseRouteMapEnum = map[int]string{ 0: "routes.Overview", @@ -459,53 +467,57 @@ var reverseRouteMapEnum = map[int]string{ 109: "routes.ConvosCreateReplySubmit", 110: "routes.ConvosDeleteReplySubmit", 111: "routes.ConvosEditReplySubmit", - 112: "routes.ViewProfile", - 113: "routes.BanUserSubmit", - 114: "routes.UnbanUser", - 115: "routes.ActivateUser", - 116: "routes.IPSearch", - 117: "routes.CreateTopicSubmit", - 118: "routes.EditTopicSubmit", - 119: "routes.DeleteTopicSubmit", - 120: "routes.StickTopicSubmit", - 121: "routes.UnstickTopicSubmit", - 122: "routes.LockTopicSubmit", - 123: "routes.UnlockTopicSubmit", - 124: "routes.MoveTopicSubmit", - 125: "routes.LikeTopicSubmit", - 126: "routes.AddAttachToTopicSubmit", - 127: "routes.RemoveAttachFromTopicSubmit", - 128: "routes.ViewTopic", - 129: "routes.CreateReplySubmit", - 130: "routes.ReplyEditSubmit", - 131: "routes.ReplyDeleteSubmit", - 132: "routes.ReplyLikeSubmit", - 133: "routes.AddAttachToReplySubmit", - 134: "routes.RemoveAttachFromReplySubmit", - 135: "routes.ProfileReplyCreateSubmit", - 136: "routes.ProfileReplyEditSubmit", - 137: "routes.ProfileReplyDeleteSubmit", - 138: "routes.PollVote", - 139: "routes.PollResults", - 140: "routes.AccountLogin", - 141: "routes.AccountRegister", - 142: "routes.AccountLogout", - 143: "routes.AccountLoginSubmit", - 144: "routes.AccountLoginMFAVerify", - 145: "routes.AccountLoginMFAVerifySubmit", - 146: "routes.AccountRegisterSubmit", - 147: "routes.AccountPasswordReset", - 148: "routes.AccountPasswordResetSubmit", - 149: "routes.AccountPasswordResetToken", - 150: "routes.AccountPasswordResetTokenSubmit", - 151: "routes.DynamicRoute", - 152: "routes.UploadedFile", - 153: "routes.StaticFile", - 154: "routes.RobotsTxt", - 155: "routes.SitemapXml", - 156: "routes.OpenSearchXml", - 157: "routes.BadRoute", - 158: "routes.HTTPSRedirect", + 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", } var osMapEnum = map[string]int{ "unknown": 0, @@ -663,7 +675,7 @@ type HTTPSRedirect struct {} func (red *HTTPSRedirect) ServeHTTP(w http.ResponseWriter, req *http.Request) { w.Header().Set("Connection", "close") - counters.RouteViewCounter.Bump(158) + counters.RouteViewCounter.Bump(162) dest := "https://" + req.Host + req.URL.String() http.Redirect(w, req, dest, http.StatusTemporaryRedirect) } @@ -872,7 +884,7 @@ func (r *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) { counters.GlobalViewCounter.Bump() if prefix == "/s" { //old prefix: /static - counters.RouteViewCounter.Bump(153) + counters.RouteViewCounter.Bump(157) req.URL.Path += extraData routes.StaticFile(w, req) return @@ -1957,9 +1969,59 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c counters.RouteViewCounter.Bump(111) err = routes.ConvosEditReplySubmit(w,req,user,extraData) + case "/user/block/create/": + err = c.MemberOnly(w,req,user) + if err != nil { + return err + } + + counters.RouteViewCounter.Bump(112) + head, err := c.UserCheck(w,req,&user) + if err != nil { + return err + } + err = routes.RelationsBlockCreate(w,req,user,head,extraData) + case "/user/block/create/submit/": + err = c.NoSessionMismatch(w,req,user) + if err != nil { + return err + } + + err = c.MemberOnly(w,req,user) + if err != nil { + return err + } + + counters.RouteViewCounter.Bump(113) + err = routes.RelationsBlockCreateSubmit(w,req,user,extraData) + case "/user/block/remove/": + err = c.MemberOnly(w,req,user) + if err != nil { + return err + } + + counters.RouteViewCounter.Bump(114) + head, err := c.UserCheck(w,req,&user) + if err != nil { + return err + } + err = routes.RelationsBlockRemove(w,req,user,head,extraData) + case "/user/block/remove/submit/": + err = c.NoSessionMismatch(w,req,user) + if err != nil { + return err + } + + err = c.MemberOnly(w,req,user) + if err != nil { + return err + } + + counters.RouteViewCounter.Bump(115) + err = routes.RelationsBlockRemoveSubmit(w,req,user,extraData) default: req.URL.Path += extraData - counters.RouteViewCounter.Bump(112) + counters.RouteViewCounter.Bump(116) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -1979,7 +2041,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(113) + counters.RouteViewCounter.Bump(117) err = routes.BanUserSubmit(w,req,user,extraData) case "/users/unban/": err = c.NoSessionMismatch(w,req,user) @@ -1992,7 +2054,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(114) + counters.RouteViewCounter.Bump(118) err = routes.UnbanUser(w,req,user,extraData) case "/users/activate/": err = c.NoSessionMismatch(w,req,user) @@ -2005,7 +2067,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(115) + counters.RouteViewCounter.Bump(119) err = routes.ActivateUser(w,req,user,extraData) case "/users/ips/": err = c.MemberOnly(w,req,user) @@ -2013,7 +2075,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(116) + counters.RouteViewCounter.Bump(120) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2037,7 +2099,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(117) + counters.RouteViewCounter.Bump(121) err = routes.CreateTopicSubmit(w,req,user) case "/topic/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2050,7 +2112,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(118) + counters.RouteViewCounter.Bump(122) err = routes.EditTopicSubmit(w,req,user,extraData) case "/topic/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2064,7 +2126,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c } req.URL.Path += extraData - counters.RouteViewCounter.Bump(119) + counters.RouteViewCounter.Bump(123) err = routes.DeleteTopicSubmit(w,req,user) case "/topic/stick/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2077,7 +2139,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(120) + counters.RouteViewCounter.Bump(124) err = routes.StickTopicSubmit(w,req,user,extraData) case "/topic/unstick/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2090,7 +2152,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(121) + counters.RouteViewCounter.Bump(125) err = routes.UnstickTopicSubmit(w,req,user,extraData) case "/topic/lock/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2104,7 +2166,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c } req.URL.Path += extraData - counters.RouteViewCounter.Bump(122) + counters.RouteViewCounter.Bump(126) err = routes.LockTopicSubmit(w,req,user) case "/topic/unlock/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2117,7 +2179,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(123) + counters.RouteViewCounter.Bump(127) err = routes.UnlockTopicSubmit(w,req,user,extraData) case "/topic/move/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2130,7 +2192,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(124) + counters.RouteViewCounter.Bump(128) err = routes.MoveTopicSubmit(w,req,user,extraData) case "/topic/like/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2143,7 +2205,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(125) + counters.RouteViewCounter.Bump(129) err = routes.LikeTopicSubmit(w,req,user,extraData) case "/topic/attach/add/submit/": err = c.MemberOnly(w,req,user) @@ -2160,7 +2222,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(126) + counters.RouteViewCounter.Bump(130) err = routes.AddAttachToTopicSubmit(w,req,user,extraData) case "/topic/attach/remove/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2173,10 +2235,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(127) + counters.RouteViewCounter.Bump(131) err = routes.RemoveAttachFromTopicSubmit(w,req,user,extraData) default: - counters.RouteViewCounter.Bump(128) + counters.RouteViewCounter.Bump(132) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2200,7 +2262,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(129) + counters.RouteViewCounter.Bump(133) err = routes.CreateReplySubmit(w,req,user) case "/reply/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2213,7 +2275,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(130) + counters.RouteViewCounter.Bump(134) err = routes.ReplyEditSubmit(w,req,user,extraData) case "/reply/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2226,7 +2288,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(131) + counters.RouteViewCounter.Bump(135) err = routes.ReplyDeleteSubmit(w,req,user,extraData) case "/reply/like/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2239,7 +2301,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(132) + counters.RouteViewCounter.Bump(136) err = routes.ReplyLikeSubmit(w,req,user,extraData) case "/reply/attach/add/submit/": err = c.MemberOnly(w,req,user) @@ -2256,7 +2318,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(133) + counters.RouteViewCounter.Bump(137) err = routes.AddAttachToReplySubmit(w,req,user,extraData) case "/reply/attach/remove/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2269,7 +2331,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(134) + counters.RouteViewCounter.Bump(138) err = routes.RemoveAttachFromReplySubmit(w,req,user,extraData) } case "/profile": @@ -2285,7 +2347,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(135) + counters.RouteViewCounter.Bump(139) err = routes.ProfileReplyCreateSubmit(w,req,user) case "/profile/reply/edit/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2298,7 +2360,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(136) + counters.RouteViewCounter.Bump(140) err = routes.ProfileReplyEditSubmit(w,req,user,extraData) case "/profile/reply/delete/submit/": err = c.NoSessionMismatch(w,req,user) @@ -2311,7 +2373,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(137) + counters.RouteViewCounter.Bump(141) err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData) } case "/poll": @@ -2327,23 +2389,23 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(138) + counters.RouteViewCounter.Bump(142) err = routes.PollVote(w,req,user,extraData) case "/poll/results/": - counters.RouteViewCounter.Bump(139) + counters.RouteViewCounter.Bump(143) err = routes.PollResults(w,req,user,extraData) } case "/accounts": switch(req.URL.Path) { case "/accounts/login/": - counters.RouteViewCounter.Bump(140) + counters.RouteViewCounter.Bump(144) head, err := c.UserCheck(w,req,&user) if err != nil { return err } err = routes.AccountLogin(w,req,user,head) case "/accounts/create/": - counters.RouteViewCounter.Bump(141) + counters.RouteViewCounter.Bump(145) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2360,7 +2422,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(142) + counters.RouteViewCounter.Bump(146) err = routes.AccountLogout(w,req,user) case "/accounts/login/submit/": err = c.ParseForm(w,req,user) @@ -2368,10 +2430,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(143) + counters.RouteViewCounter.Bump(147) err = routes.AccountLoginSubmit(w,req,user) case "/accounts/mfa_verify/": - counters.RouteViewCounter.Bump(144) + counters.RouteViewCounter.Bump(148) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2383,7 +2445,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(145) + counters.RouteViewCounter.Bump(149) err = routes.AccountLoginMFAVerifySubmit(w,req,user) case "/accounts/create/submit/": err = c.ParseForm(w,req,user) @@ -2391,10 +2453,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(146) + counters.RouteViewCounter.Bump(150) err = routes.AccountRegisterSubmit(w,req,user) case "/accounts/password-reset/": - counters.RouteViewCounter.Bump(147) + counters.RouteViewCounter.Bump(151) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2406,10 +2468,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(148) + counters.RouteViewCounter.Bump(152) err = routes.AccountPasswordResetSubmit(w,req,user) case "/accounts/password-reset/token/": - counters.RouteViewCounter.Bump(149) + counters.RouteViewCounter.Bump(153) head, err := c.UserCheck(w,req,&user) if err != nil { return err @@ -2421,7 +2483,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c return err } - counters.RouteViewCounter.Bump(150) + counters.RouteViewCounter.Bump(154) err = routes.AccountPasswordResetTokenSubmit(w,req,user) } /*case "/sitemaps": // TODO: Count these views @@ -2438,7 +2500,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c h.Del("Content-Type") h.Del("Content-Encoding") } - counters.RouteViewCounter.Bump(152) + counters.RouteViewCounter.Bump(156) req.URL.Path += extraData // TODO: Find a way to propagate errors up from this? r.UploadHandler(w,req) // TODO: Count these views @@ -2448,7 +2510,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": - counters.RouteViewCounter.Bump(154) + counters.RouteViewCounter.Bump(158) return routes.RobotsTxt(w,req) case "favicon.ico": gzw, ok := w.(c.GzipResponseWriter) @@ -2462,10 +2524,10 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c routes.StaticFile(w,req) return nil case "opensearch.xml": - counters.RouteViewCounter.Bump(156) + counters.RouteViewCounter.Bump(160) return routes.OpenSearchXml(w,req) /*case "sitemap.xml": - counters.RouteViewCounter.Bump(155) + counters.RouteViewCounter.Bump(159) return routes.SitemapXml(w,req)*/ } return c.NotFound(w,req,nil) @@ -2476,7 +2538,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c r.RUnlock() if ok { - counters.RouteViewCounter.Bump(151) // TODO: Be more specific about *which* dynamic route it is + counters.RouteViewCounter.Bump(155) // TODO: Be more specific about *which* dynamic route it is req.URL.Path += extraData return handle(w,req,user) } @@ -2487,7 +2549,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c } else { r.DumpRequest(req,"Bad Route") } - counters.RouteViewCounter.Bump(157) + counters.RouteViewCounter.Bump(161) return c.NotFound(w,req,nil) } return err diff --git a/langs/english.json b/langs/english.json index 1f310c3a..939a9f0e 100644 --- a/langs/english.json +++ b/langs/english.json @@ -144,6 +144,8 @@ "account_level_list":"Level Progress", "convos":"Conversations", "convo":"Conversation", + "create_block":"Block User", + "remove_block":"Unblock User", "panel_dashboard":"Control Panel Dashboard", "panel_forums":"Forum Manager", @@ -544,6 +546,9 @@ "create_convo_recp":"Recipient/s", "create_convo_button":"Create Convo", + "create_block_msg":"Are you sure you want to block this user?", + "remove_block_msg":"Are you sure you want to unblock this user?", + "areyousure_head":"Are you sure?", "areyousure_continue":"Continue", @@ -700,6 +705,7 @@ "profile_unban":"Unban", "profile_ban":"Ban", "profile_block":"Block", + "profile_unblock":"Unblock", "profile_report_user_tooltip":"Report User", "profile_report_user_aria":"Report User", "profile_ban_user_head":"Ban User", diff --git a/main.go b/main.go index df22f294..910b0b10 100644 --- a/main.go +++ b/main.go @@ -49,8 +49,7 @@ func init() { } func afterDBInit() (err error) { - err = storeInit() - if err != nil { + if err := storeInit(); err != nil { return err } log.Print("Exitted storeInit") @@ -139,6 +138,10 @@ func storeInit() (err error) { if err != nil { return errors.WithStack(err) } + c.UserBlocks, err = c.NewDefaultBlockStore(acc) + if err != nil { + return errors.WithStack(err) + } c.GroupPromotions, err = c.NewDefaultGroupPromotionStore(acc) if err != nil { return errors.WithStack(err) diff --git a/patcher/patches.go b/patcher/patches.go index 9c0366d0..723f1c76 100644 --- a/patcher/patches.go +++ b/patcher/patches.go @@ -5,7 +5,7 @@ import ( "database/sql" "strconv" - "github.com/Azareal/Gosora/query_gen" + qgen "github.com/Azareal/Gosora/query_gen" ) type tblColumn = qgen.DBTableColumn @@ -39,6 +39,7 @@ func init() { addPatch(23, patch23) addPatch(24, patch24) addPatch(25, patch25) + addPatch(26, patch26) } func patch0(scanner *bufio.Scanner) (err error) { @@ -56,7 +57,7 @@ func patch0(scanner *bufio.Scanner) (err error) { tC{"mid", "int", 0, false, true, ""}, }, []tblKey{ - tblKey{"mid", "primary","",false}, + tblKey{"mid", "primary", "", false}, }, )) if err != nil { @@ -83,7 +84,7 @@ func patch0(scanner *bufio.Scanner) (err error) { tC{"adminOnly", "boolean", 0, false, false, "0"}, }, []tblKey{ - tblKey{"miid", "primary","",false}, + tblKey{"miid", "primary", "", false}, }, )) if err != nil { @@ -96,8 +97,8 @@ func patch0(scanner *bufio.Scanner) (err error) { } var order int - var mOrder = "mid, name, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly" - var addMenuItem = func(data map[string]interface{}) error { + mOrder := "mid, name, htmlID, cssClass, position, path, aria, tooltip, guestOnly, memberOnly, staffOnly, adminOnly" + addMenuItem := func(data map[string]interface{}) error { cols, values := qgen.InterfaceMapToInsertStrings(data, mOrder) err := execStmt(qgen.Builder.SimpleInsert("menu_items", cols+", order", values+","+strconv.Itoa(order))) order++ @@ -153,7 +154,7 @@ func patch0(scanner *bufio.Scanner) (err error) { } func patch1(scanner *bufio.Scanner) error { - var routes = map[string]string{ + routes := map[string]string{ "routeAccountEditCriticalSubmit": "routes.AccountEditCriticalSubmit", "routeAccountEditAvatar": "routes.AccountEditAvatar", "routeAccountEditAvatarSubmit": "routes.AccountEditAvatarSubmit", @@ -164,7 +165,7 @@ func patch1(scanner *bufio.Scanner) error { } func patch2(scanner *bufio.Scanner) error { - var routes = map[string]string{ + routes := map[string]string{ "routeLogout": "routes.AccountLogout", "routeShowAttachment": "routes.ShowAttachment", "routeChangeTheme": "routes.ChangeTheme", @@ -190,13 +191,13 @@ func patch3(scanner *bufio.Scanner) error { tC{"doneAt", "createdAt", 0, false, false, ""}, }, []tblKey{ - tblKey{"rlid", "primary","",false}, + tblKey{"rlid", "primary", "", false}, }, )) } func patch4(scanner *bufio.Scanner) error { - var routes = map[string]string{ + routes := map[string]string{ "routeReportSubmit": "routes.ReportSubmit", "routeAccountEditEmail": "routes.AccountEditEmail", "routeAccountEditEmailTokenSubmit": "routes.AccountEditEmailTokenSubmit", @@ -253,7 +254,7 @@ func patch4(scanner *bufio.Scanner) error { tC{"menuID", "int", 0, false, false, "-1"}, }, []tblKey{ - tblKey{"pid", "primary","",false}, + tblKey{"pid", "primary", "", false}, }, )) if err != nil { @@ -264,7 +265,7 @@ func patch4(scanner *bufio.Scanner) error { } func patch5(scanner *bufio.Scanner) error { - var routes = map[string]string{ + routes := map[string]string{ "routePanelUsers": "panel.Users", "routePanelUsersEdit": "panel.UsersEdit", "routePanelUsersEditSubmit": "panel.UsersEditSubmit", @@ -296,7 +297,7 @@ func patch5(scanner *bufio.Scanner) error { tC{"createdAt", "createdAt", 0, false, false, ""}, }, []tblKey{ - tblKey{"uid", "primary","",false}, + tblKey{"uid", "primary", "", false}, }, )) if err != nil { @@ -316,14 +317,14 @@ func patch7(scanner *bufio.Scanner) error { tC{"uid", "int", 0, false, false, ""}, // TODO: Make this a foreign key }, []tblKey{ - tblKey{"uid", "primary","",false}, + tblKey{"uid", "primary", "", false}, }, )) } func renameRoutes(routes map[string]string) error { // ! Don't reuse this function blindly, it doesn't escape apostrophes - var replaceTextWhere = func(replaceThis string, withThis string) error { + replaceTextWhere := func(replaceThis string, withThis string) error { return execStmt(qgen.Builder.SimpleUpdate("viewchunks", "route = '"+withThis+"'", "route = '"+replaceThis+"'")) } @@ -338,7 +339,7 @@ func renameRoutes(routes map[string]string) error { } func patch8(scanner *bufio.Scanner) error { - var routes = map[string]string{ + routes := map[string]string{ "routePanelWordFilter": "panel.WordFilters", "routePanelWordFiltersCreateSubmit": "panel.WordFiltersCreateSubmit", "routePanelWordFiltersEdit": "panel.WordFiltersEdit", @@ -398,7 +399,7 @@ func patch9(scanner *bufio.Scanner) error { tC{"doneAt", "createdAt", 0, false, false, ""}, }, []tblKey{ - tblKey{"lid", "primary","",false}, + tblKey{"lid", "primary", "", false}, }, )) } @@ -418,13 +419,12 @@ func patch10(scanner *bufio.Scanner) error { err = acc().Select("topics").Cols("tid").EachInt(func(tid int) error { stid := itoa(tid) - count, err := acc().Count("attachments").Where("originTable = 'topics' and originID = " + stid).Total() if err != nil { return err } - var hasReply = false + hasReply := false err = acc().Select("replies").Cols("rid").Where("tid = " + stid).Orderby("rid DESC").Limit("1").EachInt(func(rid int) error { hasReply = true _, err := acc().Update("topics").Set("lastReplyID = ?, attachCount = ?").Where("tid = "+stid).Exec(rid, count) @@ -461,7 +461,6 @@ func patch11(scanner *bufio.Scanner) error { // We could probably do something more efficient, but as there shouldn't be too many sites right now, we can probably cheat a little, otherwise it'll take forever to get things done return acc().Select("topics").Cols("tid").EachInt(func(tid int) error { stid := itoa(tid) - count, err := acc().Count("attachments").Where("originTable = 'topics' and originID = " + stid).Total() if err != nil { return err @@ -473,7 +472,6 @@ func patch11(scanner *bufio.Scanner) error { /*return acc().Select("replies").Cols("rid").EachInt(func(rid int) error { srid := itoa(rid) - count, err := acc().Count("attachments").Where("originTable = 'replies' and originID = " + srid).Total() if err != nil { return err @@ -521,7 +519,7 @@ func patch12(scanner *bufio.Scanner) error { } func patch13(scanner *bufio.Scanner) error { - err := execStmt(qgen.Builder.AddColumn("widgets", tC{"wid", "int", 0, false, true, ""}, &tblKey{"wid", "primary","",false})) + err := execStmt(qgen.Builder.AddColumn("widgets", tC{"wid", "int", 0, false, true, ""}, &tblKey{"wid", "primary", "", false})) if err != nil { return err } @@ -530,15 +528,15 @@ func patch13(scanner *bufio.Scanner) error { } func patch14(scanner *bufio.Scanner) error { - err := execStmt(qgen.Builder.AddKey("topics", "title", tblKey{"title", "fulltext","",false})) + err := execStmt(qgen.Builder.AddKey("topics", "title", tblKey{"title", "fulltext", "", false})) if err != nil { return err } - err = execStmt(qgen.Builder.AddKey("topics", "content", tblKey{"content", "fulltext","",false})) + err = execStmt(qgen.Builder.AddKey("topics", "content", tblKey{"content", "fulltext", "", false})) if err != nil { return err } - err = execStmt(qgen.Builder.AddKey("replies", "content", tblKey{"content", "fulltext","",false})) + err = execStmt(qgen.Builder.AddKey("replies", "content", tblKey{"content", "fulltext", "", false})) if err != nil { return err } @@ -630,8 +628,8 @@ func patch20(scanner *bufio.Scanner) error { if err != nil { return err } - - return execStmt(qgen.Builder.AddForeignKey("activity_stream_matches", "asid","activity_stream","asid",true)) + + return execStmt(qgen.Builder.AddForeignKey("activity_stream_matches", "asid", "activity_stream", "asid", true)) } func patch21(scanner *bufio.Scanner) error { @@ -639,12 +637,12 @@ func patch21(scanner *bufio.Scanner) error { if err != nil { return err } - + err = execStmt(qgen.Builder.AddColumn("memchunks", tC{"heap", "int", 0, false, false, "0"}, nil)) if err != nil { return err } - + err = execStmt(qgen.Builder.CreateTable("meta", "", "", []tC{ tC{"name", "varchar", 200, false, false, ""}, @@ -676,7 +674,7 @@ func patch23(scanner *bufio.Scanner) error { tC{"lastReplyBy", "int", 0, false, false, ""}, }, []tblKey{ - tblKey{"cid", "primary","",false}, + tblKey{"cid", "primary", "", false}, }, )) if err != nil { @@ -696,7 +694,7 @@ func patch23(scanner *bufio.Scanner) error { tC{"post", "varchar", 50, false, false, "''"}, }, []tblKey{ - tblKey{"pid", "primary","",false}, + tblKey{"pid", "primary", "", false}, }, )) if err != nil { @@ -725,18 +723,27 @@ func patch24(scanner *bufio.Scanner) error { tC{"pid", "int", 0, false, true, ""}, tC{"from_gid", "int", 0, false, false, ""}, tC{"to_gid", "int", 0, false, false, ""}, - tC{"two_way", "boolean",0,false,false,"0"}, // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set + tC{"two_way", "boolean", 0, false, false, "0"}, // If a user no longer meets the requirements for this promotion then they will be demoted if this flag is set // Requirements tC{"level", "int", 0, false, false, ""}, tC{"minTime", "int", 0, false, false, ""}, // How long someone needs to have been in their current group before being promoted }, []tblKey{ - tblKey{"pid", "primary","",false}, + tblKey{"pid", "primary", "", false}, }, )) } func patch25(scanner *bufio.Scanner) error { return execStmt(qgen.Builder.AddColumn("users_groups_promotions", tC{"posts", "int", 0, false, false, "0"}, nil)) -} \ No newline at end of file +} + +func patch26(scanner *bufio.Scanner) error { + return execStmt(qgen.Builder.CreateTable("users_blocks", "", "", + []tC{ + tC{"blocker", "int", 0, false, false, ""}, + tC{"blockedUser", "int", 0, false, false, ""}, + }, nil, + )) +} diff --git a/router_gen/routes.go b/router_gen/routes.go index 31f9c5ac..cabdee59 100644 --- a/router_gen/routes.go +++ b/router_gen/routes.go @@ -92,8 +92,10 @@ func userRoutes() *RouteGroup { Action("routes.ConvosDeleteReplySubmit", "/user/convo/delete/submit/", "extraData"), Action("routes.ConvosEditReplySubmit", "/user/convo/edit/submit/", "extraData"), - //MView("routes.RelationsBlockCreate","/user/block/create/","extraData") - //Action("routes.RelationsBlockCreateSubmit","/user/block/create/submit/","extraData") + MView("routes.RelationsBlockCreate", "/user/block/create/", "extraData"), + Action("routes.RelationsBlockCreateSubmit", "/user/block/create/submit/", "extraData"), + MView("routes.RelationsBlockRemove", "/user/block/remove/", "extraData"), + Action("routes.RelationsBlockRemoveSubmit", "/user/block/remove/submit/", "extraData"), ) } diff --git a/routes/convos.go b/routes/convos.go index 207edc30..744ef7b8 100644 --- a/routes/convos.go +++ b/routes/convos.go @@ -134,6 +134,14 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R if !u.Perms.UseConvos { return c.LocalError("One of the recipients doesn't have permission to use the conversations system", w, r, user) } + blocked, err := c.UserBlocks.IsBlockedBy(u.ID, user.ID) + if err != nil { + return c.InternalError(err, w, r) + } + // Supermods can bypass blocks so they can tell people off when they do something stupid or have to convey important information + if blocked && !user.IsSuperMod { + return c.LocalError("You don't have permission to send messages to one of these users.", w, r, user) + } rlist = append(rlist, u.ID) } @@ -308,7 +316,7 @@ func ConvosEditReplySubmit(w http.ResponseWriter, r *http.Request, user c.User, } func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, spid string) c.RouteError { - accountEditHead("create_block", w, r, &user, h) + h.Title = p.GetTitlePhrase("create_block") pid, err := strconv.Atoi(spid) if err != nil { return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user) @@ -319,10 +327,69 @@ func RelationsBlockCreate(w http.ResponseWriter, r *http.Request, user c.User, h } else if err != nil { return c.InternalError(err, w, r) } - pi := c.Account{h, "dashboard", "create_block", puser} - return renderTemplate("account", w, r, h, pi) + + pi := c.Page{h, nil, c.AreYouSure{"/user/block/create/submit/" + strconv.Itoa(puser.ID), p.GetTmplPhrase("create_block_msg")}} + return renderTemplate("are_you_sure", w, r, h, pi) } -func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, spid string) c.RouteError { +func RelationsBlockCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { + pid, err := strconv.Atoi(spid) + if err != nil { + return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user) + } + puser, err := c.Users.Get(pid) + if err == sql.ErrNoRows { + return c.LocalError("The user you're trying to block doesn't exist.", w, r, user) + } else if err != nil { + return c.InternalError(err, w, r) + } + if user.ID == puser.ID { + return c.LocalError("You can't block yourself.", w, r, user) + } + + err = c.UserBlocks.Add(user.ID, puser.ID) + if err != nil { + return c.InternalError(err, w, r) + } + + http.Redirect(w, r, "/user/"+strconv.Itoa(puser.ID), http.StatusSeeOther) return nil -} \ No newline at end of file +} + +func RelationsBlockRemove(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, spid string) c.RouteError { + h.Title = p.GetTitlePhrase("remove_block") + pid, err := strconv.Atoi(spid) + if err != nil { + return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user) + } + puser, err := c.Users.Get(pid) + if err == sql.ErrNoRows { + return c.LocalError("The user you're trying to block doesn't exist.", w, r, user) + } else if err != nil { + return c.InternalError(err, w, r) + } + + pi := c.Page{h, nil, c.AreYouSure{"/user/block/remove/submit/" + strconv.Itoa(puser.ID), p.GetTmplPhrase("remove_block_msg")}} + return renderTemplate("are_you_sure", w, r, h, pi) +} + +func RelationsBlockRemoveSubmit(w http.ResponseWriter, r *http.Request, user c.User, spid string) c.RouteError { + pid, err := strconv.Atoi(spid) + if err != nil { + return c.LocalError(p.GetErrorPhrase("id_must_be_integer"), w, r, user) + } + puser, err := c.Users.Get(pid) + if err == sql.ErrNoRows { + return c.LocalError("The user you're trying to unblock doesn't exist.", w, r, user) + } else if err != nil { + return c.InternalError(err, w, r) + } + + err = c.UserBlocks.Remove(user.ID, puser.ID) + if err != nil { + return c.InternalError(err, w, r) + } + + http.Redirect(w, r, "/user/"+strconv.Itoa(puser.ID), http.StatusSeeOther) + return nil +} diff --git a/routes/profile.go b/routes/profile.go index 71a3b2f2..d476afe9 100644 --- a/routes/profile.go +++ b/routes/profile.go @@ -7,7 +7,7 @@ import ( c "github.com/Azareal/Gosora/common" "github.com/Azareal/Gosora/common/phrases" - "github.com/Azareal/Gosora/query_gen" + qgen "github.com/Azareal/Gosora/query_gen" ) type ProfileStmts struct { @@ -37,7 +37,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c. // TODO: Do a 301 if it's the wrong username? Do a canonical too? _, pid, err := ParseSEOURL(r.URL.Path[len("/user/"):]) if err != nil { - return c.SimpleError(phrases.GetErrorPhrase("url_id_must_be_integer"),w,r,header) + return c.SimpleError(phrases.GetErrorPhrase("url_id_must_be_integer"), w, r, header) } // TODO: Preload this? @@ -98,8 +98,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c. // TODO: Add a hook here replyList = append(replyList, ru) } - err = rows.Err() - if err != nil { + if err := rows.Err(); err != nil { return c.InternalError(err, w, r) } @@ -107,7 +106,11 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c. prevScore := c.GetLevelScore(puser.Level) currentScore := puser.Score - prevScore nextScore := c.GetLevelScore(puser.Level+1) - prevScore + blocked, err := c.UserBlocks.IsBlockedBy(user.ID, puser.ID) + if err != nil { + return c.InternalError(err, w, r) + } - ppage := c.ProfilePage{header, replyList, *puser, currentScore, nextScore} + ppage := c.ProfilePage{header, replyList, *puser, currentScore, nextScore, blocked} return renderTemplate("profile", w, r, header, ppage) } diff --git a/schema/mssql/query_users_blocks.sql b/schema/mssql/query_users_blocks.sql new file mode 100644 index 00000000..8a582a54 --- /dev/null +++ b/schema/mssql/query_users_blocks.sql @@ -0,0 +1,4 @@ +CREATE TABLE [users_blocks] ( + [blocker] int not null, + [blockedUser] int not null +); \ No newline at end of file diff --git a/schema/mysql/query_users_blocks.sql b/schema/mysql/query_users_blocks.sql new file mode 100644 index 00000000..eae7ba4d --- /dev/null +++ b/schema/mysql/query_users_blocks.sql @@ -0,0 +1,4 @@ +CREATE TABLE `users_blocks` ( + `blocker` int not null, + `blockedUser` int not null +); \ No newline at end of file diff --git a/schema/pgsql/query_users_blocks.sql b/schema/pgsql/query_users_blocks.sql new file mode 100644 index 00000000..290238ec --- /dev/null +++ b/schema/pgsql/query_users_blocks.sql @@ -0,0 +1,4 @@ +CREATE TABLE "users_blocks" ( + `blocker` int not null, + `blockedUser` int not null +); \ No newline at end of file diff --git a/templates/are_you_sure.html b/templates/are_you_sure.html index 99ca0ab3..e9c3e4ae 100644 --- a/templates/are_you_sure.html +++ b/templates/are_you_sure.html @@ -1,5 +1,5 @@ {{template "header.html" . }} -
+

{{lang "areyousure_head"}}

@@ -9,4 +9,4 @@
-{{template "footer.html" . }} +{{template "footer.html" . }} \ No newline at end of file diff --git a/templates/profile.html b/templates/profile.html index 46b71e45..fb3966c2 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -37,6 +37,9 @@ {{if .ProfileOwner.IsBanned}}{{lang "profile_unban"}} {{else}}{{lang "profile_ban"}}{{end}} {{end}} +
+ {{if .Blocked}}{{lang "profile_unblock"}}{{else}}{{lang "profile_block"}}{{end}} +
@@ -50,7 +53,7 @@ {{if .CurrentUser.Perms.BanUsers}}