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:
Howl
2016-08-27 12:04:12 +02:00
parent 476cd385f8
commit e4d27f8d6b
18 changed files with 130 additions and 159 deletions

View File

@@ -30,6 +30,13 @@ func (md MethodData) Query(q string) string {
return md.C.Query(q)
}
// HasQuery returns true if the parameter is encountered in the querystring.
// It returns true even if the parameter is "" (the case of ?param&etc=etc)
func (md MethodData) HasQuery(q string) bool {
_, has := md.C.GetQuery(q)
return has
}
// RequestData is the body of a request. It is wrapped into this type
// to implement the Unmarshal function, which is just a shorthand to
// json.Unmarshal.

View File

@@ -22,66 +22,6 @@ const (
// Privileges is a bitwise enum of the privileges of an user's API key.
type Privileges uint64
// HasPrivilegeReadConfidential returns whether the ReadConfidential privilege is included in the privileges.
func (p Privileges) HasPrivilegeReadConfidential() bool {
return p&PrivilegeReadConfidential != 0
}
// HasPrivilegeWrite returns whether the Write privilege is included in the privileges.
func (p Privileges) HasPrivilegeWrite() bool {
return p&PrivilegeWrite != 0
}
// HasPrivilegeManageBadges returns whether the ManageBadges privilege is included in the privileges.
func (p Privileges) HasPrivilegeManageBadges() bool {
return p&PrivilegeManageBadges != 0
}
// HasPrivilegeBetaKeys returns whether the BetaKeys privilege is included in the privileges.
func (p Privileges) HasPrivilegeBetaKeys() bool {
return p&PrivilegeBetaKeys != 0
}
// HasPrivilegeManageSettings returns whether the ManageSettings privilege is included in the privileges.
func (p Privileges) HasPrivilegeManageSettings() bool {
return p&PrivilegeManageSettings != 0
}
// HasPrivilegeViewUserAdvanced returns whether the ViewUserAdvanced privilege is included in the privileges.
func (p Privileges) HasPrivilegeViewUserAdvanced() bool {
return p&PrivilegeViewUserAdvanced != 0
}
// HasPrivilegeManageUser returns whether the ManageUser privilege is included in the privileges.
func (p Privileges) HasPrivilegeManageUser() bool {
return p&PrivilegeManageUser != 0
}
// HasPrivilegeManageRoles returns whether the ManageRoles privilege is included in the privileges.
func (p Privileges) HasPrivilegeManageRoles() bool {
return p&PrivilegeManageRoles != 0
}
// HasPrivilegeManageAPIKeys returns whether the ManageAPIKeys privilege is included in the privileges.
func (p Privileges) HasPrivilegeManageAPIKeys() bool {
return p&PrivilegeManageAPIKeys != 0
}
// HasPrivilegeBlog returns whether the Blog privilege is included in the privileges.
func (p Privileges) HasPrivilegeBlog() bool {
return p&PrivilegeBlog != 0
}
// HasPrivilegeAPIMeta returns whether the APIMeta privilege is included in the privileges.
func (p Privileges) HasPrivilegeAPIMeta() bool {
return p&PrivilegeAPIMeta != 0
}
// HasPrivilegeBeatmap returns whether the Beatmap privilege is included in the privileges.
func (p Privileges) HasPrivilegeBeatmap() bool {
return p&PrivilegeBeatmap != 0
}
var privilegeString = [...]string{
"Read",
"ReadConfidential",
@@ -101,14 +41,14 @@ var privilegeString = [...]string{
func (p Privileges) String() string {
var pvs []string
for i, v := range privilegeString {
if int(p)&(1<<uint(i)) != 0 {
if uint64(p)&uint64(1<<uint(i)) != 0 {
pvs = append(pvs, v)
}
}
return strings.Join(pvs, ", ")
}
var privilegeMustBe = [...]int{
var privilegeMustBe = [...]UserPrivileges{
1 << 30, // read is deprecated, and should be given out to no-one.
UserPrivilegeNormal,
UserPrivilegeNormal,
@@ -125,7 +65,7 @@ var privilegeMustBe = [...]int{
}
// CanOnly removes any privilege that the user has requested to have, but cannot have due to their rank.
func (p Privileges) CanOnly(userPrivs int) Privileges {
func (p Privileges) CanOnly(userPrivs UserPrivileges) Privileges {
newPrivilege := 0
for i, v := range privilegeMustBe {
wants := p&1 == 1

View File

@@ -1,9 +1,23 @@
package common
// Token Is an API token.
import "fmt"
// Token is an API token.
type Token struct {
ID int
Value string
UserID int
Privileges Privileges
ID int
Value string
UserID int
TokenPrivileges Privileges
UserPrivileges UserPrivileges
}
// OnlyUserPublic returns a string containing "(user.privileges & 1 = 1 OR users.id = <userID>)"
// if the user does not have the UserPrivilege AdminManageUsers, and returns "1" otherwise.
func (t Token) OnlyUserPublic(userManagerSeesEverything bool) string {
if userManagerSeesEverything &&
t.UserPrivileges&AdminPrivilegeManageUsers == AdminPrivilegeManageUsers {
return "1"
}
// It's safe to use sprintf directly even if it's a query, because UserID is an int.
return fmt.Sprintf("(user.privileges & 1 = 1 OR users.id = '%d')", t.UserID)
}

View File

@@ -1,8 +1,10 @@
package common
import "strings"
// user/admin privileges
const (
UserPrivilegePublic = 1 << iota
UserPrivilegePublic UserPrivileges = 1 << iota
UserPrivilegeNormal
UserPrivilegeDonor
AdminPrivilegeAccessRAP
@@ -22,4 +24,42 @@ const (
AdminPrivilegeSendAlerts
AdminPrivilegeChatMod
AdminPrivilegeKickUsers
UserPrivilegePendingVerification
)
// UserPrivileges represents a bitwise enum of the privileges of an user.
type UserPrivileges uint64
var userPrivilegeString = [...]string{
"UserPublic",
"UserNormal",
"UserDonor",
"AdminAccessRAP",
"AdminManageUsers",
"AdminBanUsers",
"AdminSilenceUsers",
"AdminWipeUsers",
"AdminManageBeatmap",
"AdminManageServer",
"AdminManageSetting",
"AdminManageBetaKey",
"AdminManageReport",
"AdminManageDocs",
"AdminManageBadges",
"AdminViewRAPLogs",
"AdminManagePrivilege",
"AdminSendAlerts",
"AdminChatMod",
"AdminKickUsers",
"UserPendingVerification",
}
func (p UserPrivileges) String() string {
var pvs []string
for i, v := range userPrivilegeString {
if uint64(p)&uint64(1<<uint(i)) != 0 {
pvs = append(pvs, v)
}
}
return strings.Join(pvs, ", ")
}