fix: resolve --user-login by exact match

Redmine user.filter(login=...) performs an inexact substring search, but
_resolve_user_id took users[0].id unconditionally, so a report could
silently be built for the wrong user (e.g. 'ivanov' matching 'ivanov2').

Now only exact (case-sensitive) login matches are considered: exactly one
match resolves to its id, multiple matches raise an ambiguity error,
no match falls through to the name lookup and then to a 'not found'
error — symmetric with the --user-name resolution.

Closes #60
This commit is contained in:
Кокос Артем Николаевич
2026-07-17 12:21:47 +07:00
parent 46674ba926
commit 598f2d35a1
2 changed files with 98 additions and 2 deletions

View File

@@ -205,8 +205,18 @@ def _resolve_user_id(redmine: Redmine, user_arg: Union[int, str]) -> int:
# Затем ищем по логину
try:
users = redmine.user.filter(login=text)
if users:
return int(users[0].id)
# Фильтр Redmine по логину неточный (substring-поиск), поэтому
# выбираем только точные регистрозависимые совпадения логина (#60).
exact_matches = [u for u in users if getattr(u, "login", None) == text]
if len(exact_matches) == 1:
return int(exact_matches[0].id)
if len(exact_matches) > 1:
matches = ", ".join(str(u.id) for u in exact_matches[:5])
raise RedmineAPIError(
f"Multiple users match '{text}': {matches}. Use --user-id with numeric ID."
)
except RedmineAPIError:
raise
except Exception as exc:
raise RedmineAPIError(
f"Cannot resolve user login '{text}': {_format_redmine_error(exc)}",