Esempio n. 1
0
// List the LDAP users
func (a Authorizer) ListExternalUsers(search string, page, count int) (externalUsers models.ExternalUsers, err error) {
	directory, err := a.GetDirectory()
	if err != nil {
		return externalUsers, err
	}
	url := GetUrl(directory.LdapServer, directory.Port)
	DisplayName := "DisplayName"
	FirstName := "CN"
	LastName := "SN"
	Email := "mail"
	if directory.DisplayName != "" {
		DisplayName = directory.DisplayName
	}
	if directory.FirstName != "" {
		FirstName = directory.FirstName
	}
	if directory.LastName != "" {
		LastName = directory.LastName
	}
	if directory.Email != "" {
		Email = directory.Email
	}

	ldap, err := openldap.Initialize(url)
	if err != nil {
		logger.Get().Error("failed to connect the LDAP/AD server. error: %v", err)
		return externalUsers, err
	}

	if directory.DomainAdmin != "" {
		block, err := aes.NewCipher([]byte(CipherKey))
		if err != nil {
			logger.Get().Error("failed to generate new cipher")
			return externalUsers, nil
		}

		ciphertext := []byte(directory.Password)
		iv := ciphertext[:aes.BlockSize]
		stream := cipher.NewOFB(block, iv)
		hkey := make([]byte, 100)
		stream = cipher.NewOFB(block, iv)
		stream.XORKeyStream(hkey, ciphertext[aes.BlockSize:])
		err = ldap.Bind(fmt.Sprintf("%s=%s,%s", directory.Uid, directory.DomainAdmin, directory.Base), string(hkey))
		if err != nil {
			logger.Get().Error("Error binding to LDAP Server:%s. error: %v", url, err)
			return externalUsers, err
		}
	}

	scope := openldap.LDAP_SCOPE_SUBTREE
	// If the search string is empty, it will list all the users
	// If the search string contains 'mail=tjey*' it will returns the list of all
	// users start with 'tjey'
	// If the search string contains 'tim' this will return list of all users
	// names contains the word 'tim'
	// Possible search strings 'mail=t*redhat.com' / 'tim*' / '*john*' / '*peter'
	filter := "(objectclass=*)"
	if len(search) > 0 {
		if strings.Contains(search, "=") {
			filter = fmt.Sprintf("(%s*)", search)
		} else if strings.Contains(search, "*") {
			filter = fmt.Sprintf("(%s=%s)", directory.Uid, search)
		} else {
			filter = fmt.Sprintf("(%s=*%s*)", directory.Uid, search)
		}
	}

	attributes := []string{directory.Uid, DisplayName, FirstName, LastName, Email}
	rv, err := ldap.SearchAll(directory.Base, scope, filter, attributes)

	if err != nil {
		logger.Get().Error("Failed to search LDAP/AD server. error: %v", err)
		return externalUsers, err
	}

	from := (page-1)*count + 1
	to := from + count - 1
	i := 0

	for _, entry := range rv.Entries() {
		i++
		if i < from {
			continue
		}
		if i > to {
			break
		}
		user := models.User{}
		for _, attr := range entry.Attributes() {
			switch attr.Name() {
			case directory.Uid:
				user.Username = strings.Join(attr.Values(), ", ")
			case Email:
				user.Email = strings.Join(attr.Values(), ", ")
			// Some setup may have an attribute like mail or email
			// or operator can't be used between strings to combind cases
			case "email":
				user.Email = strings.Join(attr.Values(), ", ")
			case FirstName:
				user.FirstName = strings.Join(attr.Values(), ", ")
			case LastName:
				user.LastName = strings.Join(attr.Values(), ", ")
			}
		}
		// Assiging the default roles
		user.Role = a.defaultRole
		user.Groups = append(user.Groups, a.defaultGroup)
		user.Type = authprovider.External
		if len(user.Username) != 0 {
			externalUsers.Users = append(externalUsers.Users, user)
		}
	}
	externalUsers.TotalCount = rv.Count()
	externalUsers.StartIndex = from
	externalUsers.EndIndex = to
	if externalUsers.EndIndex > externalUsers.TotalCount {
		externalUsers.EndIndex = externalUsers.TotalCount
	}
	return externalUsers, nil
}