Add UseConvosOnlyWithMod group permission.

Add UseConvosOnlyWithMod phrase.
Add initial convo tests.
Bar access to ConvosCreate route if we don't have the needed perms.
This commit is contained in:
Azareal 2020-02-11 13:13:38 +10:00
parent 59fb83619b
commit 84cdc097e7
15 changed files with 137 additions and 63 deletions

View File

@ -118,6 +118,7 @@ func seedTables(a qgen.Adapter) error {
UploadFiles UploadFiles
UploadAvatars UploadAvatars
UseConvos UseConvos
UseConvosOnlyWithMod
CreateProfileReply CreateProfileReply
AutoEmbed AutoEmbed
// CreateConvo ? // CreateConvo ?
@ -163,15 +164,15 @@ func seedTables(a qgen.Adapter) error {
perms.EditGroupAdmin = false perms.EditGroupAdmin = false
addGroup("Administrator", perms, true, true, false, "Admin") addGroup("Administrator", perms, true, true, false, "Admin")
perms = c.Perms{BanUsers: true, ActivateUsers: true, EditUser: true, EditUserEmail: false, EditUserGroup: true, ViewIPs: true, UploadFiles: true, UploadAvatars: true, UseConvos: true, CreateProfileReply: true, AutoEmbed: true, ViewTopic: true, LikeItem: true, CreateTopic: true, EditTopic: true, DeleteTopic: true, CreateReply: true, EditReply: true, DeleteReply: true, PinTopic: true, CloseTopic: true, MoveTopic: true} perms = c.Perms{BanUsers: true, ActivateUsers: true, EditUser: true, EditUserEmail: false, EditUserGroup: true, ViewIPs: true, UploadFiles: true, UploadAvatars: true, UseConvos: true, UseConvosOnlyWithMod: true, CreateProfileReply: true, AutoEmbed: 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") addGroup("Moderator", perms, true, false, false, "Mod")
perms = c.Perms{UploadFiles: true, UploadAvatars: true, UseConvos: true, CreateProfileReply: true, AutoEmbed: true, ViewTopic: true, LikeItem: true, CreateTopic: true, CreateReply: true} perms = c.Perms{UploadFiles: true, UploadAvatars: true, UseConvos: true, UseConvosOnlyWithMod: true, CreateProfileReply: true, AutoEmbed: true, ViewTopic: true, LikeItem: true, CreateTopic: true, CreateReply: true}
addGroup("Member", perms, false, false, false, "") addGroup("Member", perms, false, false, false, "")
perms = c.Perms{ViewTopic: true} perms = c.Perms{ViewTopic: true}
addGroup("Banned", perms, false, false, true, "") addGroup("Banned", perms, false, false, true, "")
addGroup("Awaiting Activation", perms, false, false, false, "") addGroup("Awaiting Activation", c.Perms{ViewTopic: true, UseConvosOnlyWithMod: true}, false, false, false, "")
addGroup("Not Loggedin", perms, false, false, false, "Guest") addGroup("Not Loggedin", perms, false, false, false, "Guest")
// //

View File

@ -5,7 +5,7 @@ import (
"encoding/json" "encoding/json"
"sync" "sync"
"github.com/Azareal/Gosora/query_gen" qgen "github.com/Azareal/Gosora/query_gen"
) )
var FPStore ForumPermsStore var FPStore ForumPermsStore
@ -13,8 +13,8 @@ var FPStore ForumPermsStore
type ForumPermsStore interface { type ForumPermsStore interface {
Init() error Init() error
GetAllMap() (bigMap map[int]map[int]*ForumPerms) GetAllMap() (bigMap map[int]map[int]*ForumPerms)
Get(fid int, gid int) (fperms *ForumPerms, err error) Get(fid, gid int) (fperms *ForumPerms, err error)
GetCopy(fid int, gid int) (fperms ForumPerms, err error) GetCopy(fid, gid int) (fperms ForumPerms, err error)
ReloadAll() error ReloadAll() error
Reload(id int) error Reload(id int) error
} }
@ -36,8 +36,8 @@ func NewMemoryForumPermsStore() (*MemoryForumPermsStore, error) {
acc := qgen.NewAcc() acc := qgen.NewAcc()
fp := "forums_permissions" fp := "forums_permissions"
return &MemoryForumPermsStore{ return &MemoryForumPermsStore{
getByForum: acc.Select(fp).Columns("gid,permissions").Where("fid = ?").Orderby("gid ASC").Prepare(), getByForum: acc.Select(fp).Columns("gid,permissions").Where("fid=?").Orderby("gid ASC").Prepare(),
getByForumGroup: acc.Select(fp).Columns("permissions").Where("fid = ? AND gid = ?").Prepare(), getByForumGroup: acc.Select(fp).Columns("permissions").Where("fid=? AND gid=?").Prepare(),
evenForums: make(map[int]map[int]*ForumPerms), evenForums: make(map[int]map[int]*ForumPerms),
oddForums: make(map[int]map[int]*ForumPerms), oddForums: make(map[int]map[int]*ForumPerms),
@ -91,7 +91,7 @@ func (s *MemoryForumPermsStore) Reload(fid int) error {
return err return err
} }
DebugLog("gid: ", gid) DebugLog("gid:", gid)
DebugLogf("perms: %+v\n", perms) DebugLogf("perms: %+v\n", perms)
pperms, err := s.parseForumPerm(perms) pperms, err := s.parseForumPerm(perms)
if err != nil { if err != nil {
@ -101,7 +101,7 @@ func (s *MemoryForumPermsStore) Reload(fid int) error {
forumPerms[gid] = pperms forumPerms[gid] = pperms
} }
DebugLogf("forumPerms: %+v\n", forumPerms) DebugLogf("forumPerms: %+v\n", forumPerms)
if fid%2 == 0 { if fid%2 == 0 {
s.evenLock.Lock() s.evenLock.Lock()
s.evenForums[fid] = forumPerms s.evenForums[fid] = forumPerms
@ -126,7 +126,7 @@ func (s *MemoryForumPermsStore) Reload(fid int) error {
TopicListThaw.Thaw() TopicListThaw.Thaw()
return nil return nil
} }
for _, group := range groups { for _, group := range groups {
DebugLogf("Updating the forum permissions for Group #%d", group.ID) DebugLogf("Updating the forum permissions for Group #%d", group.ID)
canSee := []int{} canSee := []int{}
@ -193,7 +193,7 @@ func (s *MemoryForumPermsStore) GetAllMap() (bigMap map[int]map[int]*ForumPerms)
// TODO: Add a hook here and have plugin_guilds use it // TODO: Add a hook here and have plugin_guilds use it
// TODO: Check if the forum exists? // TODO: Check if the forum exists?
// TODO: Fix the races // TODO: Fix the races
func (s *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err error) { func (s *MemoryForumPermsStore) Get(fid, gid int) (fperms *ForumPerms, err error) {
var fmap map[int]*ForumPerms var fmap map[int]*ForumPerms
var ok bool var ok bool
if fid%2 == 0 { if fid%2 == 0 {
@ -218,7 +218,7 @@ func (s *MemoryForumPermsStore) Get(fid int, gid int) (fperms *ForumPerms, err e
// TODO: Check if the forum exists? // TODO: Check if the forum exists?
// TODO: Fix the races // TODO: Fix the races
func (s *MemoryForumPermsStore) GetCopy(fid int, gid int) (fperms ForumPerms, err error) { func (s *MemoryForumPermsStore) GetCopy(fid, gid int) (fperms ForumPerms, err error) {
fPermsPtr, err := s.Get(fid, gid) fPermsPtr, err := s.Get(fid, gid)
if err != nil { if err != nil {
return fperms, err return fperms, err

View File

@ -40,6 +40,7 @@ var GlobalPermList = []string{
"UploadFiles", "UploadFiles",
"UploadAvatars", "UploadAvatars",
"UseConvos", "UseConvos",
"UseConvosOnlyWithMod",
"CreateProfileReply", "CreateProfileReply",
"AutoEmbed", "AutoEmbed",
} }
@ -68,11 +69,12 @@ type Perms struct {
ViewIPs bool `json:",omitempty"` ViewIPs bool `json:",omitempty"`
// Global non-staff permissions // Global non-staff permissions
UploadFiles bool `json:",omitempty"` UploadFiles bool `json:",omitempty"`
UploadAvatars bool `json:",omitempty"` UploadAvatars bool `json:",omitempty"`
UseConvos bool `json:",omitempty"` UseConvos bool `json:",omitempty"`
CreateProfileReply bool `json:",omitempty"` UseConvosOnlyWithMod bool `json:",omitempty"`
AutoEmbed bool `json:",omitempty"` CreateProfileReply bool `json:",omitempty"`
AutoEmbed bool `json:",omitempty"`
// Forum permissions // Forum permissions
ViewTopic bool `json:",omitempty"` ViewTopic bool `json:",omitempty"`
@ -126,11 +128,12 @@ func init() {
ViewAdminLogs: true, ViewAdminLogs: true,
ViewIPs: true, ViewIPs: true,
UploadFiles: true, UploadFiles: true,
UploadAvatars: true, UploadAvatars: true,
UseConvos: true, UseConvos: true,
CreateProfileReply: true, UseConvosOnlyWithMod: true,
AutoEmbed: true, CreateProfileReply: true,
AutoEmbed: true,
ViewTopic: true, ViewTopic: true,
LikeItem: true, LikeItem: true,

View File

@ -50,8 +50,6 @@ func NewDefaultGroupPromotionStore(acc *qgen.Accumulator) (*DefaultGroupPromotio
delete: acc.Delete(ugp).Where("pid=?").Prepare(), delete: acc.Delete(ugp).Where("pid=?").Prepare(),
create: acc.Insert(ugp).Columns("from_gid, to_gid, two_way, level, posts, minTime, registeredFor").Fields("?,?,?,?,?,?,?").Prepare(), create: acc.Insert(ugp).Columns("from_gid, to_gid, two_way, level, posts, minTime, registeredFor").Fields("?,?,?,?,?,?,?").Prepare(),
//err := s.getByUser.QueryRow(u.Group, level, posts, mins).Scan(&g.ID, &g.To, &g.TwoWay, &g.Level, &g.Posts, &g.MinTime, &g.RegisteredFor)
//getByUserMins: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime, registeredFor").Where("from_gid=? AND level<=? AND posts<=?").DateOlderThanQ("registeredFor", "minute").Orderby("level DESC").Limit("1").Prepare(),
getByUserMins: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime, registeredFor").Where("from_gid=? AND level<=? AND posts<=? AND registeredFor<=?").Orderby("level DESC").Limit("1").Prepare(), getByUserMins: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime, registeredFor").Where("from_gid=? AND level<=? AND posts<=? AND registeredFor<=?").Orderby("level DESC").Limit("1").Prepare(),
getByUser: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime, registeredFor").Where("from_gid=? AND level<=? AND posts<=?").Orderby("level DESC").Limit("1").Prepare(), getByUser: acc.Select(ugp).Columns("pid, to_gid, two_way, level, posts, minTime, registeredFor").Where("from_gid=? AND level<=? AND posts<=?").Orderby("level DESC").Limit("1").Prepare(),
updateUser: acc.Update("users").Set("group=?").Where("group=? AND uid=?").Prepare(), updateUser: acc.Update("users").Set("group=?").Where("group=? AND uid=?").Prepare(),

View File

@ -29,11 +29,11 @@ type DefaultBlockStore struct {
func NewDefaultBlockStore(acc *qgen.Accumulator) (*DefaultBlockStore, error) { func NewDefaultBlockStore(acc *qgen.Accumulator) (*DefaultBlockStore, error) {
ub := "users_blocks" ub := "users_blocks"
return &DefaultBlockStore{ return &DefaultBlockStore{
isBlocked: acc.Select(ub).Cols("blocker").Where("blocker = ? AND blockedUser = ?").Prepare(), isBlocked: acc.Select(ub).Cols("blocker").Where("blocker=? AND blockedUser=?").Prepare(),
add: acc.Insert(ub).Columns("blocker,blockedUser").Fields("?,?").Prepare(), add: acc.Insert(ub).Columns("blocker,blockedUser").Fields("?,?").Prepare(),
remove: acc.Delete(ub).Where("blocker = ? AND blockedUser = ?").Prepare(), remove: acc.Delete(ub).Where("blocker=? AND blockedUser=?").Prepare(),
blockedBy: acc.Select(ub).Columns("blockedUser").Where("blocker = ?").Limit("?,?").Prepare(), blockedBy: acc.Select(ub).Columns("blockedUser").Where("blocker=?").Limit("?,?").Prepare(),
blockedByCount: acc.Count(ub).Where("blocker = ?").Prepare(), blockedByCount: acc.Count(ub).Where("blocker=?").Prepare(),
}, acc.FirstError() }, acc.FirstError()
} }
@ -102,11 +102,12 @@ type DefaultFriendStore struct {
} }
func NewDefaultFriendStore(acc *qgen.Accumulator) (*DefaultFriendStore, error) { func NewDefaultFriendStore(acc *qgen.Accumulator) (*DefaultFriendStore, error) {
ufi := "users_friends_invites"
return &DefaultFriendStore{ return &DefaultFriendStore{
addInvite: acc.Insert("users_friends_invites").Columns("requester,target").Fields("?,?").Prepare(), addInvite: acc.Insert(ufi).Columns("requester,target").Fields("?,?").Prepare(),
confirm: acc.Insert("users_friends").Columns("uid,uid2").Fields("?,?").Prepare(), confirm: acc.Insert("users_friends").Columns("uid,uid2").Fields("?,?").Prepare(),
getOwnSentInvites: acc.Select("users_friends_invites").Cols("requester,target").Where("requester = ?").Prepare(), getOwnSentInvites: acc.Select(ufi).Cols("requester,target").Where("requester=?").Prepare(),
getOwnRecvInvites: acc.Select("users_friends_invites").Cols("requester,target").Where("target = ?").Prepare(), getOwnRecvInvites: acc.Select(ufi).Cols("requester,target").Where("target=?").Prepare(),
}, acc.FirstError() }, acc.FirstError()
} }

View File

@ -31,6 +31,7 @@
"UploadFiles": "Can upload files", "UploadFiles": "Can upload files",
"UploadAvatars": "Can upload avatars", "UploadAvatars": "Can upload avatars",
"UseConvos":"Can use conversations", "UseConvos":"Can use conversations",
"UseConvosOnlyWithMod":"Can use conversations only to contact global mods",
"CreateProfileReply": "Can create profile replies", "CreateProfileReply": "Can create profile replies",
"AutoEmbed":"Automatically embed media they post", "AutoEmbed":"Automatically embed media they post",

View File

@ -1102,6 +1102,58 @@ func testProfileReplyStore(t *testing.T, newID int, ip string) {
// TODO: Test pr.SetBody() and pr.Creator() // TODO: Test pr.SetBody() and pr.Creator()
} }
func TestConvos(t *testing.T) {
miscinit(t)
if !c.PluginsInited {
c.InitPlugins()
}
_, err := c.Convos.Get(-1)
recordMustNotExist(t, err, "convo -1 should not exist")
_, err = c.Convos.Get(0)
recordMustNotExist(t, err, "convo 0 should not exist")
_, err = c.Convos.Get(1)
recordMustNotExist(t, err, "convo 1 should not exist")
_, err = c.Convos.GetUser(-1,-1)
recordMustNotExist(t, err, "convo getuser -1 -1 should not exist")
_, err = c.Convos.GetUser(-1,0)
recordMustNotExist(t, err, "convo getuser -1 0 should not exist")
_, err = c.Convos.GetUser(0,0)
recordMustNotExist(t, err, "convo getuser 0 0 should not exist")
_, err = c.Convos.GetUser(1,0)
recordMustNotExist(t, err, "convos getuser 1 0 should not exist")
expect(t,c.Convos.GetUserCount(-1)==0,"getusercount should be zero")
expect(t,c.Convos.GetUserCount(0)==0,"getusercount should be zero")
expect(t,c.Convos.GetUserCount(1)==0,"getusercount should be zero")
_, err = c.Convos.GetUserExtra(-1,-1)
recordMustNotExist(t, err, "convos getuserextra -1 -1 should not exist")
_, err = c.Convos.GetUserExtra(-1,0)
recordMustNotExist(t, err, "convos getuserextra -1 0 should not exist")
_, err = c.Convos.GetUserExtra(0,0)
recordMustNotExist(t, err, "convos getuserextra 0 0 should not exist")
_, err = c.Convos.GetUserExtra(1,0)
recordMustNotExist(t, err, "convos getuserextra 1 0 should not exist")
expect(t,c.Convos.Count()==0,"convos count should be 0")
cid, err := c.Convos.Create("hehe", 1, []int{2})
expectNilErr(t,err)
expect(t,cid==1,"cid should be 1")
expect(t,c.Convos.Count()==1,"convos count should be 1")
co, err:= c.Convos.Get(cid)
expectNilErr(t,err)
expect(t,co.ID==1,"co.ID should be 1")
expect(t,co.CreatedBy==1,"co.CreatedBy should be 1")
// TODO: CreatedAt test
expect(t,co.LastReplyBy==1,"co.LastReplyBy should be 1")
// TODO: LastReplyAt test
// TODO: More tests
}
func TestActivityStream(t *testing.T) { func TestActivityStream(t *testing.T) {
miscinit(t) miscinit(t)
@ -1149,12 +1201,12 @@ func TestLogs(t *testing.T) {
recordMustExist(t, err, "We should have at-least one "+phrase) recordMustExist(t, err, "We should have at-least one "+phrase)
expect(t, len(logs) == 1, "The length of the log slice should be one") expect(t, len(logs) == 1, "The length of the log slice should be one")
log := logs[0] l := logs[0]
expect(t, log.Action == "something", "log.Action is not something") expect(t, l.Action == "something", "l.Action is not something")
expect(t, log.ElementID == 0, "log.ElementID is not 0") expect(t, l.ElementID == 0, "l.ElementID is not 0")
expect(t, log.ElementType == "bumblefly", "log.ElementType is not bumblefly") expect(t, l.ElementType == "bumblefly", "l.ElementType is not bumblefly")
expect(t, log.IP == "::1", "log.IP is not ::1") expect(t, l.IP == "::1", "l.IP is not ::1")
expect(t, log.ActorID == 1, "log.ActorID is not 1") expect(t, l.ActorID == 1, "l.ActorID is not 1")
// TODO: Add a test for log.DoneAt? Maybe throw in some dates and times which are clearly impossible but which may occur due to timezone bugs? // TODO: Add a test for log.DoneAt? Maybe throw in some dates and times which are clearly impossible but which may occur due to timezone bugs?
} }
gTests2(c.ModLogs, "modlog") gTests2(c.ModLogs, "modlog")

View File

@ -100,6 +100,9 @@ func Convo(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header
func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func ConvosCreate(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
accountEditHead("create_convo", w, r, &user, h) accountEditHead("create_convo", w, r, &user, h)
if !user.Perms.UseConvos && !user.Perms.UseConvosOnlyWithMod {
return c.NoPermissions(w, r, user)
}
h.AddNotice("convo_dev") h.AddNotice("convo_dev")
recpName := "" recpName := ""
pi := c.Account{h, "dashboard", "create_convo", c.ConvoCreatePage{h, recpName}} pi := c.Account{h, "dashboard", "create_convo", c.ConvoCreatePage{h, recpName}}
@ -111,7 +114,7 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.UseConvos { if !user.Perms.UseConvos && !user.Perms.UseConvosOnlyWithMod {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
@ -131,9 +134,15 @@ func ConvosCreateSubmit(w http.ResponseWriter, r *http.Request, user c.User) c.R
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
// TODO: Should we kick them out of existing conversations if they're moved into a group without permission or the permission is revoked from their group? We might want to give them a chance to delete their messages though to avoid privacy headaches here and it may only be temporarily to tackle a specific incident. // TODO: Should we kick them out of existing conversations if they're moved into a group without permission or the permission is revoked from their group? We might want to give them a chance to delete their messages though to avoid privacy headaches here and it may only be temporarily to tackle a specific incident.
if !u.Perms.UseConvos { if !u.Perms.UseConvos && !u.Perms.UseConvosOnlyWithMod {
return c.LocalError("One of the recipients doesn't have permission to use the conversations system", w, r, user) return c.LocalError("One of the recipients doesn't have permission to use the conversations system", w, r, user)
} }
if !user.Perms.UseConvos && !u.IsSuperMod && user.Perms.UseConvosOnlyWithMod {
return c.LocalError("You are only allowed to message global moderators.", w, r, user)
}
if !user.IsSuperMod && !u.Perms.UseConvos && u.Perms.UseConvosOnlyWithMod {
return c.LocalError("One of the recipients doesn't have permission to engage with conversation with you.", w, r, user)
}
blocked, err := c.UserBlocks.IsBlockedBy(u.ID, user.ID) blocked, err := c.UserBlocks.IsBlockedBy(u.ID, user.ID)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
@ -176,7 +185,7 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.UseConvos { if !user.Perms.UseConvos && !user.Perms.UseConvosOnlyWithMod {
return c.NoPermissions(w, r, user) return c.NoPermissions(w, r, user)
} }
cid, err := strconv.Atoi(scid) cid, err := strconv.Atoi(scid)
@ -197,6 +206,15 @@ func ConvosCreateReplySubmit(w http.ResponseWriter, r *http.Request, user c.User
if !convo.Has(user.ID) { if !convo.Has(user.ID) {
return c.LocalError("You are not in this conversation.", w, r, user) return c.LocalError("You are not in this conversation.", w, r, user)
} }
if !user.Perms.UseConvos && user.Perms.UseConvosOnlyWithMod {
u, err := c.Users.Get(convo.CreatedBy)
if err != nil {
return c.InternalError(err, w, r)
}
if !u.IsSuperMod {
return c.LocalError("You're only allowed to talk to global moderators.", w, r, user)
}
}
body := c.PreparseMessage(r.PostFormValue("content")) body := c.PreparseMessage(r.PostFormValue("content"))
post := &c.ConversationPost{CID: cid, Body: body, CreatedBy: user.ID} post := &c.ConversationPost{CID: cid, Body: body, CreatedBy: user.ID}

View File

@ -8,15 +8,15 @@ import (
"github.com/Azareal/Gosora/common/phrases" "github.com/Azareal/Gosora/common/phrases"
) )
func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.Header) c.RouteError { func ForumList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
skip, rerr := header.Hooks.VhookSkippable("route_forum_list_start", w, r, &user, header) skip, rerr := h.Hooks.VhookSkippable("route_forum_list_start", w, r, &user, h)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
header.Title = phrases.GetTitlePhrase("forums") h.Title = phrases.GetTitlePhrase("forums")
header.Zone = "forums" h.Zone = "forums"
header.Path = "/forums/" h.Path = "/forums/"
header.MetaDesc = header.Settings["meta_desc"].(string) h.MetaDesc = h.Settings["meta_desc"].(string)
var err error var err error
var canSee []int var canSee []int
@ -44,10 +44,10 @@ func ForumList(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
f.LastTopicTime = c.RelativeTime(f.LastTopic.LastReplyAt) f.LastTopicTime = c.RelativeTime(f.LastTopic.LastReplyAt)
} }
} }
header.Hooks.Hook("forums_frow_assign", &f) h.Hooks.Hook("forums_frow_assign", &f)
forumList = append(forumList, f) forumList = append(forumList, f)
} }
} }
return renderTemplate("forums", w, r, header, c.ForumsPage{header, forumList}) return renderTemplate("forums", w, r, h, c.ForumsPage{h, forumList})
} }

View File

@ -352,6 +352,7 @@ func GroupsEditPerms(w http.ResponseWriter, r *http.Request, user c.User, sgid s
addPerm("UploadFiles", g.Perms.UploadFiles) addPerm("UploadFiles", g.Perms.UploadFiles)
addPerm("UploadAvatars", g.Perms.UploadAvatars) addPerm("UploadAvatars", g.Perms.UploadAvatars)
addPerm("UseConvos", g.Perms.UseConvos) addPerm("UseConvos", g.Perms.UseConvos)
addPerm("UseConvosOnlyWithMod", g.Perms.UseConvosOnlyWithMod)
addPerm("CreateProfileReply", g.Perms.CreateProfileReply) addPerm("CreateProfileReply", g.Perms.CreateProfileReply)
addPerm("AutoEmbed", g.Perms.AutoEmbed) addPerm("AutoEmbed", g.Perms.AutoEmbed)

View File

@ -108,7 +108,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c.
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
} }
canMessage := (!blockedInv && user.Perms.UseConvos) || user.IsSuperMod canMessage := (!blockedInv && user.Perms.UseConvos) || (!blockedInv && puser.IsSuperMod && user.Perms.UseConvosOnlyWithMod) || user.IsSuperMod
canComment := !blockedInv && user.Perms.CreateProfileReply canComment := !blockedInv && user.Perms.CreateProfileReply
ppage := c.ProfilePage{header, reList, *puser, currentScore, nextScore, blocked, canMessage, canComment} ppage := c.ProfilePage{header, reList, *puser, currentScore, nextScore, blocked, canMessage, canComment}

View File

@ -162,7 +162,6 @@ func ActivateUser(w http.ResponseWriter, r *http.Request, user c.User, suid stri
} else if err != nil { } else if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
if targetUser.Active { if targetUser.Active {
return c.LocalError("The account you're trying to activate has already been activated.", w, r, user) return c.LocalError("The account you're trying to activate has already been activated.", w, r, user)
} }

View File

@ -7,11 +7,11 @@ 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 [settings] ([name],[content],[type]) VALUES ('google_site_verify','','html-attribute');
INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1); INSERT INTO [themes] ([uname],[default]) VALUES ('cosora',1);
INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1); INSERT INTO [emails] ([email],[uid],[validated]) VALUES ('admin@localhost',1,1);
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,"CreateProfileReply":true,"AutoEmbed":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 ('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,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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,"CreateProfileReply":true,"AutoEmbed":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 ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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,"CreateProfileReply":true,"AutoEmbed":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 ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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 ('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 ('Awaiting Activation','{"UseConvosOnlyWithMod":true,"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 [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],[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] ([name],[lastTopicID],[lastReplyerID],[desc],[tmpl]) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');

View File

@ -15,11 +15,11 @@ 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 `settings`(`name`,`content`,`type`) VALUES ('google_site_verify','','html-attribute');
INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1); INSERT INTO `themes`(`uname`,`default`) VALUES ('cosora',1);
INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1); INSERT INTO `emails`(`email`,`uid`,`validated`) VALUES ('admin@localhost',1,1);
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,"CreateProfileReply":true,"AutoEmbed":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 ('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,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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,"CreateProfileReply":true,"AutoEmbed":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 ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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,"CreateProfileReply":true,"AutoEmbed":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 ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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 ('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 ('Awaiting Activation','{"UseConvosOnlyWithMod":true,"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 `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`,`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`(`name`,`lastTopicID`,`lastReplyerID`,`desc`,`tmpl`) VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');

View File

@ -7,11 +7,11 @@ 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 "settings"("name","content","type") VALUES ('google_site_verify','','html-attribute');
INSERT INTO "themes"("uname","default") VALUES ('cosora',1); INSERT INTO "themes"("uname","default") VALUES ('cosora',1);
INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1); INSERT INTO "emails"("email","uid","validated") VALUES ('admin@localhost',1,1);
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,"CreateProfileReply":true,"AutoEmbed":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 ('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,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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,"CreateProfileReply":true,"AutoEmbed":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 ('Moderator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserGroup":true,"ViewIPs":true,"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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,"CreateProfileReply":true,"AutoEmbed":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 ('Member','{"UploadFiles":true,"UploadAvatars":true,"UseConvos":true,"UseConvosOnlyWithMod":true,"CreateProfileReply":true,"AutoEmbed":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 ('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 ('Awaiting Activation','{"UseConvosOnlyWithMod":true,"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 "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","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"("name","lastTopicID","lastReplyerID","desc","tmpl") VALUES ('General',1,1,'A place for general discussions which don''t fit elsewhere','');