Repository: go-gitea/gitea
File: models/user/user.go (Go)

Code before:
		return nil, ErrUserNotExist{}
	default:
		return GetUserByID(ctx, id)
	}
}

// GetUserByNameCtx returns user by given name.
func GetUserByName(ctx context.Context, name string) (*User, error) {
	if len(name) == 0 {
		return nil, ErrUserNotExist{0, name, 0}
	}
	u := &User{LowerName: strings.ToLower(name)}
	has, err := db.GetEngine(ctx).Get(u)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrUserNotExist{0, name, 0}
	}
	return u, nil
}

// GetUserEmailsByNames returns a list of e-mails corresponds to names of users
// that have their email notifications set to enabled or onmention.
func GetUserEmailsByNames(ctx context.Context, names []string) []string {
	mails := make([]string, 0, len(names))
	for _, name := range names {
		u, err := GetUserByName(ctx, name)
		if err != nil {
			continue
		}
		if u.IsMailable() && u.EmailNotifications() != EmailNotificationsDisabled {
			mails = append(mails, u.Email)
		}
	}
	return mails
}

// GetMaileableUsersByIDs gets users from ids, but only if they can receive mails
func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]*User, error) {
	if len(ids) == 0 {
		return nil, nil
	}
	ous := make([]*User, 0, len(ids))

	if isMention {
		return ous, db.GetEngine(ctx).
			In("id", ids).
			Where("`type` = ?", UserTypeIndividual).
			And("`prohibit_login` = ?", false).
			And("`is_active` = ?", true).
			In("`email_notifications_preference`", EmailNotificationsEnabled, EmailNotificationsOnMention, EmailNotificationsAndYourOwn).

Review comment (bug):
This change is wrong, 


* Before `GetUserByName` can be used to get a org owner.
* After: it's expected that only `Individual` can be found.
    * But the new logic is also wrong, Individual is 0 then it takes no effect.
    * So the bug of bug makes the existing code still can use GetUserByName to find an org
    * But all other types can also be found by GetUserByName



And that's why people keep  adding more and more buggy code like `GetUserOrOrgByName` in "Fix bug when creating pull request (#36166)"


@techknowlogick it needs a complete fix, or please revert if it's unable to fix.


<details>
<summary>
<strike>A real example is shown below, and I believe there are far more bugs</strike>
</summary>

<img width="1848" height="990" alt="image" src="https://github.com/user-attachments/assets/cd11ccdf-8a7f-4b6a-8695-7a3ff5dbf2eb" />
</details>

Code after:
	} else if !has {
		return nil, ErrUserNotExist{id, "", 0}
	}
	return u, nil
}

// GetPossibleUserByID returns the user if id > 0 or return system usrs if id < 0
func GetPossibleUserByID(ctx context.Context, id int64) (*User, error) {
	switch id {
	case -1:
		return NewGhostUser(), nil
	case ActionsUserID:
		return NewActionsUser(), nil
	case 0:
		return nil, ErrUserNotExist{}
	default:
		return GetUserByID(ctx, id)
	}
}

// GetUserByNameCtx returns user by given name.
func GetUserByName(ctx context.Context, name string) (*User, error) {
	if len(name) == 0 {
		return nil, ErrUserNotExist{0, name, 0}
	}
	u := &User{LowerName: strings.ToLower(name), Type: UserTypeIndividual}
	has, err := db.GetEngine(ctx).Get(u)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrUserNotExist{0, name, 0}
	}
	return u, nil
}

// GetUserEmailsByNames returns a list of e-mails corresponds to names of users
// that have their email notifications set to enabled or onmention.
func GetUserEmailsByNames(ctx context.Context, names []string) []string {
	mails := make([]string, 0, len(names))
	for _, name := range names {
		u, err := GetUserByName(ctx, name)
		if err != nil {
			continue
		}
		if u.IsMailable() && u.EmailNotifications() != EmailNotificationsDisabled {
			mails = append(mails, u.Email)
		}
	}
	return mails
}