186 lines
5.2 KiB
Python
186 lines
5.2 KiB
Python
import re
|
|
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "4.0")
|
|
gi.require_version("Adw", "1")
|
|
from gi.repository import Adw, GObject, Gtk
|
|
|
|
|
|
class UserPage(Adw.Bin):
|
|
__gsignals__ = {
|
|
"validity-changed": (GObject.SignalFlags.RUN_FIRST, None, (bool,)),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self._is_valid = False
|
|
|
|
clamp = Adw.Clamp()
|
|
clamp.set_maximum_size(500)
|
|
self.set_child(clamp)
|
|
|
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
box.set_spacing(24)
|
|
box.set_valign(Gtk.Align.CENTER)
|
|
box.set_margin_top(24)
|
|
box.set_margin_bottom(24)
|
|
clamp.set_child(box)
|
|
|
|
title = Gtk.Label(label="Create User Account")
|
|
title.add_css_class("title-1")
|
|
box.append(title)
|
|
|
|
# Form Group
|
|
group = Adw.PreferencesGroup()
|
|
box.append(group)
|
|
|
|
self.fullname_row = Adw.EntryRow()
|
|
self.fullname_row.set_title("Full Name")
|
|
self.fullname_row.set_text("Administrator")
|
|
self.fullname_row.connect("notify::text", self.on_fullname_changed)
|
|
self.fullname_row.connect("notify::text", self.on_input_changed)
|
|
group.add(self.fullname_row)
|
|
|
|
self.username_row = Adw.EntryRow()
|
|
self.username_row.set_title("Username")
|
|
self.username_row.set_text("admin")
|
|
self.username_handler_id = self.username_row.connect(
|
|
"notify::text", self.on_username_changed
|
|
)
|
|
self.username_row.connect("notify::text", self.on_input_changed)
|
|
group.add(self.username_row)
|
|
|
|
self.password_row = Adw.PasswordEntryRow()
|
|
self.password_row.set_title("Password")
|
|
self.password_row.connect("notify::text", self.on_input_changed)
|
|
group.add(self.password_row)
|
|
|
|
self.confirm_row = Adw.PasswordEntryRow()
|
|
self.confirm_row.set_title("Confirm Password")
|
|
self.confirm_row.connect("notify::text", self.on_input_changed)
|
|
group.add(self.confirm_row)
|
|
|
|
# Hostname
|
|
host_group = Adw.PreferencesGroup()
|
|
host_group.set_margin_top(12)
|
|
box.append(host_group)
|
|
|
|
self.hostname_row = Adw.EntryRow()
|
|
self.hostname_row.set_title("Hostname")
|
|
self.hostname_row.set_text("iridium")
|
|
self.hostname_row.connect("notify::text", self.on_input_changed)
|
|
host_group.add(self.hostname_row)
|
|
|
|
self.username_manually_set = False
|
|
|
|
# Initial validation
|
|
self.validate()
|
|
|
|
def on_fullname_changed(self, entry, _pspec):
|
|
if self.username_manually_set:
|
|
return
|
|
|
|
username = entry.get_text().lower()
|
|
if username == "administrator":
|
|
username = "admin"
|
|
for sign in (
|
|
" ",
|
|
"-",
|
|
"_",
|
|
".",
|
|
",",
|
|
":",
|
|
";",
|
|
"!",
|
|
"?",
|
|
"/",
|
|
"\\",
|
|
"|",
|
|
"@",
|
|
"#",
|
|
"$",
|
|
"%",
|
|
"^",
|
|
"&",
|
|
"*",
|
|
"(",
|
|
")",
|
|
"[",
|
|
"]",
|
|
"{",
|
|
"}",
|
|
"'",
|
|
'"',
|
|
"`",
|
|
"~",
|
|
"<",
|
|
">",
|
|
"=",
|
|
"+",
|
|
):
|
|
username = username.replace(sign, "_")
|
|
|
|
self.username_row.handler_block(self.username_handler_id)
|
|
self.username_row.set_text(username)
|
|
self.username_row.handler_unblock(self.username_handler_id)
|
|
|
|
def on_username_changed(self, entry, _pspec):
|
|
self.username_manually_set = True
|
|
|
|
def on_input_changed(self, *args):
|
|
self.validate()
|
|
|
|
def validate(self):
|
|
valid = True
|
|
|
|
# Username validation
|
|
username = self.username_row.get_text()
|
|
if not username:
|
|
valid = False
|
|
self.username_row.add_css_class("error")
|
|
elif not re.match(r"^[a-z_][a-z0-9_-]*$", username):
|
|
valid = False
|
|
self.username_row.add_css_class("error")
|
|
else:
|
|
self.username_row.remove_css_class("error")
|
|
|
|
# Password validation
|
|
pw = self.password_row.get_text()
|
|
confirm = self.confirm_row.get_text()
|
|
|
|
if not pw:
|
|
valid = False
|
|
# Don't show error for empty password initially, just invalidate
|
|
# It looks a lot nicer like that
|
|
|
|
if pw != confirm:
|
|
valid = False
|
|
self.confirm_row.add_css_class("error")
|
|
else:
|
|
self.confirm_row.remove_css_class("error")
|
|
|
|
# Hostname validation
|
|
hostname = self.hostname_row.get_text()
|
|
if not hostname:
|
|
valid = False
|
|
self.hostname_row.add_css_class("error")
|
|
else:
|
|
self.hostname_row.remove_css_class("error")
|
|
|
|
if self._is_valid != valid:
|
|
self._is_valid = valid
|
|
self.emit("validity-changed", valid)
|
|
|
|
def is_valid(self):
|
|
return self._is_valid
|
|
|
|
def get_user_info(self):
|
|
return {
|
|
"fullname": self.fullname_row.get_text(),
|
|
"username": self.username_row.get_text(),
|
|
"password": self.password_row.get_text(),
|
|
"hostname": self.hostname_row.get_text(),
|
|
}
|