fix(a54): reject empty credentials before slot allocation
This commit is contained in:
parent
ddeba2db0e
commit
b58bfc6c77
3 changed files with 12 additions and 2 deletions
|
|
@ -739,6 +739,9 @@ class ActionExecutor:
|
||||||
valid, reason = AutoAssigner.validate_slot(prov_norm, slot)
|
valid, reason = AutoAssigner.validate_slot(prov_norm, slot)
|
||||||
if not valid:
|
if not valid:
|
||||||
return {'ok': False, 'message': reason}
|
return {'ok': False, 'message': reason}
|
||||||
|
existing_status = ProfileAuthManager.get_profile_status(prov_norm, slot) if slot else {}
|
||||||
|
if not token and prov_norm not in ('local', 'vllm', 'ollama') and not existing_status.get('authenticated'):
|
||||||
|
return {'ok': False, 'message': 'Не указан API-ключ или не завершена авторизация'}
|
||||||
validation = None
|
validation = None
|
||||||
if token or prov_norm in ('local', 'vllm', 'ollama'):
|
if token or prov_norm in ('local', 'vllm', 'ollama'):
|
||||||
from .connection_preflight import validate_connection
|
from .connection_preflight import validate_connection
|
||||||
|
|
|
||||||
|
|
@ -864,9 +864,9 @@ function renderAccountCheck(profile) {
|
||||||
${checking ? `<p>${escapeHtml(profile.display_name || profile.profile_id)}: идёт опрос провайдера, это может занять до минуты на этап.</p>` : ''}
|
${checking ? `<p>${escapeHtml(profile.display_name || profile.profile_id)}: идёт опрос провайдера, это может занять до минуты на этап.</p>` : ''}
|
||||||
<p>${escapeHtml(check.message || "Подключение ещё не проверялось")}</p>
|
<p>${escapeHtml(check.message || "Подключение ещё не проверялось")}</p>
|
||||||
<p>${escapeHtml(modelStatus)}</p>
|
<p>${escapeHtml(modelStatus)}</p>
|
||||||
<div class="account-models">${models.map(modelBrandLabel).join('')}</div>
|
<details ${models.length <= 16 ? 'open' : ''}><summary>Каталог моделей (${models.length})</summary><div class="account-models">${models.map(modelBrandLabel).join('')}</div></details>
|
||||||
${profile.provider === 'ollama' ? `<p>Выше — модели указанного сервера Ollama.</p><p>Облачный каталог Ollama: ${meta.cloud?.error ? 'Н/Д — ' + escapeHtml(meta.cloud.error) : meta.cloud?.models ? escapeHtml(meta.cloud.models.join(', ')) : 'Н/Д — ещё не получен'}</p><p>Доступ аккаунта к облачным моделям: Н/Д до успешного вызова. Для прямого вызова нужен API-ключ Ollama; для локального клиента — вход через ollama signin.</p>` : ''}
|
${profile.provider === 'ollama' ? `<p>Выше — модели указанного сервера Ollama.</p><p>Облачный каталог Ollama: ${meta.cloud?.error ? 'Н/Д — ' + escapeHtml(meta.cloud.error) : meta.cloud?.models ? escapeHtml(meta.cloud.models.join(', ')) : 'Н/Д — ещё не получен'}</p><p>Доступ аккаунта к облачным моделям: Н/Д до успешного вызова. Для прямого вызова нужен API-ключ Ollama; для локального клиента — вход через ollama signin.</p>` : ''}
|
||||||
<button class="btn btn-ghost btn-sm" ${checking ? 'disabled' : ''} onclick="event.stopPropagation(); handleAccountProbe('${escapeHtml(profile.profile_id)}')">${checking ? 'Проверяется…' : 'Проверить подключение и модели'}</button>
|
<button class="btn btn-ghost btn-sm" ${checking ? 'disabled' : ''} onclick="event.stopPropagation(); handleAccountProbe('${escapeHtml(profile.profile_id)}')">${checking ? 'Проверяется…' : 'Проверить подключение'}</button>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,3 +240,10 @@ def test_bulk_protects_symlink_into_ag(services, tmp_path):
|
||||||
assert preview['data']['targets'] == []
|
assert preview['data']['targets'] == []
|
||||||
assert ActionExecutor.execute('clear_accounts', {'confirmed': True, 'targets': []})['ok']
|
assert ActionExecutor.execute('clear_accounts', {'confirmed': True, 'targets': []})['ok']
|
||||||
assert target.read_text() == 'protected fixture'
|
assert target.read_text() == 'protected fixture'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('provider', ['openrouter', 'nvidia', 'claude'])
|
||||||
|
def test_empty_key_never_allocates_slot(services, provider):
|
||||||
|
result = ActionExecutor.execute('add_account', {'provider': provider, 'token': ''})
|
||||||
|
assert not result['ok'] and result['message']
|
||||||
|
assert not load_router_config().profiles
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue