mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-16 13:49:53 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -354,6 +354,7 @@ CREATE TABLE tp_users (
|
||||
`masked` BOOLEAN NOT NULL,
|
||||
`attribute_name` varchar(64) NOT NULL,
|
||||
`attribute_value` varchar(64) NOT NULL,
|
||||
`weight` DECIMAL(8,2) NOT NULL,
|
||||
`created_at` TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tpid` (`tpid`)
|
||||
|
||||
@@ -349,6 +349,7 @@ CREATE TABLE tp_users (
|
||||
masked BOOLEAN NOT NULL,
|
||||
attribute_name VARCHAR(64) NOT NULL,
|
||||
attribute_value VARCHAR(64) NOT NULL,
|
||||
weight NUMERIC(8,2) NOT NULL,
|
||||
created_at TIMESTAMP
|
||||
);
|
||||
CREATE INDEX tpusers_tpid_idx ON tp_users (tpid);
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#Tenant[0],UserName[1],Maksed[2],AttributeName[3],AttributeValue[4]
|
||||
cgrates.org,1001,,SysUserName,danb
|
||||
cgrates.org,1001,,SysPassword,hisPass321
|
||||
cgrates.org,1001,,Cli,+4986517174963
|
||||
cgrates.org,1001,,Account,1001
|
||||
cgrates.org,1001,,Subject,1001
|
||||
cgrates.org,1001,,Uuid,388539dfd4f5cefee8f488b78c6c244b9e19138e
|
||||
cgrates.org,1001,,ReqType,*prepaid
|
||||
cgrates.org,1002,,SysUserName,rif
|
||||
cgrates.org,1002,,RifAttr,RifVal
|
||||
cgrates.org,1002,,Account,1002
|
||||
cgrates.org,1002,,Subject,1002
|
||||
cgrates.org,1002,,Uuid,27f37edec0670fa34cf79076b80ef5021e39c5b5
|
||||
cgrates.org,1004,,SysUserName,danb4
|
||||
cgrates.org,1004,,SysPassword,hisPass321
|
||||
cgrates.org,1004,,Cli,+4986517174964
|
||||
cgrates.org,1004,,Account,1004
|
||||
cgrates.org,1004,,Subject,1004
|
||||
cgrates.org,1004,,ReqType,*rated
|
||||
#Tenant[0],UserName[1],Maksed[2],AttributeName[3],AttributeValue[4],Weight[5]
|
||||
cgrates.org,1001,,SysUserName,danb,10
|
||||
cgrates.org,1001,,SysPassword,hisPass321,10
|
||||
cgrates.org,1001,,Cli,+4986517174963,10
|
||||
cgrates.org,1001,,Account,1001,10
|
||||
cgrates.org,1001,,Subject,1001,10
|
||||
cgrates.org,1001,,Uuid,388539dfd4f5cefee8f488b78c6c244b9e19138e,10
|
||||
cgrates.org,1001,,ReqType,*prepaid,10
|
||||
cgrates.org,1002,,SysUserName,rif,10
|
||||
cgrates.org,1002,,RifAttr,RifVal,10
|
||||
cgrates.org,1002,,Account,1002,10
|
||||
cgrates.org,1002,,Subject,1002,10
|
||||
cgrates.org,1002,,Uuid,27f37edec0670fa34cf79076b80ef5021e39c5b5,10
|
||||
cgrates.org,1004,,SysUserName,danb4,10
|
||||
cgrates.org,1004,,SysPassword,hisPass321,10
|
||||
cgrates.org,1004,,Cli,+4986517174964,10
|
||||
cgrates.org,1004,,Account,1004,10
|
||||
cgrates.org,1004,,Subject,1004,10
|
||||
cgrates.org,1004,,ReqType,*rated,10
|
||||
|
||||
|
@@ -1,19 +1,19 @@
|
||||
#Tenant[0],UserName[1],Masked[2],AttributeName[3],AttributeValue[4]
|
||||
cgrates.org,1001,,SysUserName,danb
|
||||
cgrates.org,1001,,SysPassword,hisPass321
|
||||
cgrates.org,1001,,Cli,+4986517174963
|
||||
cgrates.org,1001,,Account,1001
|
||||
cgrates.org,1001,,Subject,1001
|
||||
cgrates.org,1001,,Uuid,388539dfd4f5cefee8f488b78c6c244b9e19138e
|
||||
cgrates.org,1001,,ReqType,*prepaid
|
||||
cgrates.org,1002,,SysUserName,rif
|
||||
cgrates.org,1002,,RifAttr,RifVal
|
||||
cgrates.org,1002,,Account,1002
|
||||
cgrates.org,1002,,Subject,1002
|
||||
cgrates.org,1002,,Uuid,27f37edec0670fa34cf79076b80ef5021e39c5b5
|
||||
cgrates.org,1004,,SysUserName,danb4
|
||||
cgrates.org,1004,,SysPassword,hisPass321
|
||||
cgrates.org,1004,,Cli,+4986517174964
|
||||
cgrates.org,1004,,Account,1004
|
||||
cgrates.org,1004,,Subject,1004
|
||||
cgrates.org,1004,,ReqType,*rated
|
||||
#Tenant[0],UserName[1],Masked[2],AttributeName[3],AttributeValue[4],Weight[5]
|
||||
cgrates.org,1001,,SysUserName,danb,10
|
||||
cgrates.org,1001,,SysPassword,hisPass321,10
|
||||
cgrates.org,1001,,Cli,+4986517174963,10
|
||||
cgrates.org,1001,,Account,1001,10
|
||||
cgrates.org,1001,,Subject,1001,10
|
||||
cgrates.org,1001,,Uuid,388539dfd4f5cefee8f488b78c6c244b9e19138e,10
|
||||
cgrates.org,1001,,ReqType,*prepaid,10
|
||||
cgrates.org,1002,,SysUserName,rif,10
|
||||
cgrates.org,1002,,RifAttr,RifVal,10
|
||||
cgrates.org,1002,,Account,1002,10
|
||||
cgrates.org,1002,,Subject,1002,10
|
||||
cgrates.org,1002,,Uuid,27f37edec0670fa34cf79076b80ef5021e39c5b5,10
|
||||
cgrates.org,1004,,SysUserName,danb4,10
|
||||
cgrates.org,1004,,SysPassword,hisPass321,10
|
||||
cgrates.org,1004,,Cli,+4986517174964,10
|
||||
cgrates.org,1004,,Account,1004,10
|
||||
cgrates.org,1004,,Subject,1004,10
|
||||
cgrates.org,1004,,ReqType,*rated,10
|
||||
|
||||
|
@@ -223,10 +223,10 @@ CDRST2,,,,ACD,,,,,,,,,,,,,,,,,,,,
|
||||
`
|
||||
users = `
|
||||
#Tenant[0],UserName[1],AttributeName[2],AttributeValue[3]
|
||||
cgrates.org,rif,false,test0,val0
|
||||
cgrates.org,rif,,test1,val1
|
||||
cgrates.org,dan,,another,value
|
||||
cgrates.org,mas,true,another,value
|
||||
cgrates.org,rif,false,test0,val0,10
|
||||
cgrates.org,rif,,test1,val1,10
|
||||
cgrates.org,dan,,another,value,10
|
||||
cgrates.org,mas,true,another,value,10
|
||||
`
|
||||
aliases = `
|
||||
#Direction[0],Tenant[1],Category[2],Account[3],Subject[4],DestinationId[5],Group[6],Alias[7],Weight[8]
|
||||
|
||||
@@ -177,7 +177,7 @@ func APItoModelAction(as *utils.TPActions) (result []TpAction) {
|
||||
DestinationTags: a.DestinationIds,
|
||||
RatingSubject: a.RatingSubject,
|
||||
Categories: a.Categories,
|
||||
SharedGroups: a.SharedGroups,
|
||||
SharedGroups: a.SharedGroups,
|
||||
BalanceWeight: a.BalanceWeight,
|
||||
ExtraParameters: a.ExtraParameters,
|
||||
Weight: a.Weight,
|
||||
@@ -230,7 +230,7 @@ func APItoModelActionTrigger(ats *utils.TPActionTriggers) (result []TpActionTrig
|
||||
BalanceTimingTags: at.BalanceTimingTags,
|
||||
BalanceRatingSubject: at.BalanceRatingSubject,
|
||||
BalanceCategories: at.BalanceCategories,
|
||||
BalanceSharedGroups: at.BalanceSharedGroups,
|
||||
BalanceSharedGroups: at.BalanceSharedGroups,
|
||||
BalanceDisabled: at.BalanceDisabled,
|
||||
MinQueuedItems: at.MinQueuedItems,
|
||||
ActionsTag: at.ActionsId,
|
||||
@@ -393,6 +393,7 @@ func APItoModelUsers(attr *utils.TPUsers) (result []TpUser) {
|
||||
UserName: attr.UserName,
|
||||
AttributeName: p.AttrName,
|
||||
AttributeValue: p.AttrValue,
|
||||
Weight: attr.Weight,
|
||||
})
|
||||
}
|
||||
if len(attr.Profile) == 0 {
|
||||
|
||||
@@ -730,6 +730,7 @@ func (tps TpUsers) GetUsers() (map[string]*utils.TPUsers, error) {
|
||||
user = &utils.TPUsers{
|
||||
Tenant: tp.Tenant,
|
||||
UserName: tp.UserName,
|
||||
Weight: tp.Weight,
|
||||
}
|
||||
users[tp.GetId()] = user
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ type TpAction struct {
|
||||
Categories string `index:"6" re:""`
|
||||
DestinationTags string `index:"7" re:"\*any|\w+\s*"`
|
||||
RatingSubject string `index:"8" re:"\w+\s*"`
|
||||
SharedGroups string `index:"9" re:"[0-9A-Za-z_;]*"`
|
||||
SharedGroups string `index:"9" re:"[0-9A-Za-z_;]*"`
|
||||
ExpiryTime string `index:"10" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"`
|
||||
TimingTags string `index:"11" re:"[0-9A-Za-z_;]*|\*any"`
|
||||
Units float64 `index:"12" re:"\d+\s*"`
|
||||
@@ -197,7 +197,7 @@ type TpActionTrigger struct {
|
||||
BalanceCategories string `index:"9" re:""`
|
||||
BalanceDestinationTags string `index:"10" re:"\w+|\*any"`
|
||||
BalanceRatingSubject string `index:"11" re:"\w+|\*any"`
|
||||
BalanceSharedGroups string `index:"12" re:"\w+|\*any"`
|
||||
BalanceSharedGroups string `index:"12" re:"\w+|\*any"`
|
||||
BalanceExpiryTime string `index:"13" re:"\*\w+\s*|\+\d+[smh]\s*|\d+\s*"`
|
||||
BalanceTimingTags string `index:"14" re:"[0-9A-Za-z_;]*|\*any"`
|
||||
BalanceWeight float64 `index:"15" re:"\d+\.?\d*"`
|
||||
@@ -331,11 +331,12 @@ func (t TpCdrstat) TableName() string {
|
||||
type TpUser struct {
|
||||
Id int64
|
||||
Tpid string
|
||||
Tenant string `index:"0" re:""`
|
||||
UserName string `index:"1" re:""`
|
||||
Masked bool `index:"2" re:""`
|
||||
AttributeName string `index:"3" re:""`
|
||||
AttributeValue string `index:"4" re:""`
|
||||
Tenant string `index:"0" re:""`
|
||||
UserName string `index:"1" re:""`
|
||||
Masked bool `index:"2" re:""`
|
||||
AttributeName string `index:"3" re:""`
|
||||
AttributeValue string `index:"4" re:""`
|
||||
Weight float64 `index:"5" re:""`
|
||||
}
|
||||
|
||||
func (tu *TpUser) GetId() string {
|
||||
|
||||
@@ -15,6 +15,7 @@ type UserProfile struct {
|
||||
UserName string
|
||||
Masked bool
|
||||
Profile map[string]string
|
||||
Weight float64
|
||||
ponder int
|
||||
}
|
||||
|
||||
@@ -28,8 +29,9 @@ func (ups UserProfiles) Swap(i, j int) {
|
||||
ups[i], ups[j] = ups[j], ups[i]
|
||||
}
|
||||
|
||||
func (ups UserProfiles) Less(j, i int) bool { // get higher ponder in front
|
||||
return ups[i].ponder < ups[j].ponder
|
||||
func (ups UserProfiles) Less(j, i int) bool { // get higher Weight and ponder in front
|
||||
return ups[i].Weight < ups[j].Weight ||
|
||||
(ups[i].Weight == ups[j].Weight && ups[i].ponder < ups[j].ponder)
|
||||
}
|
||||
|
||||
func (ups UserProfiles) Sort() {
|
||||
@@ -60,9 +62,14 @@ type UserService interface {
|
||||
ReloadUsers(string, *string) error
|
||||
}
|
||||
|
||||
type prop struct {
|
||||
masked bool
|
||||
weight float64
|
||||
}
|
||||
|
||||
type UserMap struct {
|
||||
table map[string]map[string]string
|
||||
masked map[string]bool
|
||||
properties map[string]*prop
|
||||
index map[string]map[string]bool
|
||||
indexKeys []string
|
||||
accountingDb AccountingStorage
|
||||
@@ -81,7 +88,7 @@ func NewUserMap(accountingDb AccountingStorage, indexes []string) (*UserMap, err
|
||||
func newUserMap(accountingDb AccountingStorage, indexes []string) *UserMap {
|
||||
return &UserMap{
|
||||
table: make(map[string]map[string]string),
|
||||
masked: make(map[string]bool),
|
||||
properties: make(map[string]*prop),
|
||||
index: make(map[string]map[string]bool),
|
||||
indexKeys: indexes,
|
||||
accountingDb: accountingDb,
|
||||
@@ -94,24 +101,22 @@ func (um *UserMap) ReloadUsers(in string, reply *string) error {
|
||||
// backup old data
|
||||
oldTable := um.table
|
||||
oldIndex := um.index
|
||||
oldMaksed := um.masked
|
||||
oldProperties := um.properties
|
||||
um.table = make(map[string]map[string]string)
|
||||
um.index = make(map[string]map[string]bool)
|
||||
um.masked = make(map[string]bool)
|
||||
um.properties = make(map[string]*prop)
|
||||
|
||||
// load from db
|
||||
if ups, err := um.accountingDb.GetUsers(); err == nil {
|
||||
for _, up := range ups {
|
||||
um.table[up.GetId()] = up.Profile
|
||||
if up.Masked {
|
||||
um.masked[up.GetId()] = true
|
||||
}
|
||||
um.properties[up.GetId()] = &prop{weight: up.Weight, masked: up.Masked}
|
||||
}
|
||||
} else {
|
||||
// restore old data before return
|
||||
um.table = oldTable
|
||||
um.index = oldIndex
|
||||
um.masked = oldMaksed
|
||||
um.properties = oldProperties
|
||||
|
||||
*reply = err.Error()
|
||||
return err
|
||||
@@ -124,7 +129,7 @@ func (um *UserMap) ReloadUsers(in string, reply *string) error {
|
||||
utils.Logger.Err(fmt.Sprintf("Error adding %v indexes to user profile service: %v", um.indexKeys, err))
|
||||
um.table = oldTable
|
||||
um.index = oldIndex
|
||||
um.masked = oldMaksed
|
||||
um.properties = oldProperties
|
||||
|
||||
*reply = err.Error()
|
||||
return err
|
||||
@@ -142,9 +147,7 @@ func (um *UserMap) SetUser(up UserProfile, reply *string) error {
|
||||
return err
|
||||
}
|
||||
um.table[up.GetId()] = up.Profile
|
||||
if up.Masked {
|
||||
um.masked[up.GetId()] = true
|
||||
}
|
||||
um.properties[up.GetId()] = &prop{weight: up.Weight, masked: up.Masked}
|
||||
um.addIndex(&up, um.indexKeys)
|
||||
*reply = utils.OK
|
||||
return nil
|
||||
@@ -158,7 +161,7 @@ func (um *UserMap) RemoveUser(up UserProfile, reply *string) error {
|
||||
return err
|
||||
}
|
||||
delete(um.table, up.GetId())
|
||||
delete(um.masked, up.GetId())
|
||||
delete(um.properties, up.GetId())
|
||||
um.deleteIndex(&up)
|
||||
*reply = utils.OK
|
||||
return nil
|
||||
@@ -172,7 +175,7 @@ func (um *UserMap) UpdateUser(up UserProfile, reply *string) error {
|
||||
*reply = utils.ErrNotFound.Error()
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
masked := um.masked[up.GetId()]
|
||||
properties := um.properties[up.GetId()]
|
||||
if m == nil {
|
||||
m = make(map[string]string)
|
||||
}
|
||||
@@ -183,7 +186,8 @@ func (um *UserMap) UpdateUser(up UserProfile, reply *string) error {
|
||||
oldUp := &UserProfile{
|
||||
Tenant: up.Tenant,
|
||||
UserName: up.UserName,
|
||||
Masked: masked,
|
||||
Masked: properties.masked,
|
||||
Weight: properties.weight,
|
||||
Profile: oldM,
|
||||
}
|
||||
for key, value := range up.Profile {
|
||||
@@ -193,6 +197,7 @@ func (um *UserMap) UpdateUser(up UserProfile, reply *string) error {
|
||||
Tenant: up.Tenant,
|
||||
UserName: up.UserName,
|
||||
Masked: up.Masked,
|
||||
Weight: up.Weight,
|
||||
Profile: m,
|
||||
}
|
||||
if err := um.accountingDb.SetUser(finalUp); err != nil {
|
||||
@@ -200,9 +205,7 @@ func (um *UserMap) UpdateUser(up UserProfile, reply *string) error {
|
||||
return err
|
||||
}
|
||||
um.table[up.GetId()] = m
|
||||
if up.Masked == false {
|
||||
delete(um.masked, up.GetId())
|
||||
}
|
||||
um.properties[up.GetId()] = &prop{weight: up.Weight, masked: up.Masked}
|
||||
um.deleteIndex(oldUp)
|
||||
um.addIndex(finalUp, um.indexKeys)
|
||||
*reply = utils.OK
|
||||
@@ -247,7 +250,7 @@ func (um *UserMap) GetUsers(up UserProfile, results *UserProfiles) error {
|
||||
candidates := make(UserProfiles, 0) // It should not return nil in case of no users but []
|
||||
for key, values := range table {
|
||||
// skip masked if not asked for
|
||||
if up.Masked == false && um.masked[key] == true {
|
||||
if up.Masked == false && um.properties[key] != nil && um.properties[key].masked == true {
|
||||
continue
|
||||
}
|
||||
ponder := 0
|
||||
@@ -283,7 +286,10 @@ func (um *UserMap) GetUsers(up UserProfile, results *UserProfiles) error {
|
||||
// all filters passed, add to candidates
|
||||
nup := &UserProfile{
|
||||
Profile: make(map[string]string),
|
||||
Masked: um.masked[key],
|
||||
}
|
||||
if um.properties[key] != nil {
|
||||
nup.Masked = um.properties[key].masked
|
||||
nup.Weight = um.properties[key].weight
|
||||
}
|
||||
nup.SetId(key)
|
||||
nup.ponder = ponder
|
||||
|
||||
@@ -17,8 +17,19 @@ var testMap = UserMap{
|
||||
"test:masked": map[string]string{"t": "v"},
|
||||
},
|
||||
index: make(map[string]map[string]bool),
|
||||
masked: map[string]bool{
|
||||
"test:masked": true,
|
||||
properties: map[string]*prop{
|
||||
"test:masked": &prop{masked: true},
|
||||
},
|
||||
}
|
||||
|
||||
var testMap2 = UserMap{
|
||||
table: map[string]map[string]string{
|
||||
"an:u1": map[string]string{"a": "b", "c": "d"},
|
||||
"an:u2": map[string]string{"a": "b"},
|
||||
},
|
||||
index: make(map[string]map[string]bool),
|
||||
properties: map[string]*prop{
|
||||
"an:u2": &prop{weight: 10},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -304,6 +315,23 @@ func TestUsersGetMissingIdTwoSort(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsersGetMissingIdTwoSortWeight(t *testing.T) {
|
||||
up := UserProfile{
|
||||
Profile: map[string]string{
|
||||
"a": "b",
|
||||
"c": "d",
|
||||
},
|
||||
}
|
||||
results := UserProfiles{}
|
||||
testMap2.GetUsers(up, &results)
|
||||
if len(results) != 2 {
|
||||
t.Error("error getting users: ", results)
|
||||
}
|
||||
if results[0].GetId() != "an:u2" {
|
||||
t.Errorf("Error sorting profiles: %+v", results[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsersAddIndex(t *testing.T) {
|
||||
var r string
|
||||
testMap.AddIndex([]string{"t"}, &r)
|
||||
|
||||
@@ -345,6 +345,7 @@ type TPUsers struct {
|
||||
Masked bool
|
||||
UserName string
|
||||
Profile []*TPUserProfile
|
||||
Weight float64
|
||||
}
|
||||
|
||||
type TPUserProfile struct {
|
||||
|
||||
Reference in New Issue
Block a user