package main import ( "crypto/tls" "fmt" "strconv" "strings" "github.com/go-ldap/ldap/v3" ) func fetchDataFromLDAP() ([]Person, error) { var l *ldap.Conn var err error // Port überprüfen und entsprechende Verbindung herstellen port, err := strconv.Atoi(ldapConfig.Port) if err != nil { return nil, fmt.Errorf("ungültiger Port: %v", err) } if port == 636 { // SSL/TLS-Verbindung für Port 636 l, err = ldap.DialTLS("tcp", ldapConfig.Server+":"+ldapConfig.Port, &tls.Config{InsecureSkipVerify: true}) if err != nil { return nil, fmt.Errorf("failed to connect to LDAP server (TLS): %v", err) } } else if port == 389 { // Unverschlüsselte Verbindung für Port 389 l, err = ldap.Dial("tcp", ldapConfig.Server+":"+ldapConfig.Port) if err != nil { return nil, fmt.Errorf("failed to connect to LDAP server: %v", err) } } else { return nil, fmt.Errorf("unsupported LDAP port: %s, use 389 for unencrypted or 636 for TLS/SSL", ldapConfig.Port) } defer l.Close() err = l.Bind(ldapConfig.BindDN, ldapConfig.BindPassword) if err != nil { return nil, fmt.Errorf("failed to bind to LDAP server: %v", err) } // Erweitere den Filter, um sowohl Benutzer als auch Kontakte einzuschließen combinedFilter := fmt.Sprintf("(|(objectClass=user)(objectClass=contact)%s)", ldapConfig.Filter) searchRequest := ldap.NewSearchRequest( ldapConfig.BaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, combinedFilter, []string{"objectClass", "givenName", "sn", "mail", "telephoneNumber", "mobile", "otherTelephone", "physicalDeliveryOfficeName"}, nil, ) sr, err := l.Search(searchRequest) if err != nil { return nil, fmt.Errorf("failed to search LDAP server: %v", err) } var people []Person for _, entry := range sr.Entries { if !isValidEntry(entry) { continue } isContact := isContactObject(entry) person := Person{ FirstName: entry.GetAttributeValue("givenName"), LastName: entry.GetAttributeValue("sn"), Email: entry.GetAttributeValue("mail"), Department: entry.GetAttributeValue("physicalDeliveryOfficeName"), IsContact: isContact, } officePhone := entry.GetAttributeValue("telephoneNumber") mobilePhone := entry.GetAttributeValue("mobile") // Normalisiere die Telefonnummern für den Vergleich normalizedOffice := normalizePhoneNumber(officePhone) normalizedMobile := normalizePhoneNumber(mobilePhone) if normalizedOffice == normalizedMobile && mobilePhone != "" { formattedMobile := formatPhoneNumber(mobilePhone) person.Phones = append(person.Phones, Phone{PhoneNumber: formattedMobile, Type: "Mobil"}) person.RawPhoneNumber = formattedMobile person.InternalPhone = "" // Keine interne Rufnummer für Mobiltelefone } else if officePhone != "" { formattedPhone := formatPhoneNumber(officePhone) person.Phones = append(person.Phones, Phone{PhoneNumber: formattedPhone, Type: "Office"}) person.InternalPhone = extractInternalNumber(officePhone) person.RawPhoneNumber = formattedPhone if mobilePhone != "" && normalizedOffice != normalizedMobile { formattedMobile := formatPhoneNumber(mobilePhone) person.Phones = append(person.Phones, Phone{PhoneNumber: formattedMobile, Type: "Mobil"}) } } else if mobilePhone != "" { formattedMobile := formatPhoneNumber(mobilePhone) person.Phones = append(person.Phones, Phone{PhoneNumber: formattedMobile, Type: "Mobil"}) person.RawPhoneNumber = formattedMobile person.InternalPhone = "" // Keine interne Rufnummer für Mobiltelefone } for _, otherPhone := range entry.GetAttributeValues("otherTelephone") { person.Phones = append(person.Phones, Phone{PhoneNumber: formatPhoneNumber(otherPhone), Type: "Other"}) } if (len(person.Phones) > 0 && person.Email != "") || isContact { people = append(people, person) } } return people, nil } func isValidEntry(entry *ldap.Entry) bool { firstName := entry.GetAttributeValue("givenName") lastName := entry.GetAttributeValue("sn") telephoneNumber := entry.GetAttributeValue("telephoneNumber") mobile := entry.GetAttributeValue("mobile") // Für Kontakte erlauben wir auch Einträge ohne Telefonnummer isContact := isContactObject(entry) return (firstName != "" && lastName != "") && (isContact || telephoneNumber != config.PhoneRules.InvalidNumber || mobile != "") } func isContactObject(entry *ldap.Entry) bool { objectClasses := entry.GetAttributeValues("objectClass") for _, class := range objectClasses { if strings.ToLower(class) == "contact" { return true } } return false } func isValidContact(entry *ldap.Entry) bool { firstName := entry.GetAttributeValue("givenName") lastName := entry.GetAttributeValue("sn") telephoneNumber := entry.GetAttributeValue("telephoneNumber") return firstName != "" && lastName != "" && telephoneNumber != config.PhoneRules.InvalidNumber }