Example #1
0
    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)
Example #3
0
 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()
Example #5
0
    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))
Example #7
0
 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()
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()
Example #10
0
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()
Example #13
0
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()
Example #14
0
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()