ssh: add identity table with ability to remove key
A new table shows all the SSH identities/keys that are currently imported. The user can select one and delete it from the list if he wants to. Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This commit is contained in:
parent
446bf3814d
commit
feaf0601d3
|
@ -21,12 +21,21 @@ from urwid import LineBox, Text, connect_signal
|
||||||
|
|
||||||
from subiquity.common.types import SSHData, SSHIdentity
|
from subiquity.common.types import SSHData, SSHIdentity
|
||||||
from subiquity.ui.views.identity import UsernameField
|
from subiquity.ui.views.identity import UsernameField
|
||||||
|
from subiquitycore.ui.actionmenu import Action, ActionMenu
|
||||||
from subiquitycore.ui.buttons import cancel_btn, menu_btn, ok_btn
|
from subiquitycore.ui.buttons import cancel_btn, menu_btn, ok_btn
|
||||||
from subiquitycore.ui.container import ListBox, Pile, WidgetWrap
|
from subiquitycore.ui.container import ListBox, Pile, WidgetWrap
|
||||||
from subiquitycore.ui.form import BooleanField, ChoiceField, Form, Toggleable
|
from subiquitycore.ui.form import BooleanField, ChoiceField, Form, Toggleable
|
||||||
from subiquitycore.ui.spinner import Spinner
|
from subiquitycore.ui.spinner import Spinner
|
||||||
from subiquitycore.ui.stretchy import Stretchy
|
from subiquitycore.ui.stretchy import Stretchy
|
||||||
from subiquitycore.ui.utils import SomethingFailed, button_pile, screen
|
from subiquitycore.ui.table import ColSpec, TablePile, TableRow
|
||||||
|
from subiquitycore.ui.utils import (
|
||||||
|
Color,
|
||||||
|
Padding,
|
||||||
|
SomethingFailed,
|
||||||
|
button_pile,
|
||||||
|
make_action_menu_row,
|
||||||
|
screen,
|
||||||
|
)
|
||||||
from subiquitycore.view import BaseView
|
from subiquitycore.view import BaseView
|
||||||
|
|
||||||
log = logging.getLogger("subiquity.ui.views.ssh")
|
log = logging.getLogger("subiquity.ui.views.ssh")
|
||||||
|
@ -222,6 +231,7 @@ class ConfirmSSHKeys(Stretchy):
|
||||||
def ok(self, sender):
|
def ok(self, sender):
|
||||||
for identity in self.identities:
|
for identity in self.identities:
|
||||||
self.parent.add_key_to_table(identity.to_authorized_key())
|
self.parent.add_key_to_table(identity.to_authorized_key())
|
||||||
|
self.parent.refresh_keys_table()
|
||||||
|
|
||||||
self.parent.remove_overlay()
|
self.parent.remove_overlay()
|
||||||
|
|
||||||
|
@ -253,9 +263,22 @@ class SSHView(BaseView):
|
||||||
bp = button_pile([self._import_key_btn])
|
bp = button_pile([self._import_key_btn])
|
||||||
bp.align = "left"
|
bp.align = "left"
|
||||||
|
|
||||||
|
colspecs = {
|
||||||
|
0: ColSpec(rpad=1),
|
||||||
|
1: ColSpec(can_shrink=True),
|
||||||
|
2: ColSpec(rpad=1),
|
||||||
|
3: ColSpec(rpad=1),
|
||||||
|
}
|
||||||
|
self.keys_table = TablePile([], colspecs=colspecs)
|
||||||
|
self.refresh_keys_table()
|
||||||
|
|
||||||
rows = self.form.as_rows() + [
|
rows = self.form.as_rows() + [
|
||||||
Text(""),
|
Text(""),
|
||||||
bp,
|
bp,
|
||||||
|
Text(""),
|
||||||
|
Text(_("AUTHORIZED KEYS")),
|
||||||
|
Text(""),
|
||||||
|
self.keys_table,
|
||||||
]
|
]
|
||||||
|
|
||||||
connect_signal(self.form, "submit", self.done)
|
connect_signal(self.form, "submit", self.done)
|
||||||
|
@ -307,6 +330,62 @@ class SSHView(BaseView):
|
||||||
if self.form.install_server:
|
if self.form.install_server:
|
||||||
self.form.pwauth.enabled = True
|
self.form.pwauth.enabled = True
|
||||||
|
|
||||||
|
def remove_key_from_table(self, key: str) -> None:
|
||||||
|
"""Remove the specified key from the list of authorized keys. When
|
||||||
|
removing the last one, we also re-enable password authentication (and
|
||||||
|
disable the checkbox)."""
|
||||||
|
self.keys.remove(key)
|
||||||
|
if not self.keys:
|
||||||
|
self.form.pwauth.value = True
|
||||||
|
self.form.pwauth.enabled = False
|
||||||
|
|
||||||
|
def refresh_keys_table(self):
|
||||||
|
rows: List[TableRow] = []
|
||||||
|
|
||||||
|
if not self.keys:
|
||||||
|
rows = [
|
||||||
|
TableRow(
|
||||||
|
[
|
||||||
|
(
|
||||||
|
4,
|
||||||
|
Padding.push_2(
|
||||||
|
Color.info_minor(Text(_("No authorized key")))
|
||||||
|
),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
for key in self.keys:
|
||||||
|
menu = ActionMenu(
|
||||||
|
[
|
||||||
|
Action(
|
||||||
|
label=_("Delete"),
|
||||||
|
enabled=True,
|
||||||
|
value=(None,),
|
||||||
|
opens_dialog=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
rows.append(
|
||||||
|
make_action_menu_row(
|
||||||
|
[
|
||||||
|
Text("["),
|
||||||
|
Text(key, wrap="ellipsis"),
|
||||||
|
menu,
|
||||||
|
Text("]"),
|
||||||
|
],
|
||||||
|
menu,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
connect_signal(menu, "action", self._action, key)
|
||||||
|
|
||||||
|
self.keys_table.set_contents(rows)
|
||||||
|
|
||||||
|
def _action(self, sender, value, key):
|
||||||
|
self.remove_key_from_table(key)
|
||||||
|
self.refresh_keys_table()
|
||||||
|
|
||||||
def _toggle_server(self, sender, installed: bool):
|
def _toggle_server(self, sender, installed: bool):
|
||||||
self._import_key_btn.enabled = installed
|
self._import_key_btn.enabled = installed
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue