def __init__(self): Gtk.Application.__init__(self, application_id="org.gnome.TwoFactorAuth", flags=Gio.ApplicationFlags.FLAGS_NONE) GLib.set_application_name(_("TwoFactorAuth")) GLib.set_prgname("Gnome-TwoFactorAuth") self.menu = Gio.Menu() self.db = Database() self.cfg = SettingsReader() self.locked = self.cfg.read("state", "login") result = GK.unlock_sync("Gnome-TwoFactorAuth", None) if result == GK.Result.CANCELLED: self.quit() if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: cssFileName = "gnome-twofactorauth-post3.20.css" else: cssFileName = "gnome-twofactorauth-pre3.20.css" cssProviderFile = Gio.File.new_for_uri('resource:///org/gnome/TwoFactorAuth/%s' % cssFileName) cssProvider = Gtk.CssProvider() screen = Gdk.Screen.get_default() styleContext = Gtk.StyleContext() try: cssProvider.load_from_file(cssProviderFile) styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER) logging.debug("Loading css file ") except Exception as e: logging.error("Error message %s" % str(e))
def __init__(self, parent, window, app): Thread.__init__(self) Gtk.ListBoxRow.__init__(self) # Read default values cfg = SettingsReader() self.counter_max = cfg.read("refresh-time", "preferences") self.counter = self.counter_max self.window = window self.parent = parent self.id = app[0] self.name = app[1] self.secret_code = Database.fetch_secret_code(app[2]) if self.secret_code: self.code = Code(self.secret_code) else: self.code_generated = False logging.error( "Could not read the secret code from, the keyring keys were reset manually") self.logo = app[3] # Create needed widgets self.code_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self.revealer = Gtk.Revealer() self.checkbox = Gtk.CheckButton() self.application_name = Gtk.Label(xalign=0) self.code_label = Gtk.Label(xalign=0) self.timer_label = Gtk.Label(xalign=0) # Create the list row self.create_row() self.start() self.window.connect("key-press-event", self.__on_key_press)
def __init__(self, parent, window, app): Thread.__init__(self) Gtk.ListBoxRow.__init__(self) # Read default values cfg = SettingsReader() self.counter_max = cfg.read("refresh-time", "preferences") self.counter = self.counter_max self.window = window self.parent = parent self.id = app[0] self.name = app[1] self.secret_code = Database.fetch_secret_code(app[2]) if self.secret_code: self.code = Code(self.secret_code) else: self.code_generated = False logging.error( "Could not read the secret code from, the keyring keys were reset manually" ) self.logo = app[3] # Create needed widgets self.code_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self.revealer = Gtk.Revealer() self.checkbox = Gtk.CheckButton() self.application_name = Gtk.Label(xalign=0) self.code_label = Gtk.Label(xalign=0) self.timer_label = Gtk.Label(xalign=0) # Create the list row self.create_row() self.start() self.window.connect("key-press-event", self.__on_key_press)
def __init__(self, parent): self.parent = parent self.cfg = SettingsReader() self.notebook = Gtk.Notebook() self.auto_lock_time = Gtk.SpinButton() self.enable_switch = Gtk.CheckButton() self.auto_lock_switch = Gtk.CheckButton() self.password_button = Gtk.Button() self.generate_window() self.generate_components()
def __init__(self, window): self.parent = window self.cfg = SettingsReader() self.hb = Gtk.HeaderBar() self.apply_button = Gtk.Button.new_with_label(_("Apply")) self.new_entry = Gtk.Entry() self.new2_entry = Gtk.Entry() self.old_entry = Gtk.Entry() self.generate_window() self.generate_components() self.generate_header_bar()
def __init__(self): Gtk.Application.__init__(self, application_id="org.gnome.TwoFactorAuth", flags=Gio.ApplicationFlags.FLAGS_NONE) GLib.set_application_name(_("TwoFactorAuth")) GLib.set_prgname("Gnome-TwoFactorAuth") self.menu = Gio.Menu() self.db = Database() self.cfg = SettingsReader() self.locked = self.cfg.read("state", "login") result = GK.unlock_sync("Gnome-TwoFactorAuth", None) if result == GK.Result.CANCELLED: self.quit() cssProviderFile = Gio.File.new_for_uri('resource:///org/gnome/TwoFactorAuth/style.css') cssProvider = Gtk.CssProvider() screen = Gdk.Screen.get_default() styleContext = Gtk.StyleContext() try: cssProvider.load_from_file(cssProviderFile) styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER) logging.debug("Loading css file ") except Exception as e: logging.error("Error message %s" % str(e))
class SettingsWindow(Gtk.Window): def __init__(self, parent): self.parent = parent self.cfg = SettingsReader() self.notebook = Gtk.Notebook() self.auto_lock_time = Gtk.SpinButton() self.enable_switch = Gtk.CheckButton() self.auto_lock_switch = Gtk.CheckButton() self.password_button = Gtk.Button() self.generate_window() self.generate_components() def generate_window(self): Gtk.Window.__init__(self, title=_("Settings"), type=Gtk.WindowType.TOPLEVEL, destroy_with_parent=True, modal=True) self.connect("delete-event", self.close_window) self.resize(400, 300) self.set_size_request(400, 300) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.set_transient_for(self.parent) self.connect("key_press_event", self.on_key_press) def show_window(self): self.show_all() def on_key_press(self, key, key_event): """ Keyboard Listener handler """ if Gdk.keyval_name(key_event.keyval) == "Escape": self.close_window() def generate_components(self): """ Generate all the components """ self.add(self.notebook) user_settings = self.generate_user_settings() user_settings.set_border_width(10) self.notebook.append_page(user_settings, Gtk.Label().new(_('Behavior'))) login_settings = self.generate_login_settings() login_settings.set_border_width(10) self.notebook.append_page(login_settings, Gtk.Label().new(_('Account'))) def generate_login_settings(self): """ Create a box with login settings components :return (Gtk.Box): Box contains all the components """ main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) password_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) lock_enabled = bool(self.cfg.read("state", "login")) self.enable_switch.set_active(lock_enabled) self.enable_switch.connect("toggled", self.on_switch_activated) password_label = Gtk.Label() password_label.set_label(_("Password protection")) self.password_button.get_style_context().add_class("flat") self.password_button.get_style_context().add_class("text-button") self.password_button.set_label("******") self.password_button.connect("clicked", self.new_password_window) self.password_button.set_sensitive(lock_enabled) password_box.pack_start(self.enable_switch, False, True, 6) password_box.pack_start(password_label, False, True, 6) password_box.pack_start(self.password_button, False, True, 6) main_box.pack_start(password_box, False, True, 6) return main_box def generate_user_settings(self): """ Create a box with user settings components :return (Gtk.Box): Box contains all the components """ main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) is_auto_lock_active = bool(self.cfg.read("auto-lock", "preferences")) auto_lock_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) auto_lock_label = Gtk.Label().new(_("Auto-lock the application (m):")) self.auto_lock_switch.set_sensitive(self.cfg.read("state", "login")) self.auto_lock_switch.set_active(is_auto_lock_active) self.auto_lock_switch.connect("toggled", self.on_auto_lock_activated) default_value = self.cfg.read("auto-lock-time", "preferences") if default_value < 1 or default_value > 10: default_value = 3 adjustment = Gtk.Adjustment(value=default_value, lower=1, upper=10, step_increment=1, page_increment=1, page_size=0) self.auto_lock_time.connect("value-changed", self.on_auto_lock_time_changed) self.auto_lock_time.set_adjustment(adjustment) self.auto_lock_time.set_sensitive(is_auto_lock_active) self.auto_lock_time.set_value(default_value) auto_lock_box.pack_start(self.auto_lock_switch, False, True, 6) auto_lock_box.pack_start(auto_lock_label, False, True, 6) auto_lock_box.pack_start(self.auto_lock_time, False, True, 12) main_box.pack_start(auto_lock_box, False, True, 6) return main_box def new_password_window(self, *args): """ Show a new password window """ pass_window = PasswordWindow(self) pass_window.show_window() def on_auto_lock_time_changed(self, spin_button): """ Update auto lock time """ self.cfg.update("auto-lock-time", spin_button.get_value_as_int(), "preferences") logging.info("Auto lock time updated") def on_switch_activated(self, switch, *args): """ Update password state : enabled/disabled """ self.password_button.set_sensitive(switch.get_active()) self.cfg.update("state", switch.get_active(), "login") if switch.get_active(): password = self.cfg.read("password", "login") if len(password) == 0: self.new_password_window() self.auto_lock_switch.set_sensitive(switch.get_active()) logging.info("Password enabled/disabled") self.parent.refresh_window() def on_auto_lock_activated(self, switch, *args): """ Update auto-lock state : enabled/disabled """ self.auto_lock_time.set_sensitive(switch.get_active()) self.cfg.update("auto-lock", switch.get_active(), "preferences") logging.info("Auto lock state updated") def close_window(self, *args): """ Close the window """ logging.debug("SettingsWindow closed") self.destroy()
class Application(Gtk.Application): win = None alive = True locked = False settings_action = None def __init__(self): Gtk.Application.__init__(self, application_id="org.gnome.TwoFactorAuth", flags=Gio.ApplicationFlags.FLAGS_NONE) GLib.set_application_name(_("TwoFactorAuth")) GLib.set_prgname("Gnome-TwoFactorAuth") self.menu = Gio.Menu() self.db = Database() self.cfg = SettingsReader() self.locked = self.cfg.read("state", "login") result = GK.unlock_sync("Gnome-TwoFactorAuth", None) if result == GK.Result.CANCELLED: self.quit() if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: cssFileName = "gnome-twofactorauth-post3.20.css" else: cssFileName = "gnome-twofactorauth-pre3.20.css" cssProviderFile = Gio.File.new_for_uri('resource:///org/gnome/TwoFactorAuth/%s' % cssFileName) cssProvider = Gtk.CssProvider() screen = Gdk.Screen.get_default() styleContext = Gtk.StyleContext() try: cssProvider.load_from_file(cssProviderFile) styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER) logging.debug("Loading css file ") except Exception as e: logging.error("Error message %s" % str(e)) def do_startup(self): Gtk.Application.do_startup(self) self.generate_menu() def generate_menu(self): # Settings section settings_content = Gio.Menu.new() settings_content.append_item( Gio.MenuItem.new(_("Settings"), "app.settings")) settings_section = Gio.MenuItem.new_section(None, settings_content) self.menu.append_item(settings_section) # Help section help_content = Gio.Menu.new() if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: help_content.append_item(Gio.MenuItem.new( _("Shortcuts"), "app.shortcuts")) help_content.append_item(Gio.MenuItem.new(_("About"), "app.about")) help_content.append_item(Gio.MenuItem.new(_("Quit"), "app.quit")) help_section = Gio.MenuItem.new_section(None, help_content) self.menu.append_item(help_section) self.settings_action = Gio.SimpleAction.new("settings", None) self.settings_action.connect("activate", self.on_settings) self.settings_action.set_enabled(not self.locked) self.add_action(self.settings_action) if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: action = Gio.SimpleAction.new("shortcuts", None) action.connect("activate", self.on_shortcuts) self.add_action(action) action = Gio.SimpleAction.new("about", None) action.connect("activate", self.on_about) self.add_action(action) action = Gio.SimpleAction.new("quit", None) action.connect("activate", self.on_quit) self.add_action(action) if is_gnome(): self.set_app_menu(self.menu) logging.debug("Adding gnome shell menu") def do_activate(self, *args): if not self.win: self.win = Window(self) self.win.show_all() self.add_window(self.win) else: self.win.present() def refresh_menu(self): is_enabled = self.settings_action.get_enabled() self.settings_action.set_enabled(not is_enabled) def on_shortcuts(self, *args): """ Shows keyboard shortcuts """ shortcuts = Application.shortcuts_dialog() if shortcuts: shortcuts.set_transient_for(self.win) shortcuts.show() @staticmethod def shortcuts_dialog(): if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: builder = Gtk.Builder() builder.add_from_resource('/org/gnome/TwoFactorAuth/shortcuts.ui') shortcuts = builder.get_object("shortcuts") return shortcuts return None @staticmethod def about_dialog(): """ Shows about dialog """ builder = Gtk.Builder() builder.add_from_resource('/org/gnome/TwoFactorAuth/about.ui') dialog = builder.get_object("AboutDialog") return dialog def on_about(self, *args): """ Shows about dialog """ dialog = Application.about_dialog() dialog.set_transient_for(self.win) dialog.run() dialog.destroy() def on_settings(self, *args): """ Shows settings window """ settings_window = SettingsWindow(self.win) settings_window.show_window() settings_window.present() def on_quit(self, *args): """ Close the application, stops all threads and clear clipboard for safety reasons """ try: clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) clipboard.clear() except Exception as e: logging.error(str(e)) self.alive = False signal.signal(signal.SIGINT, lambda x, y: self.alive) if self.win: self.win.save_window_state() self.win.destroy() self.quit()
class PasswordWindow(Gtk.Window): def __init__(self, window): self.parent = window self.cfg = SettingsReader() self.hb = Gtk.HeaderBar() self.apply_button = Gtk.Button.new_with_label(_("Apply")) self.new_entry = Gtk.Entry() self.new2_entry = Gtk.Entry() self.old_entry = Gtk.Entry() self.generate_window() self.generate_components() self.generate_header_bar() def generate_window(self): Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL, title=_("Change password"), modal=True, destroy_with_parent=True) self.connect("delete-event", self.close_window) self.resize(300, 100) self.set_border_width(18) self.set_size_request(300, 100) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.set_resizable(False) self.set_transient_for(self.parent) self.connect("key_press_event", self.on_key_press) def show_window(self): self.show_all() def on_key_press(self, key, key_event): """ Keyboard listener handler """ if Gdk.keyval_name(key_event.keyval) == "Escape": self.close_window() def generate_components(self): """ Generate window components """ main_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) if len(self.cfg.read("password", "login")) != 0: box_old = Gtk.Box( orientation=Gtk.Orientation.HORIZONTAL, spacing=18) old_label = Gtk.Label() old_label.set_text(_("Old password")) self.old_entry.connect("changed", self.on_type_password) self.old_entry.set_visibility(False) box_old.pack_end(self.old_entry, False, True, 0) box_old.pack_end(old_label, False, True, 0) box.add(box_old) box_new = Gtk.Box( orientation=Gtk.Orientation.HORIZONTAL, spacing=18) new_label = Gtk.Label() new_label.set_text(_("New password")) self.new_entry.connect("changed", self.on_type_password) self.new_entry.set_visibility(False) box_new.pack_end(self.new_entry, False, True, 0) box_new.pack_end(new_label, False, True, 0) box_new2 = Gtk.Box( orientation=Gtk.Orientation.HORIZONTAL, spacing=18) new2_label = Gtk.Label() new2_label.set_text(_("Repeat new password")) self.new2_entry.connect("changed", self.on_type_password) self.new2_entry.set_visibility(False) box_new2.pack_end(self.new2_entry, False, True, 0) box_new2.pack_end(new2_label, False, True, 0) box.add(box_new) box.add(box_new2) main_box.pack_start(box, False, True, 6) self.add(main_box) def update_password(self, *args): """ Update user password """ password = sha256( self.new_entry.get_text().encode("utf-8")).hexdigest() self.cfg.update("password", password, "login") logging.debug("Password changed successfully") self.close_window() def on_type_password(self, entry): """ Validate the old & new password """ pwd = self.cfg.read("password", "login") old_is_ok = True if self.new_entry.get_text() != self.new2_entry.get_text(): self.new_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic") self.new2_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic") are_diff = True elif len(self.new_entry.get_text()) == 0: are_diff = True elif len(self.new_entry.get_text()) == 0: are_diff = True else: are_diff = False if len(pwd) != 0: if sha256(self.old_entry.get_text().encode('utf-8')).hexdigest() != pwd: self.old_entry.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic") old_is_ok = False else: old_is_ok = True if old_is_ok: self.old_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) if not are_diff: self.new_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) self.new2_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) self.apply_button.set_sensitive(not are_diff and old_is_ok) def generate_header_bar(self): """ Generate header bar box """ left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) right_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) cancel_button = Gtk.Button.new_with_label(_("Cancel")) cancel_button.connect("clicked", self.close_window) cancel_button.get_style_context().add_class("destructive-action") left_box.add(cancel_button) self.apply_button.get_style_context().add_class("suggested-action") self.apply_button.connect("clicked", self.update_password) self.apply_button.set_sensitive(False) right_box.add(self.apply_button) self.hb.pack_start(left_box) self.hb.pack_end(right_box) self.set_titlebar(self.hb) def close_window(self, *args): """ Close the window """ logging.debug("Closing PasswordWindow") self.destroy()
class Application(Gtk.Application): win = None alive = True locked = False settings_action = None def __init__(self): Gtk.Application.__init__(self, application_id="org.gnome.TwoFactorAuth", flags=Gio.ApplicationFlags.FLAGS_NONE) GLib.set_application_name(_("TwoFactorAuth")) GLib.set_prgname("Gnome-TwoFactorAuth") self.menu = Gio.Menu() self.db = Database() self.cfg = SettingsReader() self.locked = self.cfg.read("state", "login") result = GK.unlock_sync("Gnome-TwoFactorAuth", None) if result == GK.Result.CANCELLED: self.quit() cssProviderFile = Gio.File.new_for_uri('resource:///org/gnome/TwoFactorAuth/style.css') cssProvider = Gtk.CssProvider() screen = Gdk.Screen.get_default() styleContext = Gtk.StyleContext() try: cssProvider.load_from_file(cssProviderFile) styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER) logging.debug("Loading css file ") except Exception as e: logging.error("Error message %s" % str(e)) def do_startup(self): Gtk.Application.do_startup(self) self.generate_menu() def generate_menu(self): # Settings section settings_content = Gio.Menu.new() settings_content.append_item( Gio.MenuItem.new(_("Settings"), "app.settings")) settings_section = Gio.MenuItem.new_section(None, settings_content) self.menu.append_item(settings_section) # Help section help_content = Gio.Menu.new() if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: help_content.append_item(Gio.MenuItem.new( _("Shortcuts"), "app.shortcuts")) help_content.append_item(Gio.MenuItem.new(_("About"), "app.about")) help_content.append_item(Gio.MenuItem.new(_("Quit"), "app.quit")) help_section = Gio.MenuItem.new_section(None, help_content) self.menu.append_item(help_section) self.settings_action = Gio.SimpleAction.new("settings", None) self.settings_action.connect("activate", self.on_settings) self.settings_action.set_enabled(not self.locked) self.add_action(self.settings_action) if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: action = Gio.SimpleAction.new("shortcuts", None) action.connect("activate", self.on_shortcuts) self.add_action(action) action = Gio.SimpleAction.new("about", None) action.connect("activate", self.on_about) self.add_action(action) action = Gio.SimpleAction.new("quit", None) action.connect("activate", self.on_quit) self.add_action(action) if is_gnome(): self.set_app_menu(self.menu) logging.debug("Adding gnome shell menu") def do_activate(self, *args): if not self.win: self.win = Window(self) self.win.show_all() self.add_window(self.win) else: self.win.present() def refresh_menu(self): is_enabled = self.settings_action.get_enabled() self.settings_action.set_enabled(not is_enabled) def on_shortcuts(self, *args): """ Shows keyboard shortcuts """ shortcuts = Application.shortcuts_dialog() if shortcuts: shortcuts.set_transient_for(self.win) shortcuts.show() @staticmethod def shortcuts_dialog(): if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20: builder = Gtk.Builder() builder.add_from_resource('/org/gnome/TwoFactorAuth/shortcuts.ui') shortcuts = builder.get_object("shortcuts") return shortcuts return None @staticmethod def about_dialog(): """ Shows about dialog """ builder = Gtk.Builder() builder.add_from_resource('/org/gnome/TwoFactorAuth/about.ui') dialog = builder.get_object("AboutDialog") return dialog def on_about(self, *args): """ Shows about dialog """ dialog = Application.about_dialog() dialog.set_transient_for(self.win) dialog.run() dialog.destroy() def on_settings(self, *args): """ Shows settings window """ settings_window = SettingsWindow(self.win) settings_window.show_window() settings_window.present() def on_quit(self, *args): """ Close the application, stops all threads and clear clipboard for safety reasons """ try: clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) clipboard.clear() except Exception as e: logging.error(str(e)) self.alive = False signal.signal(signal.SIGINT, lambda x, y: self.alive) if self.win: self.win.save_window_state() self.win.destroy() self.quit()
class SettingsWindow(Gtk.Window): def __init__(self, parent): self.parent = parent self.cfg = SettingsReader() self.notebook = Gtk.Notebook() self.auto_lock_time = Gtk.SpinButton() self.enable_switch = Gtk.CheckButton() self.auto_lock_switch = Gtk.CheckButton() self.password_button = Gtk.Button() self.generate_window() self.generate_components() def generate_window(self): Gtk.Window.__init__(self, title=_("Settings"), type=Gtk.WindowType.TOPLEVEL, destroy_with_parent=True, modal=True) self.connect("delete-event", self.close_window) self.resize(400, 300) self.set_size_request(400, 300) self.set_resizable(False) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.set_transient_for(self.parent) self.connect("key_press_event", self.on_key_press) def show_window(self): self.show_all() def on_key_press(self, key, key_event): """ Keyboard Listener handler """ if Gdk.keyval_name(key_event.keyval) == "Escape": self.close_window() def generate_components(self): """ Generate all the components """ self.add(self.notebook) user_settings = self.generate_user_settings() user_settings.set_border_width(10) self.notebook.append_page( user_settings, Gtk.Label().new(_('Behavior'))) login_settings = self.generate_login_settings() login_settings.set_border_width(10) self.notebook.append_page( login_settings, Gtk.Label().new(_('Account'))) def generate_login_settings(self): """ Create a box with login settings components :return (Gtk.Box): Box contains all the components """ main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) password_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) lock_enabled = bool(self.cfg.read("state", "login")) self.enable_switch.set_active(lock_enabled) self.enable_switch.connect("toggled", self.on_switch_activated) password_label = Gtk.Label() password_label.set_label(_("Password protection")) self.password_button.get_style_context().add_class("flat") self.password_button.get_style_context().add_class("text-button") self.password_button.set_label("******") self.password_button.connect("clicked", self.new_password_window) self.password_button.set_sensitive(lock_enabled) password_box.pack_start(self.enable_switch, False, True, 6) password_box.pack_start(password_label, False, True, 6) password_box.pack_start(self.password_button, False, True, 6) main_box.pack_start(password_box, False, True, 6) return main_box def generate_user_settings(self): """ Create a box with user settings components :return (Gtk.Box): Box contains all the components """ main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) is_auto_lock_active = bool(self.cfg.read("auto-lock", "preferences")) auto_lock_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) auto_lock_label = Gtk.Label().new(_("Auto-lock the application (m):")) self.auto_lock_switch.set_sensitive(self.cfg.read("state", "login")) self.auto_lock_switch.set_active(is_auto_lock_active) self.auto_lock_switch.connect("toggled", self.on_auto_lock_activated) default_value = self.cfg.read("auto-lock-time", "preferences") if default_value < 1 or default_value > 10: default_value = 3 adjustment = Gtk.Adjustment(value=default_value, lower=1, upper=10, step_increment=1, page_increment=1, page_size=0) self.auto_lock_time.connect( "value-changed", self.on_auto_lock_time_changed) self.auto_lock_time.set_adjustment(adjustment) self.auto_lock_time.set_sensitive(is_auto_lock_active) self.auto_lock_time.set_value(default_value) auto_lock_box.pack_start(self.auto_lock_switch, False, True, 6) auto_lock_box.pack_start(auto_lock_label, False, True, 6) auto_lock_box.pack_start(self.auto_lock_time, False, True, 12) main_box.pack_start(auto_lock_box, False, True, 6) return main_box def new_password_window(self, *args): """ Show a new password window """ pass_window = PasswordWindow(self) pass_window.show_window() def on_auto_lock_time_changed(self, spin_button): """ Update auto lock time """ self.cfg.update("auto-lock-time", spin_button.get_value_as_int(), "preferences") logging.info("Auto lock time updated") def on_switch_activated(self, switch, *args): """ Update password state : enabled/disabled """ self.password_button.set_sensitive(switch.get_active()) self.cfg.update("state", switch.get_active(), "login") if switch.get_active(): password = self.cfg.read("password", "login") if len(password) == 0: self.new_password_window() self.auto_lock_switch.set_sensitive(switch.get_active()) logging.info("Password enabled/disabled") self.parent.refresh_window() def on_auto_lock_activated(self, switch, *args): """ Update auto-lock state : enabled/disabled """ self.auto_lock_time.set_sensitive(switch.get_active()) self.cfg.update("auto-lock", switch.get_active(), "preferences") logging.info("Auto lock state updated") def close_window(self, *args): """ Close the window """ logging.debug("SettingsWindow closed") self.destroy()
class PasswordWindow(Gtk.Window): def __init__(self, window): self.parent = window self.cfg = SettingsReader() self.hb = Gtk.HeaderBar() self.apply_button = Gtk.Button.new_with_label(_("Apply")) self.new_entry = Gtk.Entry() self.new2_entry = Gtk.Entry() self.old_entry = Gtk.Entry() self.generate_window() self.generate_components() self.generate_header_bar() def generate_window(self): Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL, title=_("Change password"), modal=True, destroy_with_parent=True) self.connect("delete-event", self.close_window) self.resize(300, 100) self.set_border_width(18) self.set_size_request(300, 100) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) self.set_resizable(False) self.set_transient_for(self.parent) self.connect("key_press_event", self.on_key_press) def show_window(self): self.show_all() def on_key_press(self, key, key_event): """ Keyboard listener handler """ if Gdk.keyval_name(key_event.keyval) == "Escape": self.close_window() def generate_components(self): """ Generate window components """ main_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) if len(self.cfg.read("password", "login")) != 0: box_old = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18) old_label = Gtk.Label() old_label.set_text(_("Old password")) self.old_entry.connect("changed", self.on_type_password) self.old_entry.set_visibility(False) box_old.pack_end(self.old_entry, False, True, 0) box_old.pack_end(old_label, False, True, 0) box.add(box_old) box_new = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18) new_label = Gtk.Label() new_label.set_text(_("New password")) self.new_entry.connect("changed", self.on_type_password) self.new_entry.set_visibility(False) box_new.pack_end(self.new_entry, False, True, 0) box_new.pack_end(new_label, False, True, 0) box_new2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=18) new2_label = Gtk.Label() new2_label.set_text(_("Repeat new password")) self.new2_entry.connect("changed", self.on_type_password) self.new2_entry.set_visibility(False) box_new2.pack_end(self.new2_entry, False, True, 0) box_new2.pack_end(new2_label, False, True, 0) box.add(box_new) box.add(box_new2) main_box.pack_start(box, False, True, 6) self.add(main_box) def update_password(self, *args): """ Update user password """ password = sha256( self.new_entry.get_text().encode("utf-8")).hexdigest() self.cfg.update("password", password, "login") logging.debug("Password changed successfully") self.close_window() def on_type_password(self, entry): """ Validate the old & new password """ pwd = self.cfg.read("password", "login") old_is_ok = True if self.new_entry.get_text() != self.new2_entry.get_text(): self.new_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic") self.new2_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic") are_diff = True elif len(self.new_entry.get_text()) == 0: are_diff = True elif len(self.new_entry.get_text()) == 0: are_diff = True else: are_diff = False if len(pwd) != 0: if sha256(self.old_entry.get_text().encode( 'utf-8')).hexdigest() != pwd: self.old_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, "dialog-error-symbolic") old_is_ok = False else: old_is_ok = True if old_is_ok: self.old_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) if not are_diff: self.new_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) self.new2_entry.set_icon_from_icon_name( Gtk.EntryIconPosition.SECONDARY, None) self.apply_button.set_sensitive(not are_diff and old_is_ok) def generate_header_bar(self): """ Generate header bar box """ left_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) right_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) cancel_button = Gtk.Button.new_with_label(_("Cancel")) cancel_button.connect("clicked", self.close_window) cancel_button.get_style_context().add_class("destructive-action") left_box.add(cancel_button) self.apply_button.get_style_context().add_class("suggested-action") self.apply_button.connect("clicked", self.update_password) self.apply_button.set_sensitive(False) right_box.add(self.apply_button) self.hb.pack_start(left_box) self.hb.pack_end(right_box) self.set_titlebar(self.hb) def close_window(self, *args): """ Close the window """ logging.debug("Closing PasswordWindow") self.destroy()