121 lines
4.7 KiB
Go
121 lines
4.7 KiB
Go
package management
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
type TokenSpec struct {
|
|
Principal string `json:"principal"`
|
|
Realm string `json:"realm"`
|
|
Scopes []string `json:"scopes"`
|
|
Resources map[string][]string `json:"resources,omitempty"`
|
|
}
|
|
|
|
type Config struct {
|
|
Addr string
|
|
Mode string
|
|
DBPath string
|
|
MockCellApply bool
|
|
MockCellFailures map[string]string
|
|
SeedDemo bool
|
|
AllowPrivateAgent bool
|
|
AgentAllowlist map[string]bool
|
|
AllowedOrigins map[string]bool
|
|
Tokens map[string]TokenSpec
|
|
}
|
|
|
|
func DefaultConfig() Config {
|
|
return Config{
|
|
Addr: "127.0.0.1:8080", Mode: ModeMock, DBPath: "./data/management.db",
|
|
MockCellApply: false, MockCellFailures: map[string]string{}, SeedDemo: false, AgentAllowlist: map[string]bool{}, AllowedOrigins: map[string]bool{"http://localhost:3000": true, "http://127.0.0.1:3000": true}, Tokens: defaultTokens(),
|
|
}
|
|
}
|
|
|
|
func defaultTokens() map[string]TokenSpec {
|
|
all := []string{"sip.provider.read", "sip.provider.write", "sip.trunk.read", "sip.trunk.write", "sip.trunk.publish", "sip.trunk.disable", "sip.trunk.rollback", "sip.cell.read", "sip.cell.write", "sip.status.read", "sip.statistics.read", "sip.calls.read", "sip.audit.read", "sip.operation.read"}
|
|
return map[string]TokenSpec{
|
|
"dev-admin-token": {Principal: "operator:local-admin", Realm: "admin", Scopes: all},
|
|
"dev-config-token": {Principal: "operator:config", Realm: "admin", Scopes: []string{"sip.provider.read", "sip.provider.write", "sip.trunk.read", "sip.trunk.write", "sip.cell.read", "sip.status.read", "sip.statistics.read", "sip.calls.read"}},
|
|
"dev-publisher-token": {Principal: "operator:publisher", Realm: "admin", Scopes: []string{"sip.provider.read", "sip.trunk.read", "sip.trunk.publish", "sip.trunk.disable", "sip.trunk.rollback", "sip.cell.read", "sip.status.read", "sip.operation.read"}},
|
|
"dev-observer-token": {Principal: "operator:observer", Realm: "admin", Scopes: []string{"sip.provider.read", "sip.trunk.read", "sip.cell.read", "sip.status.read", "sip.statistics.read", "sip.calls.read"}},
|
|
"dev-audit-token": {Principal: "operator:auditor", Realm: "admin", Scopes: []string{"sip.provider.read", "sip.trunk.read", "sip.audit.read", "sip.operation.read"}},
|
|
"dev-saas-token": {Principal: "saas:readonly", Realm: "saas", Scopes: []string{"sip.trunk.read"}},
|
|
"dev-scheduler-token": {Principal: "scheduler:ordinary", Realm: "scheduler", Scopes: []string{"sip.trunk.read"}},
|
|
}
|
|
}
|
|
|
|
func LoadConfig(v *viper.Viper) Config {
|
|
cfg := DefaultConfig()
|
|
v.SetDefault("addr", cfg.Addr)
|
|
v.SetDefault("mode", cfg.Mode)
|
|
v.SetDefault("db_path", cfg.DBPath)
|
|
v.SetDefault("mock_cell_apply", cfg.MockCellApply)
|
|
v.SetDefault("seed_demo", cfg.SeedDemo)
|
|
v.SetDefault("allow_private_agent", cfg.AllowPrivateAgent)
|
|
v.SetDefault("mock_cell_failures", "")
|
|
v.SetDefault("agent_allowlist", "")
|
|
v.SetDefault("allowed_origins", "")
|
|
v.SetDefault("tokens_json", "")
|
|
cfg.Addr = v.GetString("addr")
|
|
cfg.Mode = strings.ToLower(v.GetString("mode"))
|
|
if cfg.Mode != ModeReal {
|
|
cfg.Mode = ModeMock
|
|
}
|
|
cfg.DBPath = v.GetString("db_path")
|
|
cfg.MockCellApply = v.GetBool("mock_cell_apply")
|
|
cfg.MockCellFailures = map[string]string{}
|
|
for _, item := range strings.Split(v.GetString("mock_cell_failures"), ",") {
|
|
parts := strings.SplitN(strings.TrimSpace(item), "=", 2)
|
|
if len(parts) == 2 && validID(parts[0]) && parts[1] != "" {
|
|
cfg.MockCellFailures[parts[0]] = parts[1]
|
|
}
|
|
}
|
|
cfg.SeedDemo = v.GetBool("seed_demo")
|
|
cfg.AllowPrivateAgent = v.GetBool("allow_private_agent")
|
|
cfg.AgentAllowlist = map[string]bool{}
|
|
for _, host := range strings.Split(v.GetString("agent_allowlist"), ",") {
|
|
if host = strings.TrimSpace(strings.ToLower(host)); host != "" {
|
|
cfg.AgentAllowlist[host] = true
|
|
}
|
|
}
|
|
cfg.AllowedOrigins = map[string]bool{}
|
|
for _, origin := range strings.Split(v.GetString("allowed_origins"), ",") {
|
|
if origin = strings.TrimSpace(origin); origin != "" {
|
|
cfg.AllowedOrigins[origin] = true
|
|
}
|
|
}
|
|
if len(cfg.AllowedOrigins) == 0 {
|
|
cfg.AllowedOrigins = DefaultConfig().AllowedOrigins
|
|
}
|
|
if raw := v.GetString("tokens_json"); raw != "" {
|
|
var tokens map[string]TokenSpec
|
|
if json.Unmarshal([]byte(raw), &tokens) == nil && len(tokens) > 0 {
|
|
cfg.Tokens = tokens
|
|
}
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func ConfigFromEnv() Config {
|
|
v := viper.New()
|
|
v.SetEnvPrefix("MANAGEMENT")
|
|
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
|
v.AutomaticEnv()
|
|
return LoadConfig(v)
|
|
}
|
|
|
|
func (c Config) PublicMode() string {
|
|
if c.Mode == ModeReal {
|
|
return ModeReal
|
|
}
|
|
return ModeMock
|
|
}
|
|
|
|
func EnsureDevTokenWarning(c Config) bool {
|
|
return c.Mode == ModeMock && os.Getenv("MANAGEMENT_SUPPRESS_DEV_TOKEN_WARNING") == ""
|
|
}
|