huge improvements

This commit is contained in:
Bilal Elmoussaoui 2016-06-12 13:26:48 +02:00
parent d30b193dde
commit c2b7e06c35
16 changed files with 124 additions and 108 deletions

View file

@ -12,11 +12,12 @@ do_substitution = sed -e 's,[@]pythondir[@],$(pythondir),g' \
-e 's,[@]VERSION[@],$(VERSION),g' \
-e 's,[@]pyexecdir[@],$(pyexecdir),g'
gnome-twofactorauth: gnome-twofactorauth.in Makefile
$(do_substitution) < $(srcdir)/gnome-twofactorauth.in > gnome-twofactorauth
chmod +x gnome-twofactorauth
SUBDIRS = TwoFactorAuth \
data \
po \
schemas
po

View file

@ -1,16 +1,8 @@
app_PYTHON = \
application.py \
__init__.py
do_substitution = sed -e 's,[@]pythondir[@],$(pythondir),g' \
-e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
-e 's,[@]localedir[@],$(localedir),g' \
-e 's,[@]PACKAGE[@],$(PACKAGE),g' \
-e 's,[@]VERSION[@],$(VERSION),g' \
-e 's,[@]pyexecdir[@],$(pyexecdir),g'
__init__.py
appdir = $(pythondir)/Gnome-TwoFactorAuth
appdir = $(pythondir)/TwoFactorAuth
SUBDIRS = models \
widgets

View file

@ -12,7 +12,6 @@ import signal
from gettext import gettext as _
from os import environ as env
class Application(Gtk.Application):
win = None
alive = True
@ -24,15 +23,14 @@ class Application(Gtk.Application):
settings_window = None
settings_action = None
def __init__(self, *args, **kwargs):
global DATA_DIR
for key in kwargs:
setattr(self, key, kwargs[key])
Gtk.Application.__init__(self,
application_id="org.gnome.TwoFactorAuth",
flags=Gio.ApplicationFlags.FLAGS_NONE)
DATA_DIR = self.pkgdatadir
GLib.set_application_name(self.package)
GLib.set_prgname(self.package)
GLib.set_application_name(_("TwoFactorAuth"))
GLib.set_prgname("Gnome-TwoFactorAuth")
current_desktop = env.get("XDG_CURRENT_DESKTOP")
if current_desktop:
@ -47,24 +45,21 @@ class Application(Gtk.Application):
self.cfg = SettingsReader()
if self.cfg.read("state", "login"):
self.locked = True
provider = Gtk.CssProvider()
cssProviderFile = Gio.File.new_for_uri('resource:///org/gnome/TwoFactorAuth/style.css')
print(cssProviderFile)
cssProvider = Gtk.CssProvider()
screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()
try:
provider.load_from_path(cssProviderFile)
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_USER)
logging.debug("Loading css file %s" % cssProviderFile)
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.debug("File not found %s" % cssProviderFile)
logging.debug("Error message %s" % str(e))
logging.error("Error message %s" % str(e))
def do_startup(self):
Gtk.Application.do_startup(self)
self.generate_menu()
if self.use_GMenu:
logging.debug("Adding gnome shell menu")
def generate_menu(self):
# Settings section
@ -125,20 +120,34 @@ class Application(Gtk.Application):
self.win.refresh_window()
def on_shortcuts(self, *args):
self.win.show_shortcuts()
"""
Shows keyboard shortcuts
"""
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")
shortcuts.set_transient_for(self.win)
shortcuts.show()
def on_about(self, *args):
self.win.show_about()
"""
Shows about dialog
"""
builder = Gtk.Builder()
builder.add_from_resource('/org/gnome/TwoFactorAuth/about.ui')
dialog = builder.get_object("AboutDialog")
dialog.set_transient_for(self.win)
dialog.run()
dialog.destroy()
def on_settings(self, *args):
"""
Shows settings window
"""
try:
settings_window = SettingsWindow(self.win)
settings_window.show_window()
except Exception as e:
print(e)
settings_window = SettingsWindow(self.win)
settings_window.show_window()
def on_quit(self, *args):
"""

View file

@ -1,11 +1,10 @@
import sqlite3
import logging
from os import path, mknod, makedirs
from os import path, mknod, makedirs, environ as env
from gi.repository import GdkPixbuf, Gtk
from gi.repository import GnomeKeyring as GK
from hashlib import sha256
class Authenticator:
def __init__(self):
@ -28,9 +27,9 @@ class Authenticator:
self.conn = sqlite3.connect(database_file)
if not self.is_table_exists():
logging.debug(
"SQL: Table 'applications' does not exists, creating it now...")
"SQL: Table 'accounts' does not exists, creating it now...")
self.create_table()
logging.debug("SQL: Table 'applications' created successfully")
logging.debug("SQL: Table 'accounts' created successfully")
@staticmethod
def fetch_secret_code(secret_code):
@ -42,17 +41,17 @@ class Authenticator:
else:
return None
def add_application(self, name, secret_code, image):
def add_account(self, name, secret_code, image):
"""
Add an application to applications table
:param name: (str) Application name
Add an account to accounts table
:param name: (str) account name
:param secret_code: (str) ASCII Secret code
:param image: image path or icon name
:return:
"""
encrypted_secret = sha256(secret_code.encode('utf-8')).hexdigest()
t = (name, encrypted_secret, image,)
query = "INSERT INTO applications (name, secret_code, image) VALUES (?, ?, ?)"
query = "INSERT INTO accounts (name, secret_code, image) VALUES (?, ?, ?)"
try:
GK.create_sync("TwoFactorAuth", None)
attr = GK.Attribute.list_new()
@ -63,27 +62,27 @@ class Authenticator:
self.conn.execute(query, t)
self.conn.commit()
except Exception as e:
logging.error("SQL: Couldn't add a new application : %s ", str(e))
logging.error("SQL: Couldn't add a new account : %s ", str(e))
def get_secret_code(self, uid):
"""
Count number of applications
Count number of accounts
:return: (int) count
"""
c = self.conn.cursor()
query = "SELECT secret_code FROM applications WHERE uid=?"
query = "SELECT secret_code FROM accounts WHERE uid=?"
try:
data = c.execute(query, (uid,))
return data.fetchone()[0]
except Exception as e:
logging.error(
"SQL: Couldn't get application secret code : %s " % str(e))
"SQL: Couldn't get account secret code : %s " % str(e))
return None
def remove_by_id(self, uid):
"""
Remove an application by uid
:param uid: (int) application uid
Remove an account by uid
:param uid: (int) account uid
:return:
"""
secret_code = self.get_secret_code(uid)
@ -98,41 +97,41 @@ class Authenticator:
break
if found:
GK.item_delete_sync("TwoFactorAuth", gid)
query = "DELETE FROM applications WHERE uid=?"
query = "DELETE FROM accounts WHERE uid=?"
try:
self.conn.execute(query, (uid,))
self.conn.commit()
except Exception as e:
logging.error(
"SQL: Couldn't remove application by uid : %s with error : %s" % (uid, str(e)))
"SQL: Couldn't remove account by uid : %s with error : %s" % (uid, str(e)))
def count(self):
"""
Count number of applications
Count number of accounts
:return: (int) count
"""
c = self.conn.cursor()
query = "SELECT COUNT(uid) AS count FROM applications"
query = "SELECT COUNT(uid) AS count FROM accounts"
try:
data = c.execute(query)
return data.fetchone()[0]
except Exception as e:
logging.error(
"SQL: Couldn't count applications list : %s " % str(e))
"SQL: Couldn't count accounts list : %s " % str(e))
return None
def fetch_apps(self):
"""
Fetch list of applications
:return: (tuple) list of applications
Fetch list of accounts
:return: (tuple) list of accounts
"""
c = self.conn.cursor()
query = "SELECT * FROM applications"
query = "SELECT * FROM accounts"
try:
data = c.execute(query)
return data.fetchall()
except Exception as e:
logging.error("SQL: Couldn't fetch applications list %s" % str(e))
logging.error("SQL: Couldn't fetch accounts list %s" % str(e))
return None
@staticmethod
@ -142,7 +141,7 @@ class Authenticator:
:param image: icon name or image path
:return: GdkPixbux Image
"""
directory = DATA_DIR + "/data/applications/"
directory = path.join(env.get("DATA_DIR"), "applications") + "/"
theme = Gtk.IconTheme.get_default()
if path.isfile(directory + image) and path.exists(directory + image):
icon = GdkPixbuf.Pixbuf.new_from_file(directory + image)
@ -159,11 +158,11 @@ class Authenticator:
def get_latest_id(self):
"""
Get the latest uid on applications table
Get the latest uid on accounts table
:return: (int) latest uid
"""
c = self.conn.cursor()
query = "SELECT uid FROM applications ORDER BY uid DESC LIMIT 1;"
query = "SELECT uid FROM accounts ORDER BY uid DESC LIMIT 1;"
try:
data = c.execute(query)
return data.fetchone()[0]
@ -173,12 +172,12 @@ class Authenticator:
def create_table(self):
"""
Create applications table
Create accounts table
"""
query = '''CREATE TABLE "applications" (
query = '''CREATE TABLE "accounts" (
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE ,
"name" VARCHAR NOT NULL ,
"secret_code" VARCHAR NOT NULL UNIQUE ,
"secret_code" VARCHAR NOT NULL ,
"image" TEXT NOT NULL
)'''
try:
@ -186,14 +185,14 @@ class Authenticator:
self.conn.commit()
except Exception as e:
logging.error(
"SQL: impossible to create table 'applications' %s " % str(e))
"SQL: impossible to create table 'accounts' %s " % str(e))
def is_table_exists(self):
"""
Check if applications table exists
Check if accounts table exists
:return: (bool)
"""
query = "SELECT uid from applications LIMIT 1"
query = "SELECT uid from accounts LIMIT 1"
c = self.conn.cursor()
try:
data = c.execute(query)

View file

@ -130,7 +130,7 @@ class AccountRow(Thread, Gtk.ListBoxRow):
self.checkbox.set_visible(False)
self.checkbox.set_no_show_all(True)
self.checkbox.connect("toggled", self.parent.select_application)
h_box.pack_start(self.checkbox, False, True, 6)
h_box.pack_start(self.checkbox, False, True, 0)
# Application logo
auth_icon = Authenticator.get_auth_icon(self.logo)

View file

@ -52,7 +52,7 @@ class AddAccount(Gtk.Window):
self.apply_button = Gtk.Button.new_with_label(_("Add"))
self.apply_button.get_style_context().add_class("suggested-action")
self.apply_button.connect("clicked", self.add_application)
self.apply_button.connect("clicked", self.add_account)
self.apply_button.set_sensitive(False)
right_box.add(self.apply_button)
@ -109,7 +109,6 @@ class AddAccount(Gtk.Window):
"""
Update image logo
"""
directory = DATA_DIR + "/data/applications/"
self.selected_image = image
auth_icon = Authenticator.get_auth_icon(image)
self.logo_image.clear()
@ -129,7 +128,7 @@ class AddAccount(Gtk.Window):
entry.set_icon_from_icon_name(
Gtk.EntryIconPosition.SECONDARY, None)
def add_application(self, *args):
def add_account(self, *args):
"""
Add a new application to the database
"""
@ -137,7 +136,7 @@ class AddAccount(Gtk.Window):
secret_entry = self.secret_code.get_text()
image_entry = self.selected_image if self.selected_image else "image-missing"
try:
self.parent.app.auth.add_application(name_entry, secret_entry,
self.parent.app.auth.add_account(name_entry, secret_entry,
image_entry)
uid = self.parent.app.auth.get_latest_id()
self.parent.append_list_box(
@ -145,7 +144,7 @@ class AddAccount(Gtk.Window):
self.parent.refresh_window()
self.close_window()
except Exception as e:
logging.error("Error in adding a new application")
logging.error("Error in adding a new account")
logging.error(str(e))
def show_window(self):

View file

@ -4,7 +4,7 @@ from gi.repository import Gtk, GLib, Gio, Gdk
from TwoFactorAuth.models.authenticator import Authenticator
from TwoFactorAuth.widgets.search_bar import SearchBar
from TwoFactorAuth.widgets.application_row import ApplicationRow
from os import path, listdir
from os import path, listdir, environ as env
from gettext import gettext as _
@ -12,7 +12,9 @@ class ApplicationChooserWindow(Gtk.Window):
def __init__(self, window):
# directory that contains the main icons
self.logos = listdir(DATA_DIR + "/data/applications/")
directory = path.join(env.get("DATA_DIR"), "applications") + "/"
self.logos = listdir(directory)
self.logos.sort()
self.parent = window

View file

@ -12,7 +12,7 @@ class SearchBar(Gtk.Box):
self.generate()
def generate(self):
Gtk.ListBoxRow.__init__(self, orientation=Gtk.Orientation.VERTICAL)
Gtk.Box.__init__(self, orientation=Gtk.Orientation.VERTICAL)
self.revealer = Gtk.Revealer()
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
@ -22,6 +22,7 @@ class SearchBar(Gtk.Box):
"system-search-symbolic")
box.pack_start(self.search_entry, True, False, 12)
box.props.margin = 6
self.revealer.add(box)
self.revealer.set_reveal_child(False)
self.pack_start(self.revealer, True, False, 0)
@ -29,6 +30,7 @@ class SearchBar(Gtk.Box):
def toggle(self, *args):
if self.revealer.get_reveal_child():
self.revealer.set_reveal_child(False)
self.search_entry.set_text("")
self.list_accounts.set_filter_func(lambda x, y, z: True,
None, False)
else:

View file

@ -59,8 +59,8 @@ class Window(Gtk.ApplicationWindow):
self.move_latest_position()
self.set_wmclass("Gnome-TwoFactorAuth", "Gnome TwoFactorAuth")
self.set_icon_name("Gnome-TwoFactorAuth")
self.resize(410, 550)
self.set_size_request(410, 550)
self.resize(420, 550)
self.set_size_request(420, 550)
self.set_resizable(False)
self.connect("key_press_event", self.on_key_press)
self.connect("delete-event", lambda x, y: self.app.on_quit())
@ -586,7 +586,6 @@ class Window(Gtk.ApplicationWindow):
if Gtk.get_major_version() >= 3 and Gtk.get_minor_version() >= 20:
builder = Gtk.Builder()
builder.add_from_resource('/org/gnome/TwoFactorAuth/shortcuts.ui')
# builder.add_from_file(DATA_DIR + "/data/shortcuts.ui")
shortcuts = builder.get_object("shortcuts")
shortcuts.set_transient_for(self)
shortcuts.show()

View file

@ -10,7 +10,7 @@ AM_MAINTAINER_MODE([enable])
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
GETTEXT_PACKAGE=TwoFactorAuth
GETTEXT_PACKAGE=woFactorAuth
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE",
[The prefix for our gettext translation domains.])
@ -32,7 +32,6 @@ AC_CONFIG_FILES([
TwoFactorAuth/Makefile
TwoFactorAuth/models/Makefile
TwoFactorAuth/widgets/Makefile
schemas/Makefile
po/Makefile.in
])

View file

@ -4,28 +4,46 @@ resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) --sourc
gnome-twofactorauth.gresource: gnome-twofactorauth.gresource.xml $(resource_files)
$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir) --sourcedir=$(builddir) $<
resourcedir = $(pkgdatadir)
resource_DATA = gnome-twofactorauth.gresource
desktopdir = $(datadir)/applications
desktop_DATA = gnome-twofactorauth.desktop
@INTLTOOL_DESKTOP_RULE@
appdatadir = $(pkgdatadir)/appdata
appdata_DATA = \
gnome-twofactorauth.appdata.xml
appdata_DATA = $(appdata_in_files:.xml.in=.xml)
appdata_in_files = gnome-twofactorauth.appdata.xml.in
@INTLTOOL_XML_RULE@
gsettings_SCHEMAS = org.gnome.TwoFactorAuth.gschema.xml
gschemas.compiled: $(gsettings_SCHEMAS) Makefile
$(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) $(builddir)
@GSETTINGS_RULES@
EXTRA_DIST = \
$(resource_files) \
$(desktop_DATA) \
$(appdata_DATA)
$(appdata_DATA) \
gnome-twofactorauth.gresource.xml \
org.gnome.TwoFactorAuth.gschema.xml
CLEANFILES = \
$(appdata_DATA) \
gnome-twofactorauth.gresource \
gnome-twofactorauth.appdata.xml \
$(desktop_DATA) \
$(resource_files) \
*.valid \
gschemas.compiled
install-data-hook:
$(UPDATE_DESKTOP)
uninstall-hook:
$(UPDATE_DESKTOP)
all-local: gschemas.compiled

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<application>
<id type="desktop">twofactorauth.desktop</id>
<licence>CC0</licence>
<licence>GPL3</licence>
<name>Gnome TwoFactorAuth</name>
<summary>Two Factor Authentication code generator</summary>
<description>

View file

@ -28,7 +28,7 @@
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">True</property>
<property name="title" translatable="yes" context="shortcut window">Add a new application</property>
<property name="title" translatable="yes" context="shortcut window">Add a new account</property>
<property name="accelerator">&lt;Primary&gt;N</property>
</object>
</child>
@ -47,18 +47,10 @@
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">True</property>
<property name="title" translatable="yes" context="shortcut window">Select next application</property>
<property name="accelerator">Up</property>
<property name="title" translatable="yes" context="shortcut window">Select next/previous account</property>
<property name="accelerator">Up Down</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">True</property>
<property name="title" translatable="yes" context="shortcut window">Select previous application</property>
<property name="accelerator">Down</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="visible">True</property>

View file

@ -21,6 +21,7 @@
import sys
sys.path.insert(1, '@pyexecdir@')
sys.path.insert(1, '@pythondir@')
from gi.repository import Gio
from TwoFactorAuth import application
import logging
import locale
@ -28,6 +29,7 @@ import gettext
_ = gettext.gettext
import argparse
import faulthandler
from os import path, environ as env
if __name__ == "__main__":
@ -36,6 +38,9 @@ if __name__ == "__main__":
gettext.bindtextdomain('TwoFactorAuth', "@localedir@")
gettext.textdomain('TwoFactorAuth')
env["DATA_DIR"] = "@pkgdatadir@"
env["LOCALE_DIR"] = "@localedir@"
parser = argparse.ArgumentParser(prog="TwoFactorAuth")
parser.add_argument("--debug", "-d", action="store_true",
help=_("start in debug mode"))
@ -47,14 +52,16 @@ if __name__ == "__main__":
if args.debug:
level = logging.DEBUG
faulthandler.enable()
logging.basicConfig(level=level,
format='[%(levelname)s] %(message)s',
)
format='%(asctime)s %(levelname)s\t%(message)s',
datefmt='%H:%M:%S')
resource = Gio.resource_load(path.join('@pkgdatadir@',
'gnome-twofactorauth.gresource'))
Gio.Resource._register(resource)
if args.version:
sys.exit("Version : @VERSION@")
app = application.Application(package="@PACKAGE@",
version="@VERSION@",
pkgdatadir="@pkgdatadir@")
app = application.Application()
exit_status = app.run(None)
sys.exit(exit_status)

View file

@ -1,3 +0,0 @@
gsettings_SCHEMAS = org.gnome.TwoFactorAuth.gschema.xml
@GSETTINGS_RULES@