mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-15 13:19:53 +05:00
199 lines
4.7 KiB
Go
199 lines
4.7 KiB
Go
package engine
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/cgrates/cgrates/utils"
|
|
"github.com/cgrates/rpcclient"
|
|
)
|
|
|
|
type UserProfile struct {
|
|
Tenant string
|
|
UserName string
|
|
Profile map[string]string
|
|
}
|
|
|
|
func (ud *UserProfile) GetId() string {
|
|
return utils.ConcatenatedKey(ud.Tenant, ud.UserName)
|
|
}
|
|
|
|
func (ud *UserProfile) SetId(id string) error {
|
|
vals := strings.Split(id, utils.CONCATENATED_KEY_SEP)
|
|
if len(vals) != 2 {
|
|
return utils.ErrInvalidKey
|
|
}
|
|
ud.Tenant = vals[0]
|
|
ud.UserName = vals[1]
|
|
return nil
|
|
}
|
|
|
|
type UserService interface {
|
|
SetUser(UserProfile, *string) error
|
|
RemoveUser(UserProfile, *string) error
|
|
UpdateUser(UserProfile, *string) error
|
|
GetUsers(UserProfile, *[]*UserProfile) error
|
|
AddIndex([]string, *string) error
|
|
}
|
|
|
|
type UserMap struct {
|
|
Table map[string]map[string]string
|
|
Index map[string][]string
|
|
}
|
|
|
|
func NewUserMap() *UserMap {
|
|
return &UserMap{
|
|
Table: make(map[string]map[string]string),
|
|
Index: make(map[string][]string),
|
|
}
|
|
}
|
|
|
|
func (um *UserMap) SetUser(up UserProfile, reply *string) error {
|
|
um.Table[up.GetId()] = up.Profile
|
|
*reply = utils.OK
|
|
return nil
|
|
}
|
|
|
|
func (um *UserMap) RemoveUser(up UserProfile, reply *string) error {
|
|
delete(um.Table, up.GetId())
|
|
*reply = utils.OK
|
|
return nil
|
|
}
|
|
|
|
func (um *UserMap) UpdateUser(up UserProfile, reply *string) error {
|
|
m, found := um.Table[up.GetId()]
|
|
if !found {
|
|
*reply = utils.ErrNotFound.Error()
|
|
return utils.ErrNotFound
|
|
}
|
|
if m == nil {
|
|
um.Table[up.GetId()] = make(map[string]string, 0)
|
|
}
|
|
for key, value := range up.Profile {
|
|
um.Table[up.GetId()][key] = value
|
|
}
|
|
*reply = utils.OK
|
|
return nil
|
|
}
|
|
|
|
func (um *UserMap) GetUsers(up UserProfile, results *[]*UserProfile) error {
|
|
table := um.Table // no index
|
|
|
|
indexUnionKeys := make(map[string]bool)
|
|
// search index
|
|
if up.Tenant != "" {
|
|
if keys, found := um.Index[utils.ConcatenatedKey("Tenant", up.Tenant)]; found {
|
|
for _, key := range keys {
|
|
indexUnionKeys[key] = true
|
|
}
|
|
}
|
|
}
|
|
if up.UserName != "" {
|
|
if keys, found := um.Index[utils.ConcatenatedKey("UserName", up.UserName)]; found {
|
|
for _, key := range keys {
|
|
indexUnionKeys[key] = true
|
|
}
|
|
}
|
|
}
|
|
for k, v := range up.Profile {
|
|
if keys, found := um.Index[utils.ConcatenatedKey(k, v)]; found {
|
|
for _, key := range keys {
|
|
indexUnionKeys[key] = true
|
|
}
|
|
}
|
|
}
|
|
if len(indexUnionKeys) != 0 {
|
|
table = make(map[string]map[string]string)
|
|
for key := range indexUnionKeys {
|
|
table[key] = um.Table[key]
|
|
}
|
|
}
|
|
|
|
var candidates []*UserProfile
|
|
for key, values := range table {
|
|
if up.Tenant != "" && !strings.HasPrefix(key, up.Tenant+utils.CONCATENATED_KEY_SEP) {
|
|
continue
|
|
}
|
|
if up.UserName != "" && !strings.HasSuffix(key, utils.CONCATENATED_KEY_SEP+up.UserName) {
|
|
continue
|
|
}
|
|
valid := true
|
|
for k, v := range up.Profile {
|
|
if values[k] != v {
|
|
valid = false
|
|
break
|
|
}
|
|
}
|
|
if !valid {
|
|
continue
|
|
}
|
|
// all filters passed, add to candidates
|
|
nup := &UserProfile{Profile: make(map[string]string)}
|
|
nup.SetId(key)
|
|
for k, v := range values {
|
|
nup.Profile[k] = v
|
|
}
|
|
candidates = append(candidates, nup)
|
|
}
|
|
*results = candidates
|
|
return nil
|
|
}
|
|
|
|
func (um *UserMap) AddIndex(indexes []string, reply *string) error {
|
|
for key, values := range um.Table {
|
|
ud := &UserProfile{Profile: values}
|
|
ud.SetId(key)
|
|
for _, index := range indexes {
|
|
if index == "Tenant" {
|
|
if ud.Tenant != "" {
|
|
um.Index[utils.ConcatenatedKey(index, ud.Tenant)] = append(um.Index[utils.ConcatenatedKey(index, ud.Tenant)], key)
|
|
}
|
|
continue
|
|
}
|
|
if index == "UserName" {
|
|
if ud.UserName != "" {
|
|
um.Index[utils.ConcatenatedKey(index, ud.UserName)] = append(um.Index[utils.ConcatenatedKey(index, ud.UserName)], key)
|
|
}
|
|
continue
|
|
}
|
|
|
|
for k, v := range ud.Profile {
|
|
if k == index && v != "" {
|
|
um.Index[utils.ConcatenatedKey(k, v)] = append(um.Index[utils.ConcatenatedKey(k, v)], key)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*reply = utils.OK
|
|
return nil
|
|
}
|
|
|
|
type UserProxy struct{}
|
|
|
|
type ProxyUserService struct {
|
|
Client *rpcclient.RpcClient
|
|
}
|
|
|
|
func NewProxyUserService(addr string, reconnects int) (*ProxyUserService, error) {
|
|
client, err := rpcclient.NewRpcClient("tcp", addr, reconnects, utils.GOB)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &ProxyUserService{Client: client}, nil
|
|
}
|
|
|
|
func (ps *ProxyUserService) SetUser(ud UserProfile, reply *string) error {
|
|
return ps.Client.Call("UserService.SetUser", ud, reply)
|
|
}
|
|
|
|
func (ps *ProxyUserService) RemoveUser(ud UserProfile, reply *string) error {
|
|
return ps.Client.Call("UserService.RemoveUser", ud, reply)
|
|
}
|
|
|
|
func (ps *ProxyUserService) GetUsers(ud UserProfile, users *[]*UserProfile) error {
|
|
return ps.Client.Call("UserService.GetUsers", ud, users)
|
|
}
|
|
|
|
func (ps *ProxyUserService) AddIndex(indexes []string, reply *string) error {
|
|
return ps.Client.Call("UserService.AddIndex", indexes, reply)
|
|
}
|