forked from Deuxfleurs/bottin
174 lines
4.8 KiB
Go
174 lines
4.8 KiB
Go
|
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
|
||
|
}
|