github.com/Azareal/Gosora@v0.0.0-20210729070923-553e66b59003/common/forum_perms.go (about) 1 package common 2 3 import ( 4 "database/sql" 5 "encoding/json" 6 7 "github.com/Azareal/Gosora/query_gen" 8 ) 9 10 // ? - Can we avoid duplicating the items in this list in a bunch of places? 11 12 var LocalPermList = []string{ 13 "ViewTopic", 14 "LikeItem", 15 "CreateTopic", 16 "EditTopic", 17 "DeleteTopic", 18 "CreateReply", 19 "EditReply", 20 "DeleteReply", 21 "PinTopic", 22 "CloseTopic", 23 "MoveTopic", 24 } 25 26 // TODO: Rename this to ForumPermSet? 27 /* Inherit from group permissions for ones we don't have */ 28 type ForumPerms struct { 29 ViewTopic bool 30 //ViewOwnTopic bool 31 LikeItem bool 32 CreateTopic bool 33 EditTopic bool 34 DeleteTopic bool 35 CreateReply bool 36 //CreateReplyToOwn bool 37 EditReply bool 38 //EditOwnReply bool 39 DeleteReply bool 40 PinTopic bool 41 CloseTopic bool 42 //CloseOwnTopic bool 43 MoveTopic bool 44 45 Overrides bool 46 ExtData map[string]bool 47 } 48 49 func PresetToPermmap(preset string) (out map[string]*ForumPerms) { 50 out = make(map[string]*ForumPerms) 51 switch preset { 52 case "all": 53 out["guests"] = ReadForumPerms() 54 out["members"] = ReadWriteForumPerms() 55 out["staff"] = AllForumPerms() 56 out["admins"] = AllForumPerms() 57 case "announce": 58 out["guests"] = ReadForumPerms() 59 out["members"] = ReadReplyForumPerms() 60 out["staff"] = AllForumPerms() 61 out["admins"] = AllForumPerms() 62 case "members": 63 out["guests"] = BlankForumPerms() 64 out["members"] = ReadWriteForumPerms() 65 out["staff"] = AllForumPerms() 66 out["admins"] = AllForumPerms() 67 case "staff": 68 out["guests"] = BlankForumPerms() 69 out["members"] = BlankForumPerms() 70 out["staff"] = ReadWriteForumPerms() 71 out["admins"] = AllForumPerms() 72 case "admins": 73 out["guests"] = BlankForumPerms() 74 out["members"] = BlankForumPerms() 75 out["staff"] = BlankForumPerms() 76 out["admins"] = AllForumPerms() 77 case "archive": 78 out["guests"] = ReadForumPerms() 79 out["members"] = ReadForumPerms() 80 out["staff"] = ReadForumPerms() 81 out["admins"] = ReadForumPerms() //CurateForumPerms. Delete / Edit but no create? 82 default: 83 out["guests"] = BlankForumPerms() 84 out["members"] = BlankForumPerms() 85 out["staff"] = BlankForumPerms() 86 out["admins"] = BlankForumPerms() 87 } 88 return out 89 } 90 91 func PermmapToQuery(permmap map[string]*ForumPerms, fid int) error { 92 tx, err := qgen.Builder.Begin() 93 if err != nil { 94 return err 95 } 96 defer tx.Rollback() 97 98 deleteForumPermsByForumTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "fid = ?") 99 if err != nil { 100 return err 101 } 102 _, err = deleteForumPermsByForumTx.Exec(fid) 103 if err != nil { 104 return err 105 } 106 107 perms, err := json.Marshal(permmap["admins"]) 108 if err != nil { 109 return err 110 } 111 112 addForumPermsToForumAdminsTx, err := qgen.Builder.SimpleInsertSelectTx(tx, 113 qgen.DBInsert{"forums_permissions", "gid,fid,preset,permissions", ""}, 114 qgen.DBSelect{"users_groups", "gid,?,'',?", "is_admin = 1", "", ""}, 115 ) 116 if err != nil { 117 return err 118 } 119 _, err = addForumPermsToForumAdminsTx.Exec(fid, perms) 120 if err != nil { 121 return err 122 } 123 124 perms, err = json.Marshal(permmap["staff"]) 125 if err != nil { 126 return err 127 } 128 129 addForumPermsToForumStaffTx, err := qgen.Builder.SimpleInsertSelectTx(tx, 130 qgen.DBInsert{"forums_permissions", "gid,fid,preset,permissions", ""}, 131 qgen.DBSelect{"users_groups", "gid,?,'',?", "is_admin = 0 AND is_mod = 1", "", ""}, 132 ) 133 if err != nil { 134 return err 135 } 136 _, err = addForumPermsToForumStaffTx.Exec(fid, perms) 137 if err != nil { 138 return err 139 } 140 141 perms, err = json.Marshal(permmap["members"]) 142 if err != nil { 143 return err 144 } 145 146 addForumPermsToForumMembersTx, err := qgen.Builder.SimpleInsertSelectTx(tx, 147 qgen.DBInsert{"forums_permissions", "gid,fid,preset,permissions", ""}, 148 qgen.DBSelect{"users_groups", "gid,?,'',?", "is_admin = 0 AND is_mod = 0 AND is_banned = 0", "", ""}, 149 ) 150 if err != nil { 151 return err 152 } 153 _, err = addForumPermsToForumMembersTx.Exec(fid, perms) 154 if err != nil { 155 return err 156 } 157 158 // TODO: The group ID is probably a variable somewhere. Find it and use it. 159 // Group 5 is the Awaiting Activation group 160 err = ReplaceForumPermsForGroupTx(tx, 5, map[int]string{fid: ""}, map[int]*ForumPerms{fid: permmap["guests"]}) 161 if err != nil { 162 return err 163 } 164 165 // TODO: Consult a config setting instead of GuestUser? 166 err = ReplaceForumPermsForGroupTx(tx, GuestUser.Group, map[int]string{fid: ""}, map[int]*ForumPerms{fid: permmap["guests"]}) 167 if err != nil { 168 return err 169 } 170 171 err = tx.Commit() 172 if err != nil { 173 return err 174 } 175 return FPStore.Reload(fid) 176 //return TopicList.RebuildPermTree() 177 } 178 179 // TODO: FPStore.Reload? 180 func ReplaceForumPermsForGroup(gid int, presetSet map[int]string, permSets map[int]*ForumPerms) error { 181 tx, err := qgen.Builder.Begin() 182 if err != nil { 183 return err 184 } 185 defer tx.Rollback() 186 187 err = ReplaceForumPermsForGroupTx(tx, gid, presetSet, permSets) 188 if err != nil { 189 return err 190 } 191 return tx.Commit() 192 //return TopicList.RebuildPermTree() 193 } 194 195 func ReplaceForumPermsForGroupTx(tx *sql.Tx, gid int, presetSets map[int]string, permSets map[int]*ForumPerms) error { 196 deleteForumPermsForGroupTx, err := qgen.Builder.SimpleDeleteTx(tx, "forums_permissions", "gid = ? AND fid = ?") 197 if err != nil { 198 return err 199 } 200 201 addForumPermsToGroupTx, err := qgen.Builder.SimpleInsertTx(tx, "forums_permissions", "gid,fid,preset,permissions", "?,?,?,?") 202 if err != nil { 203 return err 204 } 205 for fid, permSet := range permSets { 206 permstr, err := json.Marshal(permSet) 207 if err != nil { 208 return err 209 } 210 _, err = deleteForumPermsForGroupTx.Exec(gid, fid) 211 if err != nil { 212 return err 213 } 214 _, err = addForumPermsToGroupTx.Exec(gid, fid, presetSets[fid], string(permstr)) 215 if err != nil { 216 return err 217 } 218 } 219 220 return nil 221 } 222 223 // TODO: Refactor this and write tests for it 224 // TODO: We really need to improve the thread safety of this 225 func ForumPermsToGroupForumPreset(fp *ForumPerms) string { 226 if !fp.Overrides { 227 return "default" 228 } 229 if !fp.ViewTopic { 230 return "no_access" 231 } 232 canPost := (fp.LikeItem && fp.CreateTopic && fp.CreateReply) 233 canModerate := (canPost && fp.EditTopic && fp.DeleteTopic && fp.EditReply && fp.DeleteReply && fp.PinTopic && fp.CloseTopic && fp.MoveTopic) 234 if canModerate { 235 return "can_moderate" 236 } 237 if fp.EditTopic || fp.DeleteTopic || fp.EditReply || fp.DeleteReply || fp.PinTopic || fp.CloseTopic || fp.MoveTopic { 238 //if !canPost { 239 return "custom" 240 //} 241 //return "quasi_mod" 242 } 243 244 if canPost { 245 return "can_post" 246 } 247 if fp.ViewTopic && !fp.LikeItem && !fp.CreateTopic && !fp.CreateReply { 248 return "read_only" 249 } 250 return "custom" 251 } 252 253 func GroupForumPresetToForumPerms(preset string) (fperms *ForumPerms, changed bool) { 254 switch preset { 255 case "read_only": 256 return ReadForumPerms(), true 257 case "can_post": 258 return ReadWriteForumPerms(), true 259 case "can_moderate": 260 return AllForumPerms(), true 261 case "no_access": 262 return &ForumPerms{Overrides: true, ExtData: make(map[string]bool)}, true 263 case "default": 264 return BlankForumPerms(), true 265 } 266 return fperms, false 267 } 268 269 func BlankForumPerms() *ForumPerms { 270 return &ForumPerms{ViewTopic: false} 271 } 272 273 func ReadWriteForumPerms() *ForumPerms { 274 return &ForumPerms{ 275 ViewTopic: true, 276 LikeItem: true, 277 CreateTopic: true, 278 CreateReply: true, 279 Overrides: true, 280 ExtData: make(map[string]bool), 281 } 282 } 283 284 func ReadReplyForumPerms() *ForumPerms { 285 return &ForumPerms{ 286 ViewTopic: true, 287 LikeItem: true, 288 CreateReply: true, 289 Overrides: true, 290 ExtData: make(map[string]bool), 291 } 292 } 293 294 func ReadForumPerms() *ForumPerms { 295 return &ForumPerms{ 296 ViewTopic: true, 297 Overrides: true, 298 ExtData: make(map[string]bool), 299 } 300 } 301 302 // AllForumPerms is a set of forum local permissions with everything set to true 303 func AllForumPerms() *ForumPerms { 304 return &ForumPerms{ 305 ViewTopic: true, 306 LikeItem: true, 307 CreateTopic: true, 308 EditTopic: true, 309 DeleteTopic: true, 310 CreateReply: true, 311 EditReply: true, 312 DeleteReply: true, 313 PinTopic: true, 314 CloseTopic: true, 315 MoveTopic: true, 316 317 Overrides: true, 318 ExtData: make(map[string]bool), 319 } 320 }