diff --git a/app/peppy/user_x.go b/app/peppy/user_x.go index b7dac1e..cfd470d 100644 --- a/app/peppy/user_x.go +++ b/app/peppy/user_x.go @@ -31,7 +31,7 @@ func GetUserBest(c *gin.Context, db *sql.DB) { func getUserX(c *gin.Context, db *sql.DB, orderBy string, limit int) { whereClause, p := genUser(c, db) query := fmt.Sprintf( - `SELECT + `SELECT beatmaps.beatmap_id, scores.score, scores.max_combo, scores.300_count, scores.100_count, scores.50_count, scores.gekis_count, scores.katus_count, scores.misses_count, @@ -40,7 +40,7 @@ func getUserX(c *gin.Context, db *sql.DB, orderBy string, limit int) { FROM scores LEFT JOIN beatmaps ON beatmaps.beatmap_md5 = scores.beatmap_md5 LEFT JOIN users ON scores.userid = users.id - WHERE %s AND scores.play_mode = ? AND users.allowed = '1' + WHERE %s AND scores.play_mode = ? AND users.privileges & 1 > 0 %s LIMIT %d`, whereClause, orderBy, limit, ) diff --git a/app/v1/friend.go b/app/v1/friend.go index 96be9a8..ee9d0a4 100644 --- a/app/v1/friend.go +++ b/app/v1/friend.go @@ -42,9 +42,9 @@ func FriendsGET(md common.MethodData) common.CodeMessager { // Yes. myFriendsQuery := ` -SELECT +SELECT users.id, users.username, users.register_datetime, users.rank, users.latest_activity, - + users_stats.username_aka, users_stats.country, users_stats.show_country FROM users_relationships @@ -169,7 +169,7 @@ 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.allowed='1')", u).Scan(&r) + err := md.DB.QueryRow("SELECT EXISTS(SELECT 1 FROM users WHERE id = ? AND users.privileges & 1 > 0)", u).Scan(&r) if err != nil && err != sql.ErrNoRows { md.Err(err) } diff --git a/app/v1/leaderboard.go b/app/v1/leaderboard.go index e1e8a17..093658f 100644 --- a/app/v1/leaderboard.go +++ b/app/v1/leaderboard.go @@ -22,10 +22,10 @@ type leaderboardResponse struct { const lbUserQuery = ` SELECT users.id, users.username, users.register_datetime, users.rank, users.latest_activity, - + users_stats.username_aka, users_stats.country, users_stats.show_country, users_stats.play_style, users_stats.favourite_mode, - + users_stats.ranked_score_%[1]s, users_stats.total_score_%[1]s, users_stats.playcount_%[1]s, users_stats.replays_watched_%[1]s, users_stats.total_hits_%[1]s, users_stats.avg_accuracy_%[1]s, users_stats.pp_%[1]s, leaderboard_%[1]s.position as %[1]s_position @@ -37,7 +37,7 @@ 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.C.Query("mode")) - query := fmt.Sprintf(lbUserQuery, m, `WHERE users.allowed = '1' ORDER BY leaderboard_`+m+`.position `+ + query := fmt.Sprintf(lbUserQuery, m, `WHERE users.privileges & 1 > 0 ORDER BY leaderboard_`+m+`.position `+ common.Paginate(md.C.Query("p"), md.C.Query("l"), 100)) rows, err := md.DB.Query(query) if err != nil { diff --git a/app/v1/manage_user.go b/app/v1/manage_user.go index b80aa86..eb54b6e 100644 --- a/app/v1/manage_user.go +++ b/app/v1/manage_user.go @@ -21,10 +21,21 @@ 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 + } if data.Allowed == 0 { banDatetime = time.Now().Unix() + newPrivileges = privileges &^(common.UserPrivilegeNormal | common.UserPrivilegePublic) + } else { + banDatetime = 0 + newPrivileges = privileges | (common.UserPrivilegeNormal | common.UserPrivilegePublic) } - _, err := md.DB.Exec("UPDATE users SET allowed = ?, ban_datetime = ? WHERE id = ?", data.Allowed, banDatetime, data.UserID) + _, err = md.DB.Exec("UPDATE users SET privileges = ?, ban_datetime = ? WHERE id = ?", newPrivileges, banDatetime, data.UserID) if err != nil { md.Err(err) return Err500 diff --git a/app/v1/token.go b/app/v1/token.go index dedf304..6d53b57 100644 --- a/app/v1/token.go +++ b/app/v1/token.go @@ -50,7 +50,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager { } var q *sql.Row - const base = "SELECT id, username, rank, password_md5, password_version, allowed FROM users " + const base = "SELECT id, username, rank, password_md5, password_version, privileges FROM users " if data.UserID != 0 { q = md.DB.QueryRow(base+"WHERE id = ? LIMIT 1", data.UserID) } else { @@ -61,10 +61,10 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager { rank int pw string pwVersion int - allowed int + privileges int ) - err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &allowed) + err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &privileges) switch { case err == sql.ErrNoRows: return common.SimpleResponse(404, "No user with that username/id was found.") @@ -88,7 +88,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager { md.Err(err) return Err500 } - if allowed == 0 { + if (privileges & 0) == 0 { r.Code = 200 r.Message = "That user is banned." r.Banned = true diff --git a/app/v1/user.go b/app/v1/user.go index 81c068d..d338fcc 100644 --- a/app/v1/user.go +++ b/app/v1/user.go @@ -35,7 +35,7 @@ SELECT users.id, users.username, register_datetime, rank, FROM users LEFT JOIN users_stats ON users.id=users_stats.id -WHERE ` + whereClause + ` AND users.allowed='1' +WHERE ` + whereClause + ` AND users.privileges & 1 > 0 LIMIT 1` return userPuts(md, md.DB.QueryRow(query, param)) } @@ -110,10 +110,10 @@ type whatIDResponse struct { func UserWhatsTheIDGET(md common.MethodData) common.CodeMessager { var ( r whatIDResponse - allowed int + privileges int ) - err := md.DB.QueryRow("SELECT id, allowed FROM users WHERE username = ? LIMIT 1", md.C.Query("name")).Scan(&r.ID, &allowed) - if err != nil || (allowed != 1 && !md.User.Privileges.HasPrivilegeViewUserAdvanced()) { + err := md.DB.QueryRow("SELECT id, privileges FROM users WHERE username = ? LIMIT 1", md.C.Query("name")).Scan(&r.ID, &privileges) + if err != nil || ( (privileges & common.UserPrivilegePublic) == 0 && !md.User.Privileges.HasPrivilegeViewUserAdvanced()) { return common.SimpleResponse(404, "That user could not be found!") } r.Code = 200 @@ -154,14 +154,14 @@ func UserFullGET(md common.MethodData) common.CodeMessager { query := ` SELECT users.id, users.username, users.register_datetime, users.rank, users.latest_activity, - + users_stats.username_aka, users_stats.badges_shown, users_stats.country, users_stats.show_country, users_stats.play_style, users_stats.favourite_mode, - + users_stats.ranked_score_std, users_stats.total_score_std, users_stats.playcount_std, users_stats.replays_watched_std, users_stats.total_hits_std, users_stats.avg_accuracy_std, users_stats.pp_std, leaderboard_std.position as std_position, - + users_stats.ranked_score_taiko, users_stats.total_score_taiko, users_stats.playcount_taiko, users_stats.replays_watched_taiko, users_stats.total_hits_taiko, users_stats.avg_accuracy_taiko, users_stats.pp_taiko, leaderboard_taiko.position as taiko_position, @@ -185,7 +185,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.allowed = '1' +WHERE ` + whereClause + ` AND users.privileges & 1 > 0 LIMIT 1 ` // Fuck. @@ -304,7 +304,7 @@ 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 allowed = '1' LIMIT 25", name) + rows, err := md.DB.Query("SELECT users.id, users.username FROM users WHERE username LIKE ? AND privileges & 1 > 0 LIMIT 25", name) if err != nil { md.Err(err) return Err500 diff --git a/app/v1/user_scores.go b/app/v1/user_scores.go index 0843eee..b853bea 100644 --- a/app/v1/user_scores.go +++ b/app/v1/user_scores.go @@ -46,7 +46,7 @@ SELECT scores.gekis_count, scores.katus_count, scores.misses_count, scores.time, scores.play_mode, scores.accuracy, scores.pp, scores.completed, - + beatmaps.beatmap_id, beatmaps.beatmapset_id, beatmaps.beatmap_md5, beatmaps.song_name, beatmaps.ar, beatmaps.od, beatmaps.difficulty, beatmaps.max_combo, beatmaps.hit_length, beatmaps.ranked, @@ -70,10 +70,10 @@ func UserScoresBestGET(md common.MethodData) common.CodeMessager { } return scoresPuts(md, fmt.Sprintf( `WHERE - scores.completed = '3' + scores.completed = '3' AND %s %s - AND users.allowed = '1' + AND users.privileges & 1 > 0 ORDER BY scores.pp DESC, scores.score DESC %s`, wc, mc, common.Paginate(md.C.Query("p"), md.C.Query("l"), 100), ), param) @@ -89,7 +89,7 @@ func UserScoresRecentGET(md common.MethodData) common.CodeMessager { `WHERE %s %s - AND users.allowed = '1' + AND users.privileges & 1 > 0 ORDER BY scores.time DESC %s`, wc, genModeClause(md), common.Paginate(md.C.Query("p"), md.C.Query("l"), 100), ), param) diff --git a/common/user_privileges.go b/common/user_privileges.go new file mode 100644 index 0000000..f8d8260 --- /dev/null +++ b/common/user_privileges.go @@ -0,0 +1,24 @@ +package common + +const ( + UserPrivilegePublic = 1 << iota + UserPrivilegeNormal + UserPrivilegeDonor + AdminPrivilegeAccessRAP + AdminPrivilegeManageUsers + AdminPrivilegeBanUsers + AdminPrivilegeSilenceUsers + AdminPrivilegeWipeUsers + AdminPrivilegeManageBeatmap + AdminPrivilegeManageServer + AdminPrivilegeManageSetting + AdminPrivilegeManageBetaKey + AdminPrivilegeManageReport + AdminPrivilegeManageDocs + AdminPrivilegeManageBadges + AdminPrivilegeViewRAPLogs + AdminPrivilegeManagePrivilege + AdminPrivilegeSendAlerts + AdminPrivilegeChatMod + AdminPrivilegeKickUsers +)