unit tests for profile comment visibility

This commit is contained in:
Azareal 2020-07-15 16:59:47 +10:00
parent eeb932bd4b
commit 5bfc5e3e40
4 changed files with 158 additions and 53 deletions

View File

@ -66,8 +66,8 @@ type User struct {
}
type UserPrivacy struct {
ShowComments int // 0 = default, 1 = public, 2 = registered, 3 = friends, 4 = mods / self
AllowMessage int // 0 = default, 1 = registered, 2 = friends, 3 = mods / self
ShowComments int // 0 = default, 1 = public, 2 = registered, 3 = friends, 4 = self, 5 = disabled / unused
AllowMessage int // 0 = default, 1 = registered, 2 = friends, 3 = mods, 4 = disabled / unused
}
func (u *User) WebSockets() *WsJSONUser {
@ -569,7 +569,6 @@ var ErrProfileCommentsOutOfBounds = errors.New("profile_comments must be an inte
var ErrEnableEmbedsOutOfBounds = errors.New("enable_embeds must be -1, 0 or 1")
/*func (u *User) UpdatePrivacyS(sProfileComments, sEnableEmbeds string) error {
return u.UpdatePrivacy(profileComments, enableEmbeds)
}*/
@ -723,6 +722,43 @@ func (u *User) InitPerms() {
}
}
// TODO: Write tests
// TODO: Implement and use this
// TODO: Implement friends
func PrivacyAllowMessage(pu, u *User) (canMsg bool) {
switch pu.Privacy.AllowMessage {
case 4: // Unused
canMsg = false
case 3: // mods
canMsg = u.IsSuperMod
//case 2: // friends
case 1: // registered
canMsg = true
default: // 0
canMsg = true
}
return canMsg
}
// TODO: Implement friend system
func PrivacyCommentsShow(pu, u *User) (showComments bool) {
switch pu.Privacy.ShowComments {
case 5: // Unused
showComments = false
case 4: // Self
showComments = u.ID == pu.ID
case 3: // friends
showComments = u.ID == pu.ID
case 2: // registered
showComments = u.Loggedin
case 1: // public
showComments = true
default: // 0
showComments = true
}
return showComments
}
var guestAvatar GuestAvatar
type GuestAvatar struct {

View File

@ -2197,6 +2197,108 @@ func passwordTest(t *testing.T, realPassword, hashedPassword string) {
expect(t, err != nil, "The two shouldn't match!")
}
func TestUserPrivacy(t *testing.T) {
pu, u := c.BlankUser(), &c.GuestUser
pu.ID = 1
var msg string
test := func(expects bool, level int) {
pu.Privacy.ShowComments = level
val := c.PrivacyCommentsShow(pu, u)
var bit string
if !expects {
bit = " not"
val = !val
}
expect(t, val, fmt.Sprintf("%s should%s be able to see comments on level %d", msg, bit, level))
}
// 0 = default, 1 = public, 2 = registered, 3 = friends, 4 = self, 5 = disabled
msg = "guest users"
test(true, 0)
test(true, 1)
test(false, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u = c.BlankUser()
msg = "blank users"
test(true, 0)
test(true, 1)
test(false, 2)
//test(false,3)
test(false, 4)
test(false, 5)
u.Loggedin = true
msg = "registered users"
test(true, 0)
test(true, 1)
test(true, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u.IsBanned = true
msg = "banned users"
test(true, 0)
test(true, 1)
test(true, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u.IsBanned = false
u.IsMod = true
msg = "mods"
test(true, 0)
test(true, 1)
test(true, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u.IsMod = false
u.IsSuperMod = true
msg = "super mods"
test(true, 0)
test(true, 1)
test(true, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u.IsSuperMod = false
u.IsAdmin = true
msg = "admins"
test(true, 0)
test(true, 1)
test(true, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u.IsAdmin = false
u.IsSuperAdmin = true
msg = "super admins"
test(true, 0)
test(true, 1)
test(true, 2)
test(false, 3)
test(false, 4)
test(false, 5)
u.IsSuperAdmin = false
u.ID = 1
test(true, 0)
test(true, 1)
test(true, 2)
test(true, 3)
test(true, 4)
test(false, 5)
}
type METri struct {
Name string // Optional, this is here for tests involving invisible characters so we know what's going in
Msg string

View File

@ -113,46 +113,14 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user *c.User, h *c.Head
canMessage := (!blockedInv && user.Perms.UseConvos) || (!blockedInv && puser.IsSuperMod && user.Perms.UseConvosOnlyWithMod) || user.IsSuperMod
canComment := !blockedInv && user.Perms.CreateProfileReply
showComments := profileCommentsShow(puser, user)
showComments := c.PrivacyCommentsShow(puser, user)
if !showComments {
canComment = false
}
if !profileAllowMessage(puser, user) {
if !c.PrivacyAllowMessage(puser, user) {
canMessage = false
}
ppage := c.ProfilePage{h, reList, *puser, currentScore, nextScore, blocked, canMessage, canComment, showComments}
return renderTemplate("profile", w, r, h, ppage)
}
func profileAllowMessage(pu, u *c.User) (canMsg bool) {
switch pu.Privacy.AllowMessage {
case 4: // Unused
canMsg = false
case 3: // mods / self
canMsg = u.IsSuperMod
//case 2: // friends
case 1: // registered
canMsg = true
default: // 0
canMsg = true
}
return canMsg
}
func profileCommentsShow(pu, u *c.User) (showComments bool) {
switch pu.Privacy.ShowComments {
case 5: // Unused
showComments = false
case 4: // Self
showComments = u.ID == pu.ID
//case 3: // friends
case 2: // registered
showComments = u.Loggedin
case 1: // public
showComments = true
default: // 0
showComments = true
}
return showComments
}

View File

@ -6,51 +6,51 @@ import (
"strconv"
c "github.com/Azareal/Gosora/common"
"github.com/Azareal/Gosora/common/counters"
co "github.com/Azareal/Gosora/common/counters"
)
func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, user *c.User) c.RouteError {
if !user.Perms.CreateProfileReply {
return c.NoPermissions(w, r, user)
func ProfileReplyCreateSubmit(w http.ResponseWriter, r *http.Request, u *c.User) c.RouteError {
if !u.Perms.CreateProfileReply {
return c.NoPermissions(w, r, u)
}
uid, err := strconv.Atoi(r.PostFormValue("uid"))
if err != nil {
return c.LocalError("Invalid UID", w, r, user)
return c.LocalError("Invalid UID", w, r, u)
}
profileOwner, err := c.Users.Get(uid)
if err == sql.ErrNoRows {
return c.LocalError("The profile you're trying to post on doesn't exist.", w, r, user)
return c.LocalError("The profile you're trying to post on doesn't exist.", w, r, u)
} else if err != nil {
return c.InternalError(err, w, r)
}
blocked, err := c.UserBlocks.IsBlockedBy(profileOwner.ID, user.ID)
blocked, err := c.UserBlocks.IsBlockedBy(profileOwner.ID, u.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 || !profileCommentsShow(profileOwner, user)) && !user.IsSuperMod {
return c.LocalError("You don't have permission to send messages to one of these users.", w, r, user)
if (blocked || !c.PrivacyCommentsShow(profileOwner, u)) && !u.IsSuperMod {
return c.LocalError("You don't have permission to send messages to one of these users.", w, r, u)
}
content := c.PreparseMessage(r.PostFormValue("content"))
if len(content) == 0 {
return c.LocalError("You can't make a blank post", w, r, user)
return c.LocalError("You can't make a blank post", w, r, u)
}
// TODO: Fully parse the post and store it in the parsed column
prid, err := c.Prstore.Create(profileOwner.ID, content, user.ID, user.GetIP())
prid, err := c.Prstore.Create(profileOwner.ID, content, u.ID, u.GetIP())
if err != nil {
return c.InternalError(err, w, r)
}
// ! Be careful about leaking per-route permission state with user ptr
alert := c.Alert{ActorID: user.ID, TargetUserID: profileOwner.ID, Event: "reply", ElementType: "user", ElementID: profileOwner.ID, Actor: user, Extra: strconv.Itoa(prid)}
alert := c.Alert{ActorID: u.ID, TargetUserID: profileOwner.ID, Event: "reply", ElementType: "user", ElementID: profileOwner.ID, Actor: u, Extra: strconv.Itoa(prid)}
err = c.AddActivityAndNotifyTarget(alert)
if err != nil {
return c.InternalError(err, w, r)
}
counters.PostCounter.Bump()
co.PostCounter.Bump()
http.Redirect(w, r, "/user/"+strconv.Itoa(uid), http.StatusSeeOther)
return nil
}
@ -91,7 +91,7 @@ func ProfileReplyEditSubmit(w http.ResponseWriter, r *http.Request, u *c.User, s
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 || !profileCommentsShow(profileOwner, u)) && !u.IsSuperMod {
if (blocked || !c.PrivacyCommentsShow(profileOwner, u)) && !u.IsSuperMod {
return c.NoPermissionsJSQ(w, r, u, js)
}
@ -108,7 +108,6 @@ func ProfileReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, u *c.User,
if err != nil {
return c.LocalErrorJSQ("The provided Reply ID is not a valid number.", w, r, u, js)
}
reply, err := c.Prstore.Get(rid)
if err == sql.ErrNoRows {
return c.PreErrorJSQ("The target reply doesn't exist.", w, r, js)