Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/specifications/secret-backend.md
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ TUI の「OpenBao の接続設定」は同じプロセスの中から `use openb
| 欄 | 接続先(`url`、1 行)、`role_id` と `secret_id`(伏せ字)。空の欄は変えない(`use` の引き継ぎ)。`role_id` を変えるときは `secret_id` も要る。`mount` / `user` / `layout` / `group_aliases` / キャッシュの設定は変えない |
| 保存の後 | `test` と同じ確認を自動で行う。失敗しても保存した設定は残し、欄を入れ直せる。`use` が失敗したら `test` を呼ばずに欄へ戻る |
| 確認のグループ | グループ別の置き場(`version: 2`・`layout: group`)で、TUI の現在地(`PWD`)がプロジェクトの外のときだけ、保存の後・確認の直前に対象のグループを選ばせ、`test` へ属性 `group`(CLI の `--group` と同じ)で渡す。選択は sync / init と同じ部品(`actions_env._group_attrs`。候補は宣言済みのグループと「名前を入力」)。プロジェクトの中では選ばせず、`test` がグループの宣言から決める。`version: 1` では選ばせず `group` を渡さない |
| 使えないグループ名 | 「名前を入力」の名前は `validate_account_group` で検証し、通らなければ「--group に使えない名前です: ...」を出してグループの選択へ戻る(`test` を呼ばない)。この規則を通る予約語の `global` / `projects` は選択では拒まず、`test` が `storage_group` の検証で 2 を返し、確認の失敗(警告と入れ直しの問い)になる |
| 使えないグループ名 | 「名前を入力」の名前は `validate_account_group` で検証し、続けて CLI の `--group` と同じ `storage_group` の検査(置き場の予約語 `global` / `projects`、`group_aliases` の読み替え先)を通す。どちらかで落ちれば「--group に使えない名前です: ...」を出してグループの選択へ戻る(`test` を呼ばない)。sync / init の選択も同じ部品を通る |
| グループの選択で戻る | Esc・← で「接続を確かめずに戻ります。保存した設定は残っています。」を出し、`test` を呼ばず、入れ直しの問いも出さずに env メニューへ戻る(`ARG_CANCEL`。一時停止しない)。Ctrl-C は TUI 全体を終える |
| 入れ直した後 | 入れ直しの問いで「はい」を選ぶと欄へ戻り、次に保存した後でもう一度グループを選ぶ |
| token | 入力させず、保存しない(実行のたびにブートストラップ機密で取り直す) |
Expand Down Expand Up @@ -1566,8 +1566,8 @@ groups:
(`--group` を付けて CLI から打ったときと同じ参照)
- 同じ条件で認証に失敗すると、グループを選んだ後に警告と入れ直しの問いが出て、保存した `secret_id` が残ること
- グループの選択で戻ると `test` を呼ばずに `ARG_CANCEL` で戻り、保存した設定が残って入れ直しの問いが出ないこと
- 「名前を入力」に `validate_account_group` で落ちる名前を入れると「--group に使えない名前です」が出て
グループの選択へ戻ること
- 「名前を入力」に `validate_account_group` で落ちる名前(`default` など)や置き場の予約語 `global` /
`projects` を入れると「--group に使えない名前です」が出て、`test` を呼ばずにグループの選択へ戻ること
- プロジェクトの中ではグループの選択が出ず、宣言のグループの置き場を読んで成功すること
- `version: 1` ではグループの選択が出ず、`test` が `group` なしで呼ばれること
- `version: 2` の端末で `DEVBASE_ROOT` から TUI の接続設定を保存し、グループを選ぶと「読めた参照」が出て
Expand Down
10 changes: 8 additions & 2 deletions lib/devbase/tui/actions_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,28 @@ def _group_attrs(devbase_root: Path) -> dict:

それ以外の設定では ``{}`` (グループの選択を出さずに今どおり実行する)。設定が読めない
ときも ``{}`` で委譲し、委譲先のコマンドが誤りを出す。使えない名前を入れたら、
``--group`` と同じ検証の文を出して選択へ戻る。
``--group`` と同じ検証の文を出して選択へ戻る。名前の規則に加えて、``--group`` と同じく
置き場のグループ名の検査 (``storage_group``: 予約語 ``global`` / ``projects`` と
``group_aliases`` の読み替え先) も通し、通らない名前は委譲先へ渡さない。
"""
from devbase.env.secret_store import SecretStore
from devbase.errors import DevbaseError
from devbase.volume.manager import validate_account_group

keys_screen = _screen("actions_env_keys")
try:
grouped = keys_screen._grouped(devbase_root)
settings = SecretStore(devbase_root).config.openbao if grouped else None
except DevbaseError:
return {}
if not grouped:
return {}
while True:
name = keys_screen._select_group(devbase_root)
try:
return {"group": validate_account_group(name)}
name = validate_account_group(name)
settings.storage_group(name)
return {"group": name}
except DevbaseError as e:
logger.error("--group に使えない名前です: %s", e)

Expand Down
20 changes: 20 additions & 0 deletions tests/cli/tui/test_actions_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,23 @@ def test_grouped_sync_reasks_for_an_unusable_typed_name(monkeypatch, tmp_path, c

assert captured['attrs'] == {'subcommand': 'sync', 'group': 'personal'}
assert 'default' in caplog.text


@pytest.mark.parametrize('op', ['sync', 'init'])
@pytest.mark.parametrize('reserved', ['global', 'projects'])
def test_grouped_sync_and_init_reask_for_a_reserved_storage_group(monkeypatch, tmp_path, caplog,
op, reserved):
"""#397: 置き場の予約語は --group と同じ検証の文を出して選択へ戻り、委譲先へ渡さない"""
from devbase.tui import actions_env_keys

_grouped_root(tmp_path)
captured = _capture_dispatch(monkeypatch)
picks = iter([actions_env_keys.TYPE_GROUP, 'acme'])
monkeypatch.setattr(menu, 'select', lambda *a, **k: next(picks))
monkeypatch.setattr(menu, 'text', lambda *a, **k: reserved)

assert actions_env._run_operation(tmp_path, op) == 0

assert captured['attrs']['group'] == 'acme'
assert '--group に使えない名前です' in caplog.text
assert f"'{reserved}' は置き場のグループ名に使えません" in caplog.text
27 changes: 27 additions & 0 deletions tests/cli/tui/test_actions_env_openbao.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,3 +281,30 @@ def test_a_flat_layout_checks_without_a_group(openbao_root, openbao, monkeypatch
assert rc == 0
assert seen == [None]
assert not script.messages('select')


@pytest.mark.parametrize('reserved', ['global', 'projects'])
def test_a_reserved_storage_group_returns_to_the_selection(grouped, openbao, monkeypatch, caplog,
reserved):
"""#397: 置き場の予約語は test へ渡さず、--group と同じ検証の文を出して選択へ戻る"""
from devbase.tui.actions_env_keys import TYPE_GROUP

groups = []
real_test = env_backend.cmd_env_backend_test

def spy(root, *, group=None):
groups.append(group)
return real_test(root, group=group)

monkeypatch.setattr(env_backend, 'cmd_env_backend_test', spy)
script = Script(monkeypatch, text=[local_url(openbao), reserved], secret=['', ''],
select=[TYPE_GROUP, 'acme'])

rc, out = run(grouped)

assert rc == 0
assert '--group に使えない名前です' in logs(caplog)
assert f"'{reserved}' は置き場のグループ名に使えません" in logs(caplog)
assert len(script.messages('select')) == 2
assert reserved not in groups
assert '読めた参照' in out
Loading