package main
import (
"fmt"
"strings"
"github.com/go-ldap/ldap/v3"
)
const default_users, default_groups = 1000, 1000
func Init() (*instance, error) {
inst, err := NewInstance(default_users, default_groups)
return inst, err
}
//Part to compare our datas
func (inst *instance) CompareOurDataWithConsul() (bool, error) {
if ok, err := inst.VerifyOurData(inst.dataUsers); !ok {
return false, err
}
if ok, err := inst.VerifyOurData(inst.dataGroups); !ok {
return false, err
}
return true, nil
}
func (inst *instance) VerifyOurData(tabData []data_DN) (bool, error) {
for _, value := range tabData {
names := getNamesAtt(value)
cn := strings.Split(value.DN, ",")[0]
res, err := inst.Search_Request(value.DN, fmt.Sprintf("(&(%s))", cn), names)
if err != nil {
return false, err
}
if len(res.Entries) != 1 {
return false, fmt.Errorf("expected 1 entry, but found %d entry/ies", len(res.Entries))
}
if !Compare(value, res.Entries[0]) {
return false, fmt.Errorf("no match with the DN: %s", value.DN)
}
}
return true, nil
}
func Compare(dat data_DN, ent *ldap.Entry) bool {
for _, value := range dat.Attributes {
logging.Debugf("Attributes from %s is now: %s.", dat.DN, dat.Attributes)
entVal := GetAttributeValuesBottin(ent, value.Name)
logging.Debugf("Values of the Entry: attributName: %s, Values: %s.", value.Name, entVal)
if !CompareSliceString(entVal, value.Data) {
logging.Debugf("Values expected: %s, values found: %s.", value.Data, entVal)
return false
}
}
return true
}
//Part modify datas
func (inst *instance) ModifyRandomAllData() error {
dg, err := inst.ModifyRandom(inst.dataGroups, []string{"description"})
if err != nil {
return err
} else {
inst.dataGroups = dg
}
dg, err = inst.ModifyRandom(inst.dataUsers, []string{"displayname"})
if err != nil {
return err
} else {
inst.dataUsers = dg
}
return nil
}
//Function which modify random way the attributes in attName of a data_DN's slice, it can delete, replace and delete
//The function modify also in the dat object
func (inst *instance) ModifyRandom(dat []data_DN, attName []string) ([]data_DN, error) {
for index, value := range dat {
del := make(map[string][]string)
add := make(map[string][]string)
replace := make(map[string][]string)
for _, att := range attName {
switch selNumber := R.Intn(3); selNumber {
case 0:
del[att] = []string{}
value = DelAtt(att, value)
logging.Debug(fmt.Sprintf("Delete the attribute %s of the DN %s.", att, value.DN))
case 1:
name := inst.GenerateName()
value = AddAtt(name, []string{name}, value)
add[name] = []string{name}
logging.Debug(fmt.Sprintf("Add the attribute %s with value %s of the DN %s.", name, name, value.DN))
case 2:
name := inst.GenerateName()
value = ReplaceAtt(att, []string{name}, value)
replace[att] = []string{name}
logging.Debug(fmt.Sprintf("Replace the attribute %s with value %s of the DN %s.", att, name, value.DN))
}
}
err := inst.Modify_Request(value.DN, add, del, replace)
if err != nil {
return dat, err
}
dat[index] = value
}
return dat, nil
}
//Add all users in a random group
func (inst *instance) AddAllUsersInGroup() error {
for _, value := range inst.dataGroups {
valueRand := (len(inst.dataUsers) + 1) / 30
if valueRand == 0 {
valueRand = 1
}
numberOfMembers := R.Intn(valueRand) + 1
logging.Debugf("%s will be have %d members.", value.DN, numberOfMembers)
groupMemory := make(map[int]struct{})
users_cn := []string{}
for i := 0; i < numberOfMembers; i++ {
selectGroup := R.Intn(len(inst.dataUsers))
for _, ok := groupMemory[selectGroup]; ok; _, ok = groupMemory[selectGroup] {
selectGroup = R.Intn(len(inst.dataUsers))
logging.Debugf("Search an other member. The value is %d , and we have %d members available.", selectGroup, len(inst.dataUsers))
}
groupMemory[selectGroup] = struct{}{}
users_cn = append(users_cn, inst.dataGroups[selectGroup].DN)
}
err := inst.AddUserSliceInGroup(users_cn, value.DN)
if err != nil {
return err
}
}
return nil
}
//Check if the groups in memberOf exist in Consul
func (inst *instance) CheckMemberOf() (bool, error) {
for _, value := range inst.dataUsers {
cn := strings.Split(value.DN, ",")[0]
res, err := inst.Search_Request(value.DN, fmt.Sprintf("(&(%s))", cn), []string{"memberOf"})
if err != nil {
return false, err
}
if len(res.Entries) != 1 {
return false, fmt.Errorf("expected 1 entry, but found %d entry/ies", len(res.Entries))
}
attValues := GetAttributeValuesBottin(res.Entries[0], "memberOf")
for _, dnGroup := range attValues {
logging.Debugf("Verify if the group %s exist...", dnGroup)
ok, err := inst.VerifyGroup(data_DN{DN: dnGroup})
if err != nil {
return false, err
}
if !ok {
return false, fmt.Errorf("don't found the group: %s", dnGroup)
}
}
}
return true, nil
}