예제 #1
0
 def remove(self):
     """
     Remove the account.
     """
     Database.get_default().delete_account(self.id)
     Keyring.get_default().remove(self._token_id)
     self.emit("removed")
     Logger.debug("Account '{}' with id {} was removed".format(
         self.username, self.id))
예제 #2
0
    def __bind_signals(self):
        settings = Settings.get_default()
        self.dark_theme_switch.set_active(settings.dark_theme
                                          and not settings.night_light)

        self.night_light_switch.set_active(settings.night_light)
        settings.bind("night-light", self.night_light_switch, "active",
                      Gio.SettingsBindFlags.DEFAULT)

        keyring = Keyring.get_default()
        # Hackish solution to get the expander from HdyExpanderRow
        self.lock_row.props.enable_expansion = keyring.has_password()
        self.lock_row_toggle_btn = self.lock_row.get_children(
        )[0].get_children()[3]

        self.lock_row.props.enable_expansion = Keyring.get_default(
        ).is_password_enabled()
        self.lock_row.connect("notify::enable-expansion",
                              self.__on_enable_password)
        self.lock_row_toggle_btn.connect("notify::active",
                                         self.__on_lock_switch_toggled)
        self.lock_row.connect("notify::expanded", self._on_lock_row_expanded)

        keyring.bind_property(
            "can-be-locked", self.lock_timeout_row, "sensitive",
            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE)
        self.lock_timeout_spinbtn.props.value = settings.auto_lock_timeout
        settings.bind("auto-lock-timeout", self.lock_timeout_spinbtn, "value",
                      Gio.SettingsBindFlags.DEFAULT)

        self._password_widget.connect("password-updated",
                                      self.__on_password_updated)
        self._password_widget.connect("password-deleted",
                                      self.__on_password_deleted)

        def on_night_light_switch(switch: Gtk.Switch, _):
            # Set the application to use Light theme
            if switch.get_active() and self.dark_theme_switch.get_active():

                self.dark_theme_switch.set_active(False)

        self.night_light_switch.connect("notify::active",
                                        on_night_light_switch)

        def on_dark_theme_switch(switch: Gtk.Switch, _):
            # Set the application to use Light theme

            if settings.night_light and switch.get_active():
                switch.set_state(False)
            elif not settings.night_light:
                settings.dark_theme = switch.get_active()

        self.dark_theme_switch.connect("notify::active", on_dark_theme_switch)
예제 #3
0
 def create(username, token, provider):
     """
     Create a new Account.
     :param username: the account's username
     :param provider: the account's provider
     :param token: the OTP secret token
     :return: Account object
     """
     # Encrypt the token to create a secret_id
     token_id = sha256(token.encode('utf-8')).hexdigest()
     # Save the account
     obj = Database.get_default().insert_account(username, token_id,
                                                 provider)
     Keyring.get_default().insert(token_id, provider, username, token)
     return Account(obj.id, username, token_id, provider)
예제 #4
0
    def __validate_password(self, *_):
        keyring = Keyring.get_default()
        password = self.password_entry.get_text()
        repeat_password = self.confirm_password_entry.get_text()
        if not password:
            self.password_entry.get_style_context().add_class("error")
            valid_password = False
        else:
            self.password_entry.get_style_context().remove_class("error")
            valid_password = True

        if not repeat_password or password != repeat_password:
            self.confirm_password_entry.get_style_context().add_class("error")
            valid_repeat_password = False
        else:
            self.confirm_password_entry.get_style_context().remove_class(
                "error")
            valid_repeat_password = True
        to_validate = [valid_password, valid_repeat_password]

        if keyring.has_password():
            old_password = self.current_password_entry.get_text()
            if old_password != keyring.get_password():
                self.current_password_entry.get_style_context().add_class(
                    "error")
                valid_old_password = False
            else:
                self.current_password_entry.get_style_context().remove_class(
                    "error")
                valid_old_password = True
            to_validate.append(valid_old_password)

        self.change_password_btn.set_sensitive(all(to_validate))
예제 #5
0
 def __on_enable_password(self, *_):
     keyring = Keyring.get_default()
     keyring.set_password_state(self.lock_row.props.enable_expansion)
     if not keyring.has_password():
         self._password_widget.set_current_password_visibility(False)
     else:
         self._password_widget.set_current_password_visibility(True)
예제 #6
0
    def __reset_password(self, *args):
        dialog = Gtk.MessageDialog(buttons=Gtk.ButtonsType.YES_NO)
        dialog.props.message_type = Gtk.MessageType.QUESTION
        dialog.props.text = _(
            "Do you want to remove the authentication password?")
        dialog.props.secondary_text = _(
            "Authentication password enforces the privacy of your accounts.")

        dialog.set_transient_for(self.parent)

        response = dialog.run()
        if response == Gtk.ResponseType.YES:
            Keyring.get_default().remove_password()
            self.reset_widgets()
            self.set_current_password_visibility(False)
            self.emit("password-deleted")
        dialog.destroy()
예제 #7
0
 def __save_password(self, *__):
     if self.change_password_btn.get_sensitive():
         keyring = Keyring.get_default()
         password = self.password_entry.get_text()
         keyring.set_password(password)
         self.reset_widgets()
         self.set_current_password_visibility(True)
         self.emit("password-updated")
예제 #8
0
    def _setup_actions(self):
        self._add_action("about", self._on_about)
        self._add_action("shortcuts", self._on_shortcuts)
        self._add_action("quit", self._on_quit)
        self._add_action("settings", self._on_settings, "is_locked")
        self._add_action("import_json", self._on_import_json, "is_locked")
        self._add_action("export_json", self._on_export_json, "is_locked")
        self.lock_action = self._add_action("lock", self._on_lock)
        Keyring.get_default().connect("notify::can-be-locked",
                                      self._sync_lock_action)

        # Keyboard shortcuts. This includes actions defined in window.py.in
        self.set_accels_for_action("app.shortcuts", ["<Ctrl>question"])
        self.set_accels_for_action("app.quit", ["<Ctrl>Q"])
        self.set_accels_for_action("app.settings", ["<Ctrl>comma"])
        self.set_accels_for_action("win.add-account", ["<Ctrl>N"])
        self.set_accels_for_action("win.toggle-searchbar", ["<Ctrl>F"])
예제 #9
0
 def __unlock_btn_clicked(self, *_):
     from Authenticator.models import Keyring
     typed_password = self.password_entry.get_text()
     if typed_password == Keyring.get_default().get_password():
         self.get_application().set_property("is-locked", False)
         # Reset password entry
         self.password_entry.get_style_context().remove_class("error")
         self.password_entry.set_text("")
     else:
         self.password_entry.get_style_context().add_class("error")
예제 #10
0
    def _do_auto_lock(self, *_):
        settings = Settings.get_default()
        keyring = Keyring.get_default()

        # If the user has a timer set already, remove it first
        if self._auto_lock_timeout_id > 0:
            GLib.Source.remove(self._auto_lock_timeout_id)
            self._auto_lock_timeout_id = 0

        if keyring.can_be_locked and settings.auto_lock_timeout > 0:
            lockout_seconds = settings.auto_lock_timeout * 60
            self._auto_lock_timeout_id = GLib.timeout_add_seconds(
                lockout_seconds, self._on_lock)
예제 #11
0
 def to_json(self):
     token = Keyring.get_default().get_by_id(self._token_id)
     if token:
         return {
             "secret": token,
             "label": self.username,
             "period": 30,
             "digits": 6,
             "type": "OTP",
             "algorithm": "SHA1",
             "thumbnail": "Default",
             "last_used": 0,
             "tags": [self.provider.name]
         }
     return None
예제 #12
0
 def __init__(self, _id, username, token_id, provider):
     GObject.GObject.__init__(self)
     self.id = _id
     self.username = username
     self.provider = provider
     self._token_id = token_id
     token = Keyring.get_default().get_by_id(self._token_id)
     self.connect("otp_out_of_date", self._on_otp_out_of_date)
     if token:
         self.otp = OTP(token)
         self._code_generated = True
     else:
         self.otp = None
         self._code_generated = False
         Logger.error("Could not read the secret code,"
                      "the keyring keys were reset manually")
예제 #13
0
    def do_startup(self):
        """Startup the application."""
        # Set the default night mode
        settings = Settings.get_default()

        Gtk.Application.do_startup(self)

        self._generate_menu()
        self._setup_actions()

        keyring = Keyring.get_default()
        self.is_locked = keyring.can_be_locked

        self._setup_css()

        # Restore default state
        self._on_dark_theme_changed()
        self._on_night_light_changed()
        # Bind signals
        settings.connect("changed::dark-theme", self._on_dark_theme_changed)
        settings.connect("changed::night-light", self._on_night_light_changed)
        settings.connect("changed::auto-lock-timeout", self._do_auto_lock)
        keyring.connect("notify::can-be-locked", self._do_auto_lock)
예제 #14
0
 def __on_lock_switch_toggled(self, toggle_btn: Gtk.ToggleButton, *_):
     toggled = toggle_btn.props.active
     expansion_enabled = self.lock_row.props.enable_expansion
     if not Keyring.get_default().has_password(
     ) and not toggled and expansion_enabled:
         self.lock_row.props.enable_expansion = False
예제 #15
0
 def _on_lock_row_expanded(self, *_):
     keyring = Keyring.get_default()
     if keyring.has_password():
         keyring.set_password_state(self.lock_row.props.expanded)
         self.lock_row_toggle_btn.props.active = False
예제 #16
0
 def _sync_lock_action(self, *_):
     keyring = Keyring.get_default()
     self.lock_action.props.enabled = keyring.can_be_locked and not self.is_locked