diff --git a/subiquity/controllers/__init__.py b/subiquity/controllers/__init__.py
index 3b0cad26..fa7e1d85 100644
--- a/subiquity/controllers/__init__.py
+++ b/subiquity/controllers/__init__.py
@@ -18,3 +18,4 @@ from .installpath import InstallpathController
from .network import NetworkController
from .filesystem import FilesystemController
from .installprogress import InstallProgressController
+from .identity import IdentityController
diff --git a/subiquity/controllers/filesystem.py b/subiquity/controllers/filesystem.py
index fbcf9bac..b510b4e4 100644
--- a/subiquity/controllers/filesystem.py
+++ b/subiquity/controllers/filesystem.py
@@ -56,6 +56,7 @@ class FilesystemController(ControllerPolicy):
curtin_write_storage_actions(actions=actions)
log.info("Generating post-install config")
curtin_write_postinst_config()
+ urwid.emit_signal(self.signal, 'identity:show')
# self.install_progress()
# Filesystem/Disk partition -----------------------------------------------
diff --git a/subiquity/controllers/identity.py b/subiquity/controllers/identity.py
new file mode 100644
index 00000000..54842439
--- /dev/null
+++ b/subiquity/controllers/identity.py
@@ -0,0 +1,33 @@
+# Copyright 2015 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+from subiquity.controller import ControllerPolicy
+from subiquity.models import IdentityModel
+from subiquity.ui.views import IdentityView
+
+
+class IdentityController(ControllerPolicy):
+ def __init__(self, ui, signal):
+ self.ui = ui
+ self.signal = signal
+ self.model = IdentityModel()
+
+ def identity(self):
+ title = "Profile setup"
+ excerpt = ("Input your username and password to log in to the system.")
+ footer = ""
+ self.ui.set_header(title, excerpt)
+ self.ui.set_footer(footer)
+ self.ui.set_body(IdentityView(self.model, self.signal))
diff --git a/subiquity/core.py b/subiquity/core.py
index 35645dcc..5b96a901 100644
--- a/subiquity/core.py
+++ b/subiquity/core.py
@@ -24,6 +24,7 @@ from subiquity.controllers import (WelcomeController,
InstallpathController,
NetworkController,
FilesystemController,
+ IdentityController,
InstallProgressController)
log = logging.getLogger('subiquity.core')
@@ -44,6 +45,7 @@ class Controller:
"installpath": InstallpathController(self.ui, self.signal),
"network": NetworkController(self.ui, self.signal),
"filesystem": FilesystemController(self.ui, self.signal),
+ "identity": IdentityController(self.ui, self.signal),
"progress": InstallProgressController(self.ui, self.signal),
}
self._connect_base_signals()
diff --git a/subiquity/models/__init__.py b/subiquity/models/__init__.py
index 5a9f1262..15dff962 100644
--- a/subiquity/models/__init__.py
+++ b/subiquity/models/__init__.py
@@ -17,3 +17,4 @@ from .filesystem import FilesystemModel
from .installpath import InstallpathModel
from .network import NetworkModel
from .welcome import WelcomeModel
+from .identity import IdentityModel
diff --git a/subiquity/models/identity.py b/subiquity/models/identity.py
index 471780ff..2d3ac415 100644
--- a/subiquity/models/identity.py
+++ b/subiquity/models/identity.py
@@ -44,11 +44,6 @@ class IdentityModel(ModelPolicy):
"validate_confirm_password")
]
- username = None
- password = None
- confirm_password = None
- encrypted_password = None
-
def get_signals(self):
return self.signals
diff --git a/subiquity/ui/interactive.py b/subiquity/ui/interactive.py
index cb4af229..a4434d60 100644
--- a/subiquity/ui/interactive.py
+++ b/subiquity/ui/interactive.py
@@ -37,6 +37,13 @@ class StringEditor(WidgetWrap):
return self._edit.get_edit_text()
+class PasswordEditor(StringEditor):
+ """ Password input prompt with masking
+ """
+ def __init__(self, caption, mask="*"):
+ super().__init__(caption, mask=mask)
+
+
class IntegerEditor(WidgetWrap):
""" IntEdit input class
"""
diff --git a/subiquity/ui/views/__init__.py b/subiquity/ui/views/__init__.py
index fcb66f7c..b32df8f7 100644
--- a/subiquity/ui/views/__init__.py
+++ b/subiquity/ui/views/__init__.py
@@ -18,3 +18,4 @@ from .network import NetworkView
from .installpath import InstallpathView
from .installprogress import ProgressOutput, ProgressView
from .welcome import WelcomeView
+from .identity import IdentityView
diff --git a/subiquity/ui/views/identity.py b/subiquity/ui/views/identity.py
new file mode 100644
index 00000000..52de0c12
--- /dev/null
+++ b/subiquity/ui/views/identity.py
@@ -0,0 +1,79 @@
+# Copyright 2015 Canonical, Ltd.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+""" Welcome
+
+Welcome provides user with language selection
+
+"""
+import logging
+from urwid import (Pile, emit_signal)
+from subiquity.ui.widgets import Box
+from subiquity.ui.buttons import done_btn, cancel_btn
+from subiquity.ui.interactive import StringEditor, PasswordEditor
+from subiquity.ui.utils import Padding, Color
+from subiquity.view import ViewPolicy
+
+log = logging.getLogger("subiquity.views.identity")
+
+
+class IdentityView(ViewPolicy):
+ def __init__(self, model, signal):
+ self.model = model
+ self.signal = signal
+ self.items = []
+ self.username = StringEditor(caption="Username: ")
+ self.password = PasswordEditor(caption="Password: ")
+ self.confirm_password = PasswordEditor(caption="Confirm Password: ")
+
+ body = [
+ Padding.center_79(self._build_model_inputs()),
+ Padding.line_break(""),
+ Padding.center_20(self._build_buttons()),
+ ]
+ super().__init__(Box(body))
+
+ def _build_buttons(self):
+ cancel = cancel_btn(on_press=self.cancel)
+ done = done_btn(on_press=self.done)
+
+ buttons = [
+ Color.button_secondary(cancel, focus_map='button_secondary focus'),
+ Color.button_secondary(done, focus_map='button_secondary focus')
+ ]
+ return Pile(buttons)
+
+ def _build_model_inputs(self):
+ sl = [
+ self.username,
+ self.password,
+ self.confirm_password
+ ]
+ return Pile(sl)
+
+ def done(self, result):
+ log.debug("User input: {} {} {}".format(self.username.value,
+ self.password.value,
+ self.confirm_password.value))
+ result = {
+ "username": self.username.value,
+ "password": self.password.value,
+ "confirm_password": self.confirm_password.value
+ }
+ log.debug("User input: {}".format(result))
+ # emit_signal(self.signal, 'installpath:show')
+
+ def cancel(self, button):
+ self.signal.emit_signal("quit")