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))
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)
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)
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))
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)
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()
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")
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"])
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")
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)
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
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")
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)
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
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
def _sync_lock_action(self, *_): keyring = Keyring.get_default() self.lock_action.props.enabled = keyring.can_be_locked and not self.is_locked