Finish up with new ranks and stuff on the API

This commit is contained in:
Howl 2016-07-04 00:06:23 +02:00
parent 39f6b2bbcf
commit fcdd042d6c
7 changed files with 46 additions and 44 deletions

View File

@ -43,7 +43,7 @@ func FriendsGET(md common.MethodData) common.CodeMessager {
// Yes. // Yes.
myFriendsQuery := ` myFriendsQuery := `
SELECT SELECT
users.id, users.username, users.register_datetime, users.rank, users.latest_activity, users.id, users.username, users.register_datetime, users.privileges, users.latest_activity,
users_stats.username_aka, users_stats.username_aka,
users_stats.country, users_stats.show_country users_stats.country, users_stats.show_country
@ -90,7 +90,7 @@ func friendPuts(md common.MethodData, row *sql.Rows) (user friendData) {
registeredOn := int64(0) registeredOn := int64(0)
latestActivity := int64(0) latestActivity := int64(0)
var showcountry bool var showcountry bool
err = row.Scan(&user.ID, &user.Username, &registeredOn, &user.Rank, &latestActivity, &user.UsernameAKA, &user.Country, &showcountry) err = row.Scan(&user.ID, &user.Username, &registeredOn, &user.Privileges, &latestActivity, &user.UsernameAKA, &user.Country, &showcountry)
if err != nil { if err != nil {
md.Err(err) md.Err(err)
return return

View File

@ -21,7 +21,7 @@ type leaderboardResponse struct {
const lbUserQuery = ` const lbUserQuery = `
SELECT SELECT
users.id, users.username, users.register_datetime, users.rank, users.latest_activity, users.id, users.username, users.register_datetime, users.privileges, users.latest_activity,
users_stats.username_aka, users_stats.country, users_stats.show_country, users_stats.username_aka, users_stats.country, users_stats.show_country,
users_stats.play_style, users_stats.favourite_mode, users_stats.play_style, users_stats.favourite_mode,
@ -53,7 +53,7 @@ func LeaderboardGET(md common.MethodData) common.CodeMessager {
showCountry bool showCountry bool
) )
err := rows.Scan( err := rows.Scan(
&u.ID, &u.Username, &register, &u.Rank, &latestActivity, &u.ID, &u.Username, &register, &u.Privileges, &latestActivity,
&u.UsernameAKA, &u.Country, &showCountry, &u.UsernameAKA, &u.Country, &showCountry,
&u.PlayStyle, &u.FavouriteMode, &u.PlayStyle, &u.FavouriteMode,

View File

@ -30,7 +30,7 @@ func UserManageSetAllowedPOST(md common.MethodData) common.CodeMessager {
} }
if data.Allowed == 0 { if data.Allowed == 0 {
banDatetime = time.Now().Unix() banDatetime = time.Now().Unix()
newPrivileges = privileges &^(common.UserPrivilegeNormal | common.UserPrivilegePublic) newPrivileges = privileges &^ (common.UserPrivilegeNormal | common.UserPrivilegePublic)
} else { } else {
banDatetime = 0 banDatetime = 0
newPrivileges = privileges | (common.UserPrivilegeNormal | common.UserPrivilegePublic) newPrivileges = privileges | (common.UserPrivilegeNormal | common.UserPrivilegePublic)
@ -42,7 +42,7 @@ func UserManageSetAllowedPOST(md common.MethodData) common.CodeMessager {
} }
go fixPrivileges(data.UserID, md.DB) go fixPrivileges(data.UserID, md.DB)
query := ` query := `
SELECT users.id, users.username, register_datetime, rank, SELECT users.id, users.username, register_datetime, privileges,
latest_activity, users_stats.username_aka, latest_activity, users_stats.username_aka,
users_stats.country, users_stats.show_country users_stats.country, users_stats.show_country
FROM users FROM users

View File

@ -50,7 +50,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
} }
var q *sql.Row var q *sql.Row
const base = "SELECT id, username, rank, password_md5, password_version, privileges FROM users " const base = "SELECT id, username, privileges, password_md5, password_version, privileges FROM users "
if data.UserID != 0 { if data.UserID != 0 {
q = md.DB.QueryRow(base+"WHERE id = ? LIMIT 1", data.UserID) q = md.DB.QueryRow(base+"WHERE id = ? LIMIT 1", data.UserID)
} else { } else {
@ -58,10 +58,10 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
} }
var ( var (
rank int rank int
pw string pw string
pwVersion int pwVersion int
privileges int privileges int
) )
err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &privileges) err = q.Scan(&r.ID, &r.Username, &rank, &pw, &pwVersion, &privileges)
@ -88,13 +88,14 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
md.Err(err) md.Err(err)
return Err500 return Err500
} }
if (privileges & 0) == 0 { const want = (common.UserPrivilegePublic | common.UserPrivilegeNormal)
if (privileges & want) != want {
r.Code = 200 r.Code = 200
r.Message = "That user is banned." r.Message = "That user is banned."
r.Banned = true r.Banned = true
return r return r
} }
r.Privileges = int(common.Privileges(data.Privileges).CanOnly(rank)) r.Privileges = int(common.Privileges(data.Privileges).CanOnly(privileges))
var ( var (
tokenStr string tokenStr string
@ -104,7 +105,7 @@ func TokenNewPOST(md common.MethodData) common.CodeMessager {
tokenStr = common.RandomString(32) tokenStr = common.RandomString(32)
tokenMD5 = fmt.Sprintf("%x", md5.Sum([]byte(tokenStr))) tokenMD5 = fmt.Sprintf("%x", md5.Sum([]byte(tokenStr)))
r.Token = tokenStr r.Token = tokenStr
id := 0 var id int
err := md.DB.QueryRow("SELECT id FROM tokens WHERE token=? LIMIT 1", tokenMD5).Scan(&id) err := md.DB.QueryRow("SELECT id FROM tokens WHERE token=? LIMIT 1", tokenMD5).Scan(&id)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
@ -210,7 +211,7 @@ func fixPrivileges(user int, db *sql.DB) {
} }
rows, err := db.Query(` rows, err := db.Query(`
SELECT SELECT
tokens.id, tokens.privileges, users.rank tokens.id, tokens.privileges, users.privileges
FROM tokens FROM tokens
LEFT JOIN users ON users.id = tokens.user LEFT JOIN users ON users.id = tokens.user
`+wc, params...) `+wc, params...)
@ -221,15 +222,15 @@ LEFT JOIN users ON users.id = tokens.user
} }
for rows.Next() { for rows.Next() {
var ( var (
id int id int
privsRaw uint64 privsRaw uint64
privs common.Privileges privs common.Privileges
newPrivs common.Privileges newPrivs common.Privileges
rank int privileges int
) )
rows.Scan(&id, &privsRaw, &rank) rows.Scan(&id, &privsRaw, &privileges)
privs = common.Privileges(privsRaw) privs = common.Privileges(privsRaw)
newPrivs = privs.CanOnly(rank) newPrivs = privs.CanOnly(privileges)
if newPrivs != privs { if newPrivs != privs {
_, err := db.Exec("UPDATE tokens SET privileges = ? WHERE id = ? LIMIT 1", uint64(newPrivs), id) _, err := db.Exec("UPDATE tokens SET privileges = ? WHERE id = ? LIMIT 1", uint64(newPrivs), id)
if err != nil { if err != nil {

View File

@ -16,7 +16,7 @@ type userData struct {
Username string `json:"username"` Username string `json:"username"`
UsernameAKA string `json:"username_aka"` UsernameAKA string `json:"username_aka"`
RegisteredOn time.Time `json:"registered_on"` RegisteredOn time.Time `json:"registered_on"`
Rank int `json:"rank"` Privileges uint64 `json:"rank"`
LatestActivity time.Time `json:"latest_activity"` LatestActivity time.Time `json:"latest_activity"`
Country string `json:"country"` Country string `json:"country"`
} }
@ -29,7 +29,7 @@ func UsersGET(md common.MethodData) common.CodeMessager {
} }
query := ` query := `
SELECT users.id, users.username, register_datetime, rank, SELECT users.id, users.username, register_datetime, privileges,
latest_activity, users_stats.username_aka, latest_activity, users_stats.username_aka,
users_stats.country, users_stats.show_country users_stats.country, users_stats.show_country
FROM users FROM users
@ -54,7 +54,7 @@ func userPuts(md common.MethodData, row *sql.Row) common.CodeMessager {
latestActivity int64 latestActivity int64
showCountry bool showCountry bool
) )
err = row.Scan(&user.ID, &user.Username, &registeredOn, &user.Rank, &latestActivity, &user.UsernameAKA, &user.Country, &showCountry) err = row.Scan(&user.ID, &user.Username, &registeredOn, &user.Privileges, &latestActivity, &user.UsernameAKA, &user.Country, &showCountry)
switch { switch {
case err == sql.ErrNoRows: case err == sql.ErrNoRows:
return common.SimpleResponse(404, "No such user was found!") return common.SimpleResponse(404, "No such user was found!")
@ -109,11 +109,11 @@ type whatIDResponse struct {
// UserWhatsTheIDGET is an API request that only returns an user's ID. // UserWhatsTheIDGET is an API request that only returns an user's ID.
func UserWhatsTheIDGET(md common.MethodData) common.CodeMessager { func UserWhatsTheIDGET(md common.MethodData) common.CodeMessager {
var ( var (
r whatIDResponse r whatIDResponse
privileges int privileges int
) )
err := md.DB.QueryRow("SELECT id, privileges FROM users WHERE username = ? LIMIT 1", md.C.Query("name")).Scan(&r.ID, &privileges) 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()) { if err != nil || ((privileges&common.UserPrivilegePublic) == 0 && !md.User.Privileges.HasPrivilegeViewUserAdvanced()) {
return common.SimpleResponse(404, "That user could not be found!") return common.SimpleResponse(404, "That user could not be found!")
} }
r.Code = 200 r.Code = 200
@ -153,7 +153,7 @@ func UserFullGET(md common.MethodData) common.CodeMessager {
// Hellest query I've ever done. // Hellest query I've ever done.
query := ` query := `
SELECT SELECT
users.id, users.username, users.register_datetime, users.rank, users.latest_activity, users.id, users.username, users.register_datetime, users.privileges, users.latest_activity,
users_stats.username_aka, users_stats.badges_shown, users_stats.country, users_stats.show_country, 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.play_style, users_stats.favourite_mode,
@ -198,7 +198,7 @@ LIMIT 1
latestActivity int64 latestActivity int64
) )
err := md.DB.QueryRow(query, param).Scan( err := md.DB.QueryRow(query, param).Scan(
&r.ID, &r.Username, &registeredOn, &r.Rank, &latestActivity, &r.ID, &r.Username, &registeredOn, &r.Privileges, &latestActivity,
&r.UsernameAKA, &badges, &country, &showCountry, &r.UsernameAKA, &badges, &country, &showCountry,
&r.PlayStyle, &r.FavouriteMode, &r.PlayStyle, &r.FavouriteMode,

View File

@ -114,27 +114,27 @@ func (p Privileges) String() string {
} }
var privilegeMustBe = [...]int{ var privilegeMustBe = [...]int{
1, UserPrivilegeNormal,
1, UserPrivilegeNormal,
1, UserPrivilegeNormal,
3, AdminPrivilegeAccessRAP | AdminPrivilegeManageBadges,
3, AdminPrivilegeAccessRAP | AdminPrivilegeManageBetaKey,
4, AdminPrivilegeAccessRAP | AdminPrivilegeManageSetting,
4, AdminPrivilegeAccessRAP,
4, AdminPrivilegeAccessRAP | AdminPrivilegeManageUsers | AdminPrivilegeBanUsers,
4, AdminPrivilegeAccessRAP | AdminPrivilegeManageUsers | AdminPrivilegeManagePrivilege,
4, AdminPrivilegeAccessRAP | AdminPrivilegeManageUsers | AdminPrivilegeManageServer,
3, AdminPrivilegeChatMod, // temporary?
4, AdminPrivilegeManageServer,
4, AdminPrivilegeAccessRAP | AdminPrivilegeManageBeatmap,
} }
// CanOnly removes any privilege that the user has requested to have, but cannot have due to their rank. // CanOnly removes any privilege that the user has requested to have, but cannot have due to their rank.
func (p Privileges) CanOnly(rank int) Privileges { func (p Privileges) CanOnly(userPrivs int) Privileges {
newPrivilege := 0 newPrivilege := 0
for i, v := range privilegeMustBe { for i, v := range privilegeMustBe {
wants := p&1 == 1 wants := p&1 == 1
can := rank >= v can := userPrivs&v == v
if wants && can { if wants && can {
newPrivilege |= 1 << uint(i) newPrivilege |= 1 << uint(i)
} }

View File

@ -1,5 +1,6 @@
package common package common
// user/admin privileges
const ( const (
UserPrivilegePublic = 1 << iota UserPrivilegePublic = 1 << iota
UserPrivilegeNormal UserPrivilegeNormal