Use json marshal for the group permissions in querygen.

Add an omitempty json tag to the Perms struct.
Take the opportunity to shorten some things.
This commit is contained in:
Azareal 2019-10-06 15:32:08 +10:00
parent 8d40139ae5
commit 45a3065db1
9 changed files with 174 additions and 151 deletions

View File

@ -2,12 +2,14 @@
package main // import "github.com/Azareal/Gosora/query_gen"
import (
"encoding/json"
"fmt"
"log"
"os"
"runtime/debug"
"strconv"
c "github.com/Azareal/Gosora/common"
qgen "github.com/Azareal/Gosora/query_gen"
)
@ -175,18 +177,42 @@ func seedTables(adapter qgen.Adapter) error {
MoveTopic
*/
// TODO: Set the permissions on a struct and then serialize the struct and insert that instead of writing raw JSON
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, tag", `'Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,"Admin"`)
p := func(perms c.Perms) string {
jBytes, err := json.Marshal(perms)
if err != nil {
panic(err)
}
return string(jBytes)
}
addGroup := func(name string, perms c.Perms, mod bool, admin bool, banned bool, tag string) {
mi, ai, bi := "0", "0", "0"
if mod {
mi = "1"
}
if admin {
ai = "1"
}
if banned {
bi = "1"
}
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, is_admin, is_banned, tag", `'`+name+`','`+p(perms)+`','{}',`+mi+`,`+ai+`,`+bi+`,"`+tag+`"`)
}
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_mod, tag", `'Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,"Mod"`)
perms := c.AllPerms
perms.EditUserGroupAdmin = false
perms.EditGroupAdmin = false
addGroup("Administrator", perms, true, true, false, "Admin")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}'`)
perms = c.Perms{BanUsers: true, ActivateUsers: true, EditUser: true, EditUserEmail: false, EditUserGroup: true, ViewIPs: true, UploadFiles: true, UploadAvatars: true, UseConvos: true, ViewTopic: true, LikeItem: true, CreateTopic: true, EditTopic: true, DeleteTopic: true, CreateReply: true, EditReply: true, DeleteReply: true, PinTopic: true, CloseTopic: true, MoveTopic: true}
addGroup("Moderator", perms, true, false, false, "Mod")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, is_banned", `'Banned','{"ViewTopic":true}','{}',1`)
perms = c.Perms{UploadFiles: true, UploadAvatars: true, UseConvos: true, ViewTopic: true, LikeItem: true, CreateTopic: true, CreateReply: true}
addGroup("Member", perms, false, false, false, "")
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms", `'Awaiting Activation','{"ViewTopic":true}','{}'`)
qgen.Install.SimpleInsert("users_groups", "name, permissions, plugin_perms, tag", `'Not Loggedin','{"ViewTopic":true}','{}','Guest'`)
perms = c.Perms{ViewTopic: true}
addGroup("Banned", perms, false, false, true, "")
addGroup("Awaiting Activation", perms, false, false, false, "")
addGroup("Not Loggedin", perms, false, false, false, "Guest")
//
// TODO: Stop processFields() from stripping the spaces in the descriptions in the next commit

View File

@ -45,50 +45,50 @@ var GlobalPermList = []string{
// Permission Structure: ActionComponent[Subcomponent]Flag
type Perms struct {
// Global Permissions
BanUsers bool
ActivateUsers bool
EditUser bool
EditUserEmail bool
EditUserPassword bool
EditUserGroup bool
EditUserGroupSuperMod bool
EditUserGroupAdmin bool
EditGroup bool
EditGroupLocalPerms bool
EditGroupGlobalPerms bool
EditGroupSuperMod bool
EditGroupAdmin bool
ManageForums bool // This could be local, albeit limited for per-forum managers?
EditSettings bool
ManageThemes bool
ManagePlugins bool
ViewAdminLogs bool
ViewIPs bool
BanUsers bool `json:",omitempty"`
ActivateUsers bool `json:",omitempty"`
EditUser bool `json:",omitempty"`
EditUserEmail bool `json:",omitempty"`
EditUserPassword bool `json:",omitempty"`
EditUserGroup bool `json:",omitempty"`
EditUserGroupSuperMod bool `json:",omitempty"`
EditUserGroupAdmin bool `json:",omitempty"`
EditGroup bool `json:",omitempty"`
EditGroupLocalPerms bool `json:",omitempty"`
EditGroupGlobalPerms bool `json:",omitempty"`
EditGroupSuperMod bool `json:",omitempty"`
EditGroupAdmin bool `json:",omitempty"`
ManageForums bool `json:",omitempty"` // This could be local, albeit limited for per-forum managers?
EditSettings bool `json:",omitempty"`
ManageThemes bool `json:",omitempty"`
ManagePlugins bool `json:",omitempty"`
ViewAdminLogs bool `json:",omitempty"`
ViewIPs bool `json:",omitempty"`
// Global non-staff permissions
UploadFiles bool
UploadAvatars bool
UseConvos bool
UploadFiles bool `json:",omitempty"`
UploadAvatars bool `json:",omitempty"`
UseConvos bool `json:",omitempty"`
// Forum permissions
ViewTopic bool
//ViewOwnTopic bool
LikeItem bool
CreateTopic bool
EditTopic bool
DeleteTopic bool
CreateReply bool
//CreateReplyToOwn bool
EditReply bool
//EditOwnReply bool
DeleteReply bool
//DeleteOwnReply bool
PinTopic bool
CloseTopic bool
//CloseOwnTopic bool
MoveTopic bool
ViewTopic bool `json:",omitempty"`
//ViewOwnTopic bool `json:",omitempty"`
LikeItem bool `json:",omitempty"`
CreateTopic bool `json:",omitempty"`
EditTopic bool `json:",omitempty"`
DeleteTopic bool `json:",omitempty"`
CreateReply bool `json:",omitempty"`
//CreateReplyToOwn bool `json:",omitempty"`
EditReply bool `json:",omitempty"`
//EditOwnReply bool `json:",omitempty"`
DeleteReply bool `json:",omitempty"`
//DeleteOwnReply bool `json:",omitempty"`
PinTopic bool `json:",omitempty"`
CloseTopic bool `json:",omitempty"`
//CloseOwnTopic bool `json:",omitempty"`
MoveTopic bool `json:",omitempty"`
//ExtData map[string]bool
//ExtData map[string]bool `json:",omitempty"`
}
func init() {

View File

@ -11,9 +11,9 @@ import (
"runtime/debug"
"strconv"
"strings"
"unicode"
"text/template/parse"
"time"
"unicode"
)
// TODO: Turn this file into a library
@ -107,15 +107,15 @@ func NewCTemplateSet(in string) *CTemplateSet {
"hasWidgets": true,
"elapsed": true,
"lang": true,
"langf":true,
"level": true,
"bunit": true,
"abstime": true,
"reltime": true,
"scope": true,
"dyntmpl": true,
"index": true,
"flush": true,
"langf": true,
"level": true,
"bunit": true,
"abstime": true,
"reltime": true,
"scope": true,
"dyntmpl": true,
"index": true,
"flush": true,
},
logger: log.New(f, "", log.LstdFlags),
loggerf: f,
@ -193,9 +193,9 @@ func (c *CTemplateSet) CompileByLoggedin(name string, fileDir string, expects st
}
var importList string
for _, item := range c.importMap {
ispl := strings.Split(item," ")
ispl := strings.Split(item, " ")
if len(ispl) > 1 {
importList += "import "+ispl[0]+" \"" + ispl[1] + "\"\n"
importList += "import " + ispl[0] + " \"" + ispl[1] + "\"\n"
} else {
importList += "import \"" + item + "\"\n"
}
@ -284,8 +284,7 @@ func (c *CTemplateSet) Compile(name string, fileDir string, expects string, expe
func (c *CTemplateSet) compile(name string, content string, expects string, expectsInt interface{}, varList map[string]VarItem, imports ...string) (out string, err error) {
defer func() {
r := recover()
if r != nil {
if r := recover(); r != nil {
fmt.Println(r)
debug.PrintStack()
err := c.loggerf.Sync()
@ -313,7 +312,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
c.stats = make(map[string]int)
tree := parse.New(name, c.funcMap)
var treeSet = make(map[string]*parse.Tree)
treeSet := make(map[string]*parse.Tree)
tree, err = tree.Parse(content, "{{", "}}", treeSet, c.funcMap)
if err != nil {
return "", err
@ -413,9 +412,9 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
}
var importList string
for _, item := range c.importMap {
ispl := strings.Split(item," ")
ispl := strings.Split(item, " ")
if len(ispl) > 1 {
importList += "import "+ispl[0]+" \"" + ispl[1] + "\"\n"
importList += "import " + ispl[0] + " \"" + ispl[1] + "\"\n"
} else {
importList += "import \"" + item + "\"\n"
}
@ -481,9 +480,9 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
}
fout += varString
var skipped = make(map[string]*SkipBlock) // map[templateName]*SkipBlock{map[atIndexAndAfter]skipThisMuch,lastCount}
skipped := make(map[string]*SkipBlock) // map[templateName]*SkipBlock{map[atIndexAndAfter]skipThisMuch,lastCount}
var writeTextFrame = func(tmplName string, index int) {
writeTextFrame := func(tmplName string, index int) {
out := "w.Write(" + tmplName + "_frags[" + strconv.Itoa(index) + "]" + ")\n"
c.detail("writing ", out)
fout += out
@ -531,7 +530,7 @@ func (c *CTemplateSet) compile(name string, content string, expects string, expe
}
fout += "return nil\n}\n"
var writeFrag = func(tmplName string, index int, body string) {
writeFrag := func(tmplName string, index int, body string) {
//c.detail("writing ", fragmentPrefix)
c.FragOut = append(c.FragOut, OutFrag{tmplName, index, body})
}
@ -704,7 +703,7 @@ func (c *CTemplateSet) compileRangeNode(con CContext, node *parse.RangeNode) {
c.detail("Expr:", expr)
c.detail("Range Kind Switch!")
var startIf = func(item reflect.Value, useCopy bool) {
startIf := func(item reflect.Value, useCopy bool) {
con.Push("startif", "if len("+expr+") != 0 {\n")
startIndex := con.StartLoop("for _, item := range " + expr + " {\n")
ccon := con
@ -812,7 +811,7 @@ func (c *CTemplateSet) compileSubSwitch(con CContext, node *parse.CommandNode) {
}
var assLines string
var multiline = false
multiline := false
for _, id := range n.Ident {
c.detail("Data Kind:", cur.Kind().String())
c.detail("Field Bit:", id)
@ -1023,7 +1022,7 @@ func (c *CTemplateSet) compareJoin(con CContext, pos int, node *parse.CommandNod
func (c *CTemplateSet) compileIdentSwitch(con CContext, node *parse.CommandNode) (out string, val reflect.Value, literal bool, notident bool) {
c.dumpCall("compileIdentSwitch", con, node)
var litString = func(inner string, bytes bool) {
litString := func(inner string, bytes bool) {
if !bytes {
inner = "StringToBytes(" + inner + ")"
}
@ -1129,9 +1128,9 @@ ArgLoop:
if leftOperand[0] != '"' {
panic("Phrase names cannot be dynamic")
}
var olist []string
for i := pos+2; i < len(node.Args); i++ {
for i := pos + 2; i < len(node.Args); i++ {
op := node.Args[i].String()
if op != "" {
if op[0] == '.' || op[0] == '$' {
@ -1140,14 +1139,14 @@ ArgLoop:
if op[0] != '"' && !unicode.IsDigit(rune(op[0])) {
break
}
olist = append(olist,op)
olist = append(olist, op)
}
}
if len(olist) == 0 {
panic("You must provide parameters for langf")
}
var ob = ","
ob := ","
for _, op := range olist {
allNum := true
for _, o := range op {
@ -1156,7 +1155,7 @@ ArgLoop:
}
}
if allNum {
ob += strings.Replace(op,"\"","\\\"",-1) + ","
ob += strings.Replace(op, "\"", "\\\"", -1) + ","
} else {
ob += ob + ","
}
@ -1316,8 +1315,8 @@ func (c *CTemplateSet) compileIfVarSub(con CContext, varname string) (out string
return varname, cur
}
var stepInterface = func() {
var nobreak = (cur.Type().Name() == "nobreak")
stepInterface := func() {
nobreak := (cur.Type().Name() == "nobreak")
c.detailf("cur.Type().Name(): %+v\n", cur.Type().Name())
if cur.Kind() == reflect.Interface && !nobreak {
cur = cur.Elem()
@ -1345,7 +1344,7 @@ func (c *CTemplateSet) compileIfVarSub(con CContext, varname string) (out string
}
bits[0] = strings.TrimPrefix(bits[0], "$")
var dumpKind = func(pre string) {
dumpKind := func(pre string) {
c.detail(pre+" Kind:", cur.Kind())
c.detail(pre+" Type:", cur.Type().Name())
}
@ -1484,12 +1483,12 @@ func (c *CTemplateSet) retCall(name string, params ...interface{}) {
}
func buildUserExprs(holder string) ([]string, []string) {
var userExprs = []string{
userExprs := []string{
holder + ".CurrentUser.Loggedin",
holder + ".CurrentUser.IsSuperMod",
holder + ".CurrentUser.IsAdmin",
}
var negUserExprs = []string{
negUserExprs := []string{
"!" + holder + ".CurrentUser.Loggedin",
"!" + holder + ".CurrentUser.IsSuperMod",
"!" + holder + ".CurrentUser.IsAdmin",

View File

@ -20,7 +20,7 @@ import (
"strconv"
"text/template"
"github.com/Azareal/Gosora/common/phrases"
p "github.com/Azareal/Gosora/common/phrases"
)
var ErrNoDefaultTheme = errors.New("The default theme isn't registered in the system")
@ -88,8 +88,8 @@ type ThemeMapTmplToDock struct {
}
// TODO: It might be unsafe to call the template parsing functions with fsnotify, do something more concurrent
func (theme *Theme) LoadStaticFiles() error {
theme.ResourceTemplates = template.New("")
func (t *Theme) LoadStaticFiles() error {
t.ResourceTemplates = template.New("")
fmap := make(map[string]interface{})
fmap["lang"] = func(phraseNameInt interface{}, tmplInt interface{}) interface{} {
phraseName, ok := phraseNameInt.(string)
@ -117,18 +117,18 @@ func (theme *Theme) LoadStaticFiles() error {
}
return out
}
theme.ResourceTemplates.Funcs(fmap)
template.Must(theme.ResourceTemplates.ParseGlob("./themes/" + theme.Name + "/public/*.css"))
t.ResourceTemplates.Funcs(fmap)
template.Must(t.ResourceTemplates.ParseGlob("./themes/" + t.Name + "/public/*.css"))
// It should be safe for us to load the files for all the themes in memory, as-long as the admin hasn't setup a ridiculous number of themes
return theme.AddThemeStaticFiles()
return t.AddThemeStaticFiles()
}
func (theme *Theme) AddThemeStaticFiles() error {
phraseMap := phrases.GetTmplPhrases()
func (t *Theme) AddThemeStaticFiles() error {
phraseMap := p.GetTmplPhrases()
// TODO: Use a function instead of a closure to make this more testable? What about a function call inside the closure to take the theme variable into account?
return filepath.Walk("./themes/"+theme.Name+"/public", func(path string, f os.FileInfo, err error) error {
DebugLog("Attempting to add static file '" + path + "' for default theme '" + theme.Name + "'")
return filepath.Walk("./themes/"+t.Name+"/public", func(path string, f os.FileInfo, err error) error {
DebugLog("Attempting to add static file '" + path + "' for default theme '" + t.Name + "'")
if err != nil {
return err
}
@ -142,21 +142,21 @@ func (theme *Theme) AddThemeStaticFiles() error {
return err
}
var ext = filepath.Ext(path)
ext := filepath.Ext(path)
if ext == ".css" && len(data) != 0 {
var b bytes.Buffer
pieces := strings.Split(path, "/")
filename := pieces[len(pieces)-1]
// TODO: Prepare resource templates for each loaded langpack?
err = theme.ResourceTemplates.ExecuteTemplate(&b, filename, CSSData{Phrases: phraseMap})
err = t.ResourceTemplates.ExecuteTemplate(&b, filename, CSSData{Phrases: phraseMap})
if err != nil {
log.Print("Failed in adding static file '" + path + "' for default theme '" + theme.Name + "'")
log.Print("Failed in adding static file '" + path + "' for default theme '" + t.Name + "'")
return err
}
data = b.Bytes()
}
path = strings.TrimPrefix(path, "themes/"+theme.Name+"/public")
path = strings.TrimPrefix(path, "themes/"+t.Name+"/public")
gzipData, err := CompressBytesGzip(data)
if err != nil {
return err
@ -167,16 +167,16 @@ func (theme *Theme) AddThemeStaticFiles() error {
hasher.Write(data)
checksum := hex.EncodeToString(hasher.Sum(nil))
StaticFiles.Set("/s/"+theme.Name+path, SFile{data, gzipData, checksum,theme.Name+path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)),strconv.Itoa(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
StaticFiles.Set("/s/"+t.Name+path, SFile{data, gzipData, checksum,t.Name+path + "?h=" + checksum, 0, int64(len(data)), int64(len(gzipData)),strconv.Itoa(len(gzipData)), mime.TypeByExtension(ext), f, f.ModTime().UTC().Format(http.TimeFormat)})
DebugLog("Added the '/" + theme.Name + path + "' static file for theme " + theme.Name + ".")
DebugLog("Added the '/" + t.Name + path + "' static file for theme " + t.Name + ".")
return nil
})
}
func (theme *Theme) MapTemplates() {
if theme.Templates != nil {
for _, themeTmpl := range theme.Templates {
func (t *Theme) MapTemplates() {
if t.Templates != nil {
for _, themeTmpl := range t.Templates {
if themeTmpl.Name == "" {
LogError(errors.New("Invalid destination template name"))
}
@ -215,34 +215,34 @@ func (theme *Theme) MapTemplates() {
}
}
func (theme *Theme) setActive(active bool) error {
func (t *Theme) setActive(active bool) error {
var sink bool
err := themeStmts.isDefault.QueryRow(theme.Name).Scan(&sink)
err := themeStmts.isDefault.QueryRow(t.Name).Scan(&sink)
if err != nil && err != sql.ErrNoRows {
return err
}
hasTheme := err != sql.ErrNoRows
if hasTheme {
_, err = themeStmts.update.Exec(active, theme.Name)
_, err = themeStmts.update.Exec(active, t.Name)
} else {
_, err = themeStmts.add.Exec(theme.Name, active)
_, err = themeStmts.add.Exec(t.Name, active)
}
if err != nil {
return err
}
// TODO: Think about what we want to do for multi-server configurations
log.Printf("Setting theme '%s' as the default theme", theme.Name)
theme.Active = active
log.Printf("Setting theme '%s' as the default theme", t.Name)
t.Active = active
return nil
}
func UpdateDefaultTheme(theme *Theme) error {
func UpdateDefaultTheme(t *Theme) error {
ChangeDefaultThemeMutex.Lock()
defer ChangeDefaultThemeMutex.Unlock()
err := theme.setActive(true)
err := t.setActive(true)
if err != nil {
return err
}
@ -258,15 +258,15 @@ func UpdateDefaultTheme(theme *Theme) error {
return err
}
DefaultThemeBox.Store(theme.Name)
DefaultThemeBox.Store(t.Name)
ResetTemplateOverrides()
theme.MapTemplates()
t.MapTemplates()
return nil
}
func (theme Theme) HasDock(name string) bool {
for _, dock := range theme.Docks {
func (t Theme) HasDock(name string) bool {
for _, dock := range t.Docks {
if dock == name {
return true
}
@ -274,8 +274,8 @@ func (theme Theme) HasDock(name string) bool {
return false
}
func (theme Theme) BuildDock(dock string) (sbody string) {
runOnDock := theme.RunOnDock
func (t Theme) BuildDock(dock string) (sbody string) {
runOnDock := t.RunOnDock
if runOnDock != nil {
return runOnDock(dock)
}
@ -294,14 +294,14 @@ func (w GzipResponseWriter) Write(b []byte) (int, error) {
// NEW method of doing theme templates to allow one user to have a different theme to another. Under construction.
// TODO: Generate the type switch instead of writing it by hand
// TODO: Cut the number of types in half
func (theme *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error {
func (t *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error {
// Unpack this to avoid an indirect call
gzw, ok := w.(GzipResponseWriter)
if ok {
w = gzw.Writer
}
var getTmpl = theme.GetTmpl(template)
getTmpl := t.GetTmpl(template)
switch tmplO := getTmpl.(type) {
case *func(interface{}, io.Writer) error:
var tmpl = *tmplO
@ -310,16 +310,16 @@ func (theme *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error
return tmplO(pi, w)
case nil, string:
//fmt.Println("falling back to interpreted for " + template)
mapping, ok := theme.TemplatesMap[template]
mapping, ok := t.TemplatesMap[template]
if !ok {
mapping = template
}
if theme.IntTmplHandle.Lookup(mapping+".html") == nil {
if t.IntTmplHandle.Lookup(mapping+".html") == nil {
return ErrBadDefaultTemplate
}
return theme.IntTmplHandle.ExecuteTemplate(w, mapping+".html", pi)
return t.IntTmplHandle.ExecuteTemplate(w, mapping+".html", pi)
default:
log.Print("theme ", theme)
log.Print("theme ", t)
log.Print("template ", template)
log.Print("pi ", pi)
log.Print("tmplO ", tmplO)
@ -339,14 +339,14 @@ func (theme *Theme) RunTmpl(template string, pi interface{}, w io.Writer) error
}
// GetTmpl attempts to get the template for a specific theme, otherwise it falls back on the default template pointer, which if absent will fallback onto the template interpreter
func (theme *Theme) GetTmpl(template string) interface{} {
func (t *Theme) GetTmpl(template string) interface{} {
// TODO: Figure out why we're getting a nil pointer here when transpiled templates are disabled, I would have assumed that we would just fall back to !ok on this
// Might have something to do with it being the theme's TmplPtr map, investigate.
tmpl, ok := theme.TmplPtr[template]
tmpl, ok := t.TmplPtr[template]
if ok {
return tmpl
}
tmpl, ok = TmplPtrMap[template+"_"+theme.Name]
tmpl, ok = TmplPtrMap[template+"_"+t.Name]
if ok {
return tmpl
}

View File

@ -54,7 +54,7 @@ func NewDefaultWordFilterStore(acc *qgen.Accumulator) (*DefaultWordFilterStore,
// ReloadAll drops all the items in the memory cache and replaces them with fresh copies from the database
func (s *DefaultWordFilterStore) ReloadAll() error {
var wordFilters = make(map[int]*WordFilter)
wordFilters := make(map[int]*WordFilter)
filters, err := s.bypassGetAll()
if err != nil {
return err
@ -77,12 +77,12 @@ func (s *DefaultWordFilterStore) bypassGetAll() (filters []*WordFilter, err erro
defer rows.Close()
for rows.Next() {
filter := &WordFilter{ID: 0}
err := rows.Scan(&filter.ID, &filter.Find, &filter.Replacement)
f := &WordFilter{ID: 0}
err := rows.Scan(&f.ID, &f.Find, &f.Replacement)
if err != nil {
return filters, err
}
filters = append(filters, filter)
filters = append(filters, f)
}
return filters, rows.Err()
}
@ -93,8 +93,8 @@ func (s *DefaultWordFilterStore) GetAll() (filters map[int]*WordFilter, err erro
}
// Create adds a new word filter to the database and refreshes the memory cache
func (s *DefaultWordFilterStore) Create(find string, replacement string) error {
_, err := s.create.Exec(find, replacement)
func (s *DefaultWordFilterStore) Create(find string, replace string) error {
_, err := s.create.Exec(find, replace)
if err != nil {
return err
}
@ -110,8 +110,8 @@ func (s *DefaultWordFilterStore) Delete(id int) error {
return s.ReloadAll()
}
func (s *DefaultWordFilterStore) Update(id int, find string, replacement string) error {
_, err := s.update.Exec(find, replacement, id)
func (s *DefaultWordFilterStore) Update(id int, find string, replace string) error {
_, err := s.update.Exec(find, replace, id)
if err != nil {
return err
}

View File

@ -7,12 +7,12 @@ INSERT INTO [settings] ([name],[content],[type]) VALUES ('rapid_loading','1','bo
INSERT INTO [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute');
INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1);
INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_banned]) VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,0,'Admin');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,0,0,'Mod');
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}',0,0,0,"");
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Banned','{"ViewTopic":true}','{}',0,0,1,"");
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}',0,0,0,"");
INSERT INTO [users_groups] ([name],[permissions],[plugin_perms],[is_mod],[is_admin],[is_banned],[tag]) VALUES ('Not Loggedin','{"ViewTopic":true}','{}',0,0,0,'Guest');
INSERT INTO [forums] ([name],[active],[desc],[tmpl]) VALUES ('Reports',0,'All the reports go here','');
INSERT INTO [forums] ([name],[lastTopicID],[lastReplyerID],[desc],[tmpl]) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');
INSERT INTO [forums_permissions] ([gid],[fid],[permissions]) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}');

View File

@ -15,12 +15,12 @@ INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('rapid_loading','1','boo
INSERT INTO `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute');
INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1);
INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_banned`) VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,0,'Admin');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,0,0,'Mod');
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}',0,0,0,"");
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Banned','{"ViewTopic":true}','{}',0,0,1,"");
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Awaiting Activation','{"ViewTopic":true}','{}',0,0,0,"");
INSERT INTO `users_groups`(`name`,`permissions`,`plugin_perms`,`is_mod`,`is_admin`,`is_banned`,`tag`) VALUES ('Not Loggedin','{"ViewTopic":true}','{}',0,0,0,'Guest');
INSERT INTO `forums`(`name`,`active`,`desc`,`tmpl`) VALUES ('Reports',0,'All the reports go here','');
INSERT INTO `forums`(`name`,`lastTopicID`,`lastReplyerID`,`desc`,`tmpl`) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');
INSERT INTO `forums_permissions`(`gid`,`fid`,`permissions`) VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}');

View File

@ -7,12 +7,12 @@ INSERT INTO "settings"("name","content","type") VALUES ('rapid_loading','1','boo
INSERT INTO "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute');
INSERT INTO "themes"("uname","default") VALUES ('cosora',1);
INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1);
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,'Admin');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,'Mod');
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_banned") VALUES ('Banned','{"ViewTopic":true}','{}',1);
INSERT INTO "users_groups"("name","permissions","plugin_perms") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}');
INSERT INTO "users_groups"("name","permissions","plugin_perms","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}','Guest');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewAdminLogs":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,1,0,'Admin');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true,"MoveTopic":true}','{}',1,0,0,'Mod');
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}','{}',0,0,0,"");
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Banned','{"ViewTopic":true}','{}',0,0,1,"");
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Awaiting Activation','{"ViewTopic":true}','{}',0,0,0,"");
INSERT INTO "users_groups"("name","permissions","plugin_perms","is_mod","is_admin","is_banned","tag") VALUES ('Not Loggedin','{"ViewTopic":true}','{}',0,0,0,'Guest');
INSERT INTO "forums"("name","active","desc","tmpl") VALUES ('Reports',0,'All the reports go here','');
INSERT INTO "forums"("name","lastTopicID","lastReplyerID","desc","tmpl") VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');
INSERT INTO "forums_permissions"("gid","fid","permissions") VALUES (1,1,'{"ViewTopic":true,"CreateReply":true,"CreateTopic":true,"PinTopic":true,"CloseTopic":true}');

View File

@ -26,9 +26,7 @@
{{end}}
</div>
</div>
{{if .Poll.ID}}
{{template "topic_poll.html" . }}
{{end}}
{{if .Poll.ID}}{{template "topic_poll.html" . }}{{end}}
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}), url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">