Implement username field protection

man 8 useradd says:

    It is usually recommended to only use usernames that begin with a
    lower case letter or an underscore, followed by lower case
    letters, digits, underscores, or dashes. They can end with a
    dollar sign. In regular expression terms: [a-z_][a-z0-9_-]*[$]?

    On Debian, the only constraints are that usernames must neither
    start with a dash ('-') nor plus ('+') nor tilde ('~') nor
    contain a colon (':'), a comma (','), or a whitespace (space: ' ',
    end of line: '\n', tabulation: '\t', etc.).  Note that using a
    slash ('/') may break the default algorithm for the definition
    of the user's home directory.

    Usernames may only be up to 32 characters long.

In this patch we implement most of this.  Subset of the regular
expression suggested above is used to limit input into the username
field.  We've not yet determined how to provide a fixed width widget
so at this time, user can input more than 32 characters, but upon
selectin done, we raise and error and reset the state.

Signed-off-by: Ryan Harper <ryan.harper@canonical.com>
This commit is contained in:
Ryan Harper 2015-10-23 15:21:13 -05:00
parent e8fb26f982
commit 1de06aa63e
2 changed files with 31 additions and 2 deletions

View File

@ -18,6 +18,7 @@
from urwid import (Edit, IntEdit, RadioButton, WidgetWrap)
import logging
import re
log = logging.getLogger("subiquity.ui.input")
@ -59,6 +60,26 @@ class PasswordEditor(StringEditor):
super().__init__(caption, mask=mask)
class UsernameEditor(StringEditor):
""" Username input prompt with input rules
"""
def keypress(self, size, key):
''' restrict what chars we allow for username '''
userlen = len(self.value)
if userlen == 0:
username = r'[a-z_]'
else:
username = r'[a-z0-9_-]'
# don't allow non username chars
if re.match(username, key) is None:
return False
return super().keypress(size, key)
class IntegerEditor(WidgetWrap):
""" IntEdit input class
"""

View File

@ -21,7 +21,9 @@ Welcome provides user with language selection
import logging
from urwid import (Pile, Columns, Text, ListBox)
from subiquity.ui.buttons import done_btn, cancel_btn
from subiquity.ui.interactive import StringEditor, PasswordEditor
from subiquity.ui.interactive import (PasswordEditor,
StringEditor,
UsernameEditor)
from subiquity.ui.utils import Padding, Color
from subiquity.view import ViewPolicy
@ -34,7 +36,7 @@ class IdentityView(ViewPolicy):
self.signal = signal
self.items = []
self.realname = StringEditor(caption="")
self.username = StringEditor(caption="")
self.username = UsernameEditor(caption="")
self.password = PasswordEditor(caption="")
self.error = Text("", align="center")
self.confirm_password = PasswordEditor(caption="")
@ -105,6 +107,12 @@ class IdentityView(ViewPolicy):
self.password.value = ""
self.confirm_password.value = ""
return
if len(self.username.value) > 32:
self.error.set_text("Username too long, must be < 32")
self.username.value = ""
return
cpassword = self.model.encrypt_password(self.password.value)
log.debug("*crypted* User input: {} {} {}".format(
self.username.value, cpassword, cpassword))