mirror of
https://github.com/pagefaultgames/rogueserver.git
synced 2025-04-02 02:57:15 +08:00
refactor: Simplify, hardcode (empty) access groups
This commit is contained in:
parent
5c8b07138e
commit
4c3a424188
@ -37,6 +37,11 @@ const (
|
||||
|
||||
UUIDSize = 16
|
||||
TokenSize = 32
|
||||
|
||||
// feature access groups
|
||||
DEV_STAFF = "DEV_STAFF"
|
||||
CONTRIBUTOR = "CONTRIBUTOR"
|
||||
EVERYONE = "EVERYONE"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -106,3 +106,19 @@ func RetrieveDiscordId(code string) (string, error) {
|
||||
|
||||
return user.Id, nil
|
||||
}
|
||||
|
||||
// TODO: fetch these instead of hardcoding them
|
||||
var devsAndStaff = map[string]bool{}
|
||||
var contributors = map[string]bool{}
|
||||
|
||||
func GetAccessGroupByDiscordRole(discordId string) (group string) {
|
||||
if devsAndStaff[discordId] {
|
||||
return DEV_STAFF
|
||||
}
|
||||
|
||||
if contributors[discordId] {
|
||||
return CONTRIBUTOR
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
@ -22,20 +22,54 @@ import (
|
||||
)
|
||||
|
||||
type InfoResponse struct {
|
||||
Username string `json:"username"`
|
||||
DiscordId string `json:"discordId"`
|
||||
GoogleId string `json:"googleId"`
|
||||
LastSessionSlot int `json:"lastSessionSlot"`
|
||||
Username string `json:"username"`
|
||||
DiscordId string `json:"discordId"`
|
||||
GoogleId string `json:"googleId"`
|
||||
LastSessionSlot int `json:"lastSessionSlot"`
|
||||
FeatureFlags []string `json:"featureFlags"`
|
||||
}
|
||||
|
||||
// /account/info - get account info
|
||||
func Info(username string, discordId string, googleId string, uuid []byte) (InfoResponse, error) {
|
||||
slot, _ := db.GetLatestSessionSaveDataSlot(uuid)
|
||||
featureFlags := getFeatureFlags(discordId)
|
||||
response := InfoResponse{
|
||||
Username: username,
|
||||
LastSessionSlot: slot,
|
||||
DiscordId: discordId,
|
||||
GoogleId: googleId,
|
||||
FeatureFlags: featureFlags,
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func getFeatureFlags(discordId string) []string {
|
||||
var flags []string
|
||||
|
||||
enabledFlags, err := db.GetEnabledFeatureFlags()
|
||||
if err != nil {
|
||||
return flags
|
||||
}
|
||||
|
||||
for _, flag := range enabledFlags {
|
||||
var hasAccess = false
|
||||
|
||||
if flag.AccessLevel == EVERYONE {
|
||||
hasAccess = true
|
||||
} else {
|
||||
accessGroup := GetAccessGroupByDiscordRole(discordId)
|
||||
|
||||
if flag.AccessLevel == DEV_STAFF {
|
||||
hasAccess = accessGroup == DEV_STAFF
|
||||
} else if flag.AccessLevel == CONTRIBUTOR {
|
||||
hasAccess = accessGroup == CONTRIBUTOR || accessGroup == DEV_STAFF
|
||||
}
|
||||
}
|
||||
|
||||
if hasAccess {
|
||||
flags = append(flags, flag.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2024 Pagefault Games
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"hash/crc32"
|
||||
"math"
|
||||
)
|
||||
|
||||
func CheckFeatureFlagEnabled(accountId []byte, flag string, percent int) bool {
|
||||
if percent <= 0 {
|
||||
return false
|
||||
} else if percent >= 100 {
|
||||
return true
|
||||
}
|
||||
|
||||
pct := math.Max(0, math.Min(100, float64(percent)))
|
||||
flagBytes := []byte(flag)
|
||||
|
||||
// hash key is [...accountId, ...flagBytes]
|
||||
hashKey := make([]byte, len(accountId)+len(flagBytes))
|
||||
copy(hashKey, accountId)
|
||||
copy(hashKey[len(accountId):], flagBytes)
|
||||
|
||||
boundary := float64(math.MaxUint32) * (pct / float64(100))
|
||||
hash := float64(crc32.ChecksumIEEE(hashKey))
|
||||
|
||||
return hash >= boundary
|
||||
}
|
3
db/db.go
3
db/db.go
@ -106,8 +106,7 @@ func setupDb(tx *sql.Tx) error {
|
||||
|
||||
// ----------------------------------
|
||||
// MIGRATION 004
|
||||
`CREATE TABLE IF NOT EXISTS featureFlags (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) UNIQUE NOT NULL, enabled TINYINT(1) NOT NULL, percentage TINYINT(3) NOT NULL DEFAULT 0, CONSTRAINT chk_featureFlagsPercentage_withinRange CHECK(percentage >= 0 AND percentage <= 100))`,
|
||||
`CREATE TABLE IF NOT EXISTS accountFeatureFlagOverrides (accountId BINARY(16) NOT NULL, flagId INT(11) NOT NULL, enabled TINYINT(1) NOT NULL, PRIMARY KEY (accountId, flagId), FOREIGN KEY (accountId) REFERENCES accounts (uuid) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY (flagId) REFERENCES featureFlags (id) ON DELETE CASCADE ON UPDATE CASCADE)`,
|
||||
`CREATE TABLE IF NOT EXISTS featureFlags (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) UNIQUE NOT NULL, accessLevel VARCHAR(16), CONSTRAINT chk_featureFlags_accessLevel CHECK(accessLevel IN ('DEV_STAFF', 'CONTRIBUTOR', 'EVERYONE')))`,
|
||||
}
|
||||
|
||||
for _, q := range queries {
|
||||
|
@ -17,12 +17,14 @@
|
||||
|
||||
package db
|
||||
|
||||
import "github.com/pagefaultgames/rogueserver/defs"
|
||||
import (
|
||||
"github.com/pagefaultgames/rogueserver/defs"
|
||||
)
|
||||
|
||||
func GetEnabledFeatureFlags() ([]defs.FeatureFlag, error) {
|
||||
var activeFlags []defs.FeatureFlag
|
||||
|
||||
results, err := handle.Query("SELECT name, percentage FROM featureFlags WHERE enabled = 1")
|
||||
results, err := handle.Query("SELECT name, accessLevel FROM featureFlags WHERE enabled = 1")
|
||||
|
||||
if err != nil {
|
||||
return activeFlags, err
|
||||
@ -33,7 +35,8 @@ func GetEnabledFeatureFlags() ([]defs.FeatureFlag, error) {
|
||||
for results.Next() {
|
||||
var flag defs.FeatureFlag
|
||||
|
||||
err = results.Scan(&flag.Name, &flag.Percentage)
|
||||
err = results.Scan(&flag.Name, &flag.AccessLevel)
|
||||
|
||||
if err != nil {
|
||||
return activeFlags, err
|
||||
}
|
||||
@ -43,28 +46,3 @@ func GetEnabledFeatureFlags() ([]defs.FeatureFlag, error) {
|
||||
|
||||
return activeFlags, nil
|
||||
}
|
||||
|
||||
func GetFeatureFlagOverrides(accountId []byte) ([]defs.FeatureFlagOverride, error) {
|
||||
var overrides []defs.FeatureFlagOverride
|
||||
|
||||
results, err := handle.Query("SELECT ff.name, o.enabled FROM accoutFeatureFlagOverrides o JOIN featureFlags ff ON o.flagId = ff.id WHERE accountId = ?", accountId)
|
||||
|
||||
if err != nil {
|
||||
return overrides, err
|
||||
}
|
||||
|
||||
defer results.Close()
|
||||
|
||||
for results.Next() {
|
||||
var override defs.FeatureFlagOverride
|
||||
|
||||
err = results.Scan(&override.FlagName, &override.Enabled)
|
||||
if err != nil {
|
||||
return overrides, err
|
||||
}
|
||||
|
||||
overrides = append(overrides, override)
|
||||
}
|
||||
|
||||
return overrides, nil
|
||||
}
|
||||
|
@ -18,11 +18,6 @@
|
||||
package defs
|
||||
|
||||
type FeatureFlag struct {
|
||||
Name string
|
||||
Percentage int
|
||||
}
|
||||
|
||||
type FeatureFlagOverride struct {
|
||||
FlagName string
|
||||
Enabled bool
|
||||
Name string
|
||||
AccessLevel string // DEV_STAFF | CONTRIBUTOR | EVERYONE
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user