Allow users with AdminManageUsers to see banned users
Also: - General code refactoring - Allow banned/restricted users to see their scores etc - common.MethodData now contains UserPrivileges - UserPrivileges have now their own type - Implement md.HasQuery, to know if there's a GET querystring parameter or not
This commit is contained in:
@@ -71,7 +71,7 @@ type blogPostContent struct {
|
||||
// BlogPostsContentGET retrieves the content of a specific blog post.
|
||||
func BlogPostsContentGET(md common.MethodData) common.CodeMessager {
|
||||
field := "markdown"
|
||||
if _, present := md.C.GetQuery("html"); present {
|
||||
if md.HasQuery("html") {
|
||||
field = "html"
|
||||
}
|
||||
var (
|
||||
|
@@ -21,7 +21,7 @@ type docResponse struct {
|
||||
// DocGET retrieves a list of documentation files.
|
||||
func DocGET(md common.MethodData) common.CodeMessager {
|
||||
var wc string
|
||||
if !md.User.Privileges.HasPrivilegeBlog() || md.Query("public") == "1" {
|
||||
if md.User.TokenPrivileges&common.PrivilegeBlog == 0 || md.Query("public") == "1" {
|
||||
wc = "WHERE public = '1'"
|
||||
}
|
||||
rows, err := md.DB.Query("SELECT id, doc_name, public, is_rule FROM docs " + wc)
|
||||
@@ -55,7 +55,7 @@ func DocContentGET(md common.MethodData) common.CodeMessager {
|
||||
return common.SimpleResponse(404, "Documentation file not found!")
|
||||
}
|
||||
var wc string
|
||||
if !md.User.Privileges.HasPrivilegeBlog() || md.Query("public") == "1" {
|
||||
if md.User.TokenPrivileges&common.PrivilegeBlog == 0 || md.Query("public") == "1" {
|
||||
wc = "AND public = '1'"
|
||||
}
|
||||
var r docContentResponse
|
||||
|
@@ -157,7 +157,8 @@ func addFriend(md common.MethodData, u int) common.CodeMessager {
|
||||
|
||||
// userExists makes sure an user exists.
|
||||
func userExists(md common.MethodData, u int) (r bool) {
|
||||
err := md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users WHERE id = ? AND users.privileges & 1 > 0)", u).Scan(&r)
|
||||
err := md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users WHERE id = ? AND "+
|
||||
md.User.OnlyUserPublic(true)+")", u).Scan(&r)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
md.Err(err)
|
||||
}
|
||||
|
@@ -36,8 +36,10 @@ INNER JOIN users_stats ON users_stats.id = leaderboard_%[1]s.user
|
||||
// LeaderboardGET gets the leaderboard.
|
||||
func LeaderboardGET(md common.MethodData) common.CodeMessager {
|
||||
m := getMode(md.Query("mode"))
|
||||
query := fmt.Sprintf(lbUserQuery, m, `WHERE users.privileges & 1 > 0 ORDER BY leaderboard_`+m+`.position `+
|
||||
common.Paginate(md.Query("p"), md.Query("l"), 100))
|
||||
// Admins may not want to see banned users on the leaderboard.
|
||||
// This is the default setting. In case they do, they have to activate see_everything.
|
||||
query := fmt.Sprintf(lbUserQuery, m, `WHERE `+md.User.OnlyUserPublic(md.HasQuery("see_everything"))+
|
||||
` ORDER BY leaderboard_`+m+`.position `+common.Paginate(md.Query("p"), md.Query("l"), 100))
|
||||
rows, err := md.DB.Query(query)
|
||||
if err != nil {
|
||||
md.Err(err)
|
||||
|
@@ -21,21 +21,15 @@ func UserManageSetAllowedPOST(md common.MethodData) common.CodeMessager {
|
||||
return common.SimpleResponse(400, "Allowed status must be between 0 and 2")
|
||||
}
|
||||
var banDatetime int64
|
||||
var privileges int32
|
||||
var newPrivileges int32
|
||||
err := md.DB.QueryRow("SELECT privileges FROM users WHERE id = ?", data.UserID).Scan(&privileges)
|
||||
if err != nil {
|
||||
md.Err(err)
|
||||
return Err500
|
||||
}
|
||||
var privsSet string
|
||||
if data.Allowed == 0 {
|
||||
banDatetime = time.Now().Unix()
|
||||
newPrivileges = privileges &^ (common.UserPrivilegeNormal | common.UserPrivilegePublic)
|
||||
privsSet = "privileges = (privileges & ~3)"
|
||||
} else {
|
||||
banDatetime = 0
|
||||
newPrivileges = privileges | (common.UserPrivilegeNormal | common.UserPrivilegePublic)
|
||||
privsSet = "privileges = (privileges | 3)"
|
||||
}
|
||||
_, err = md.DB.Exec("UPDATE users SET privileges = ?, ban_datetime = ? WHERE id = ?", newPrivileges, banDatetime, data.UserID)
|
||||
_, err := md.DB.Exec("UPDATE users SET "+privsSet+", ban_datetime = ? WHERE id = ?", banDatetime, data.UserID)
|
||||
if err != nil {
|
||||
md.Err(err)
|
||||
return Err500
|
||||
|
@@ -87,8 +87,8 @@ func surpriseMe() string {
|
||||
|
||||
type pingResponse struct {
|
||||
common.ResponseBase
|
||||
ID int `json:"user_id"`
|
||||
Privileges int `json:"privileges"`
|
||||
ID int `json:"user_id"`
|
||||
Privileges uint64 `json:"privileges"`
|
||||
}
|
||||
|
||||
// PingGET is a message to check with the API that we are logged in, and know what are our privileges.
|
||||
@@ -103,7 +103,7 @@ func PingGET(md common.MethodData) common.CodeMessager {
|
||||
}
|
||||
|
||||
r.ID = md.ID()
|
||||
r.Privileges = int(md.User.Privileges)
|
||||
r.Privileges = uint64(md.User.TokenPrivileges)
|
||||
|
||||
return r
|
||||
}
|
||||
|
@@ -1,43 +0,0 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"git.zxq.co/ripple/rippleapi/common"
|
||||
)
|
||||
|
||||
type privilegesData struct {
|
||||
common.ResponseBase
|
||||
Read bool `json:"read"`
|
||||
ReadConfidential bool `json:"read_confidential"`
|
||||
Write bool `json:"write"`
|
||||
ManageBadges bool `json:"manage_badges"`
|
||||
BetaKeys bool `json:"beta_keys"`
|
||||
ManageSettings bool `json:"manage_settings"`
|
||||
ViewUserAdvanced bool `json:"view_user_advanced"`
|
||||
ManageUser bool `json:"manage_user"`
|
||||
ManageRoles bool `json:"manage_roles"`
|
||||
ManageAPIKeys bool `json:"manage_api_keys"`
|
||||
Blog bool `json:"blog"`
|
||||
APIMeta bool `json:"api_meta"`
|
||||
Beatmap bool `json:"beatmap"`
|
||||
}
|
||||
|
||||
// PrivilegesGET returns an explaination for the privileges, telling the client what they can do with this token.
|
||||
func PrivilegesGET(md common.MethodData) common.CodeMessager {
|
||||
r := privilegesData{}
|
||||
r.Code = 200
|
||||
// This code sucks.
|
||||
r.Read = true
|
||||
r.ReadConfidential = md.User.Privileges.HasPrivilegeReadConfidential()
|
||||
r.Write = md.User.Privileges.HasPrivilegeWrite()
|
||||
r.ManageBadges = md.User.Privileges.HasPrivilegeManageBadges()
|
||||
r.BetaKeys = md.User.Privileges.HasPrivilegeBetaKeys()
|
||||
r.ManageSettings = md.User.Privileges.HasPrivilegeManageSettings()
|
||||
r.ViewUserAdvanced = md.User.Privileges.HasPrivilegeViewUserAdvanced()
|
||||
r.ManageUser = md.User.Privileges.HasPrivilegeManageUser()
|
||||
r.ManageRoles = md.User.Privileges.HasPrivilegeManageRoles()
|
||||
r.ManageAPIKeys = md.User.Privileges.HasPrivilegeManageAPIKeys()
|
||||
r.Blog = md.User.Privileges.HasPrivilegeBlog()
|
||||
r.APIMeta = md.User.Privileges.HasPrivilegeAPIMeta()
|
||||
r.Beatmap = md.User.Privileges.HasPrivilegeBeatmap()
|
||||
return r
|
||||
}
|
@@ -83,7 +83,8 @@ SELECT
|
||||
FROM scores
|
||||
INNER JOIN users ON users.id = scores.userid
|
||||
INNER JOIN users_stats ON users_stats.id = scores.userid
|
||||
WHERE scores.beatmap_md5 = ? AND scores.completed = '3' AND users.privileges & 1 > 0 `+genModeClause(md)+`
|
||||
WHERE scores.beatmap_md5 = ? AND scores.completed = '3' AND `+md.User.OnlyUserPublic(true)+
|
||||
` `+genModeClause(md)+`
|
||||
`+sort+common.Paginate(md.Query("p"), md.Query("l"), 100), beatmapMD5)
|
||||
if err != nil {
|
||||
md.Err(err)
|
||||
|
@@ -60,13 +60,13 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
|
||||
}
|
||||
|
||||
var (
|
||||
rank int
|
||||
pw string
|
||||
pwVersion int
|
||||
privileges int
|
||||
rank int
|
||||
pw string
|
||||
pwVersion int
|
||||
privilegesRaw uint64
|
||||
)
|
||||
|
||||
err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &privileges)
|
||||
err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &privilegesRaw)
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
return common.SimpleResponse(404, "No user with that username/id was found.")
|
||||
@@ -74,6 +74,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
|
||||
md.Err(err)
|
||||
return Err500
|
||||
}
|
||||
privileges := common.UserPrivileges(privilegesRaw)
|
||||
|
||||
if nFailedAttempts(r.ID) > 20 {
|
||||
return common.SimpleResponse(429, "You've made too many login attempts. Try again later.")
|
||||
@@ -227,13 +228,18 @@ LEFT JOIN users ON users.id = tokens.user
|
||||
}
|
||||
for rows.Next() {
|
||||
var (
|
||||
id int
|
||||
privsRaw uint64
|
||||
privs common.Privileges
|
||||
newPrivs common.Privileges
|
||||
privileges int
|
||||
id int
|
||||
privsRaw uint64
|
||||
privs common.Privileges
|
||||
newPrivs common.Privileges
|
||||
privilegesRaw uint64
|
||||
)
|
||||
rows.Scan(&id, &privsRaw, &privileges)
|
||||
err := rows.Scan(&id, &privsRaw, &privilegesRaw)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
privileges := common.UserPrivileges(privilegesRaw)
|
||||
privs = common.Privileges(privsRaw)
|
||||
newPrivs = privs.CanOnly(privileges)
|
||||
if newPrivs != privs {
|
||||
|
@@ -36,7 +36,7 @@ SELECT users.id, users.username, register_datetime, privileges,
|
||||
FROM users
|
||||
LEFT JOIN users_stats
|
||||
ON users.id=users_stats.id
|
||||
WHERE ` + whereClause + ` AND users.privileges & 1 > 0
|
||||
WHERE ` + whereClause + ` AND ` + md.User.OnlyUserPublic(true) + `
|
||||
LIMIT 1`
|
||||
return userPuts(md, md.DB.QueryRowx(query, param))
|
||||
}
|
||||
@@ -92,10 +92,11 @@ type whatIDResponse struct {
|
||||
func UserWhatsTheIDGET(md common.MethodData) common.CodeMessager {
|
||||
var (
|
||||
r whatIDResponse
|
||||
privileges int
|
||||
privileges uint64
|
||||
)
|
||||
err := md.DB.QueryRow("SELECT id, privileges FROM users WHERE username = ? LIMIT 1", md.Query("name")).Scan(&r.ID, &privileges)
|
||||
if err != nil || ((privileges&common.UserPrivilegePublic) == 0 && !md.User.Privileges.HasPrivilegeViewUserAdvanced()) {
|
||||
if err != nil || ((privileges&uint64(common.UserPrivilegePublic)) == 0 &&
|
||||
(md.User.UserPrivileges&common.AdminPrivilegeManageUsers == 0)) {
|
||||
return common.SimpleResponse(404, "That user could not be found!")
|
||||
}
|
||||
r.Code = 200
|
||||
@@ -167,7 +168,7 @@ LEFT JOIN leaderboard_ctb
|
||||
ON users.id=leaderboard_ctb.user
|
||||
LEFT JOIN leaderboard_mania
|
||||
ON users.id=leaderboard_mania.user
|
||||
WHERE ` + whereClause + ` AND users.privileges & 1 > 0
|
||||
WHERE ` + whereClause + ` AND ` + md.User.OnlyUserPublic(true) + `
|
||||
LIMIT 1
|
||||
`
|
||||
// Fuck.
|
||||
@@ -278,7 +279,8 @@ func UserLookupGET(md common.MethodData) common.CodeMessager {
|
||||
return common.SimpleResponse(400, "please provide an username to start searching")
|
||||
}
|
||||
name = "%" + name + "%"
|
||||
rows, err := md.DB.Query("SELECT users.id, users.username FROM users WHERE username LIKE ? AND privileges & 1 > 0 LIMIT 25", name)
|
||||
rows, err := md.DB.Query("SELECT users.id, users.username FROM users WHERE username LIKE ? AND "+
|
||||
md.User.OnlyUserPublic(true)+" LIMIT 25", name)
|
||||
if err != nil {
|
||||
md.Err(err)
|
||||
return Err500
|
||||
|
@@ -52,7 +52,7 @@ func UserScoresBestGET(md common.MethodData) common.CodeMessager {
|
||||
scores.completed = '3'
|
||||
AND %s
|
||||
%s
|
||||
AND users.privileges & 1 > 0
|
||||
AND `+md.User.OnlyUserPublic(true)+`
|
||||
ORDER BY scores.pp DESC, scores.score DESC %s`,
|
||||
wc, mc, common.Paginate(md.Query("p"), md.Query("l"), 100),
|
||||
), param)
|
||||
@@ -68,7 +68,7 @@ func UserScoresRecentGET(md common.MethodData) common.CodeMessager {
|
||||
`WHERE
|
||||
%s
|
||||
%s
|
||||
AND users.privileges & 1 > 0
|
||||
AND `+md.User.OnlyUserPublic(true)+`
|
||||
ORDER BY scores.time DESC %s`,
|
||||
wc, genModeClause(md), common.Paginate(md.Query("p"), md.Query("l"), 100),
|
||||
), param)
|
||||
|
Reference in New Issue
Block a user