Re-architecting changes
authorPete Fotheringham <pete.fotheringham@codethink.co.uk>
Tue, 20 Dec 2011 12:15:00 +0000 (12:15 +0000)
committerPete Fotheringham <pete.fotheringham@codethink.co.uk>
Tue, 20 Dec 2011 12:15:00 +0000 (12:15 +0000)
Makefile.am
configure.ac
src/moonshot-custom-vbox.vala
src/moonshot-idcard-store.vala [new file with mode: 0644]
src/moonshot-idcard-widget.vala
src/moonshot-identities-manager.vala
src/moonshot-identity-management-view.vala [moved from src/moonshot-window.vala with 86% similarity]
src/moonshot-identity-manager-app.vala [new file with mode: 0644]
src/moonshot-identity-request.vala
src/moonshot-local-flat-file-store.vala [new file with mode: 0644]
src/moonshot-server.vala

index 7b03494..8b5b014 100644 (file)
@@ -34,6 +34,10 @@ include_HEADERS = libmoonshot/libmoonshot.h
 noinst_HEADERS = libmoonshot/libmoonshot-common.h
 
 src_moonshot_SOURCES = \
+        src/moonshot-identity-manager-app.vala \
+        src/moonshot-identity-management-view.vala \
+        src/moonshot-local-flat-file-store.vala \
+        src/moonshot-idcard-store.vala \
         src/moonshot-id.vala \
         src/moonshot-add-dialog.vala \
         src/moonshot-idcard-widget.vala \
@@ -41,7 +45,6 @@ src_moonshot_SOURCES = \
         src/moonshot-identities-manager.vala \
         src/moonshot-identity-request.vala \
         src/moonshot-server.vala \
-        src/moonshot-window.vala \
         src/moonshot-password-dialog.vala \
         src/moonshot-utils.vala
 
@@ -49,7 +52,7 @@ src_moonshot_webp_SOURCES = \
         src/moonshot-webp-parser.vala \
         src/moonshot-id.vala
 
-src_moonshot_VALAFLAGS = --pkg gdk-2.0 --pkg gtk+-2.0 $(AM_VALAFLAGS)
+src_moonshot_VALAFLAGS = --pkg gdk-2.0 --pkg gtk+-2.0 --pkg gee-1.0 $(AM_VALAFLAGS)
 src_moonshot_CPPFLAGS = $(moonshot_CFLAGS) $(AM_CPPFLAGS)
 src_moonshot_LDADD = $(moonshot_LIBS)
 
@@ -63,7 +66,7 @@ libmoonshot_libmoonshot_la_LDFLAGS = -no-undefined
 
 src_moonshot_CFLAGS = -mwindows
 src_moonshot_webp_CFLAGS = -mwindows
-
+    
 AM_CPPFLAGS += -DOS_WIN32
 AM_VALAFLAGS += --define=OS_WIN32
 
index ab3e55e..7b392fb 100644 (file)
@@ -28,11 +28,33 @@ AC_CANONICAL_HOST
 case "$host" in
   *-*-mingw*)
     win32=yes
+    macos=no
+    linux=no
     SERVER_IPC_MODULE="msrpc-glib2-1.0"
     CLIENT_IPC_MODULE="msrpc-mingw-1.0"
     ;;
+    
+  *darwin*) 
+    win32=no
+    macos=yes
+    linux=no
+
+    # We require dbus-glib for the client library even if we are using GDBus
+    # in the server. The reason we can't always use dbus-glib in the server is
+    # because Vala drops support for it, but as it ships with DBus there is very
+    # little danger of it being dropped by distros any time soon.
+    CLIENT_IPC_MODULE="dbus-glib-1"
+    PKG_CHECK_MODULES([GDBUS],
+            [gio-2.0 >= 2.26],
+            [SERVER_IPC_MODULE="gio-2.0"],
+            [SERVER_IPC_MODULE="dbus-glib-1"]
+    )
+
+    ;;
   *)
+    macos=no
     win32=no
+    linux=yes
 
     # We require dbus-glib for the client library even if we are using GDBus
     # in the server. The reason we can't always use dbus-glib in the server is
@@ -48,8 +70,9 @@ case "$host" in
     ;;
 esac
 
-AM_CONDITIONAL([OS_LINUX], [test "$win32" != "yes"])
+AM_CONDITIONAL([OS_LINUX], [test "$linux" = "yes"])
 AM_CONDITIONAL([OS_WIN32], [test "$win32" = "yes"])
+AM_CONDITIONAL([OS_MACOS], [test "$macos" = "yes"])
 
 AM_CONDITIONAL([IPC_MSRPC], [test "$SERVER_IPC_MODULE" = "msrpc-glib2-1.0"])
 AM_CONDITIONAL([IPC_DBUS], [test "$SERVER_IPC_MODULE" != "msrpc-glib2-1.0"])
@@ -134,7 +157,7 @@ if test "$win32" = "yes"; then
   fi
 fi
 
-if test "$win32" != "yes"; then
+if test "$linux" = "yes"; then
   AC_PATH_PROG([UPDATE_MIME_DATABASE], [update-mime-database], [no])
   if test "$UPDATE_MIME_DATABASE" = "no"; then
     AC_MSG_ERROR([
@@ -168,6 +191,7 @@ PKG_CHECK_MODULES(moonshot,[
         glib-2.0 >= 2.22
         gobject-2.0 >= 2.22
         gtk+-2.0 >= 2.18
+        gee-1.0 > 0.6
         $SERVER_IPC_MODULE
 ])
 
index 31b2a20..3fb96ff 100644 (file)
@@ -3,9 +3,9 @@ using Gtk;
 class CustomVBox : VBox
 {
     public IdCardWidget current_idcard { get; set; default = null; }
-    private MainWindow main_window; 
+    private IdentityManagerView main_window; 
 
-    public CustomVBox (MainWindow window, bool homogeneous, int spacing)
+    public CustomVBox (IdentityManagerView window, bool homogeneous, int spacing)
     {
         main_window = window;
         set_homogeneous (homogeneous);
diff --git a/src/moonshot-idcard-store.vala b/src/moonshot-idcard-store.vala
new file mode 100644 (file)
index 0000000..8f2f8ec
--- /dev/null
@@ -0,0 +1,9 @@
+using Gee; 
+public interface IIdentityCardStore : Object {
+    // Methods
+    public abstract void add_card(IdCard card);
+    public abstract void remove_card(IdCard card);
+    public abstract void update_card(IdCard card);
+    public abstract LinkedList<IdCard> get_card_list(); 
+}
+
index 7633de0..c6758af 100644 (file)
@@ -78,7 +78,7 @@ class IdCardWidget : Box
     {
         string services_text = "";
 
-        var display_name = Markup.printf_escaped ("<b>%s</b>", this.id_card.display_name);
+        var display_name = Markup.printf_escaped ("<big>%s</big>", this.id_card.display_name);
         for (int i=0; i<id_card.services.length; i++)
         {
             var service = id_card.services[i];
index 90bbec9..86c731b 100644 (file)
-class IdentitiesManager : Object {
-
-    public SList<IdCard> id_card_list;
+using Gee;
 
+class IdentityManagerModel : Object {
     private const string FILE_NAME = "identities.txt";
 
-    public IdentitiesManager ()
-    {
-        id_card_list = new SList<IdCard>();
-        var key_file = new KeyFile ();
-
-        var path = get_data_dir ();
-        var filename = Path.build_filename (path, FILE_NAME);
-
-        try
-        {
-            key_file.load_from_file (filename, KeyFileFlags.NONE);
-        }
-        catch (Error e)
-        {
-            stdout.printf("Error: %s\n", e.message);
-            return;
-        }
-
-        var identities_uris = key_file.get_groups ();
-        foreach (string identity in identities_uris)
-        {
-            try
-            {
-                IdCard id_card = new IdCard ();
-
-                id_card.issuer = key_file.get_string (identity, "Issuer");
-                id_card.username = key_file.get_string (identity, "Username");
-                id_card.password = key_file.get_string (identity, "Password");
-                id_card.services = key_file.get_string_list (identity, "Services");
-                id_card.display_name = key_file.get_string (identity, "DisplayName");
-                id_card.set_data ("pixbuf", find_icon ("avatar-default", 48));
-                
-                
-                if (key_file.has_key (identity, "Rules-Patterns") &&
-                    key_file.has_key (identity, "Rules-AlwaysConfirm"))
-                {
-                    string [] rules_patterns =    key_file.get_string_list (identity, "Rules-Patterns");
-                    string [] rules_always_conf = key_file.get_string_list (identity, "Rules-AlwaysConfirm");
-                    
-                    if (rules_patterns.length == rules_always_conf.length)
-                    {
-                      Rule[] rules = new Rule[rules_patterns.length];
-                      for (int i = 0; i < rules_patterns.length; i++)
-                      {
-                        rules[i] = {rules_patterns[i], rules_always_conf[i]};
-                      }
-                      id_card.rules = rules;
-                    }
-                }
-                // Trust anchor 
-                id_card.trust_anchor.ca_cert = key_file.get_string (identity, "CA-Cert");
-                id_card.trust_anchor.subject = key_file.get_string (identity, "Subject");
-                id_card.trust_anchor.subject_alt = key_file.get_string (identity, "SubjectAlt");
-                id_card.trust_anchor.server_cert = key_file.get_string (identity, "ServerCert");
-
-                id_card_list.prepend (id_card);
-            }
-            catch (Error e)
-            {
-                stdout.printf ("Error:  %s\n", e.message);
-            }
-        }
+    private IIdentityCardStore store;
+    public LinkedList<IdCard>  get_card_list() {
+         return store.get_card_list(); 
     }
+    public signal void card_list_changed();
 
-    public void store_id_cards ()
-    {
-        var key_file = new KeyFile ();
+    public void add_card(IdCard card) {
+        store.add_card(card);
+        card_list_changed();
+     }
 
-        foreach (IdCard id_card in this.id_card_list)
-        {
-            string[] rules_patterns = new string[id_card.rules.length];
-            string[] rules_always_conf = new string[id_card.rules.length];
-            
-            for (int i=0; i<id_card.rules.length; i++)
-            {
-              rules_patterns[i] = id_card.rules[i].pattern;
-              rules_always_conf[i] = id_card.rules[i].always_confirm;
-            }
-
-            key_file.set_string (id_card.display_name, "Issuer", id_card.issuer ?? "");
-            key_file.set_string (id_card.display_name, "DisplayName", id_card.display_name ?? "");
-            key_file.set_string (id_card.display_name, "Username", id_card.username ?? "");
-            key_file.set_string (id_card.display_name, "Password", id_card.password ?? "");
-            key_file.set_string_list (id_card.display_name, "Services", id_card.services ?? {});
-
-            if (id_card.rules.length > 0)
-            {
-              key_file.set_string_list (id_card.display_name, "Rules-Patterns", rules_patterns);
-              key_file.set_string_list (id_card.display_name, "Rules-AlwaysConfirm", rules_always_conf);
-            }
-            // Trust anchor 
-            key_file.set_string (id_card.display_name, "CA-Cert", id_card.trust_anchor.ca_cert ?? "");
-            key_file.set_string (id_card.display_name, "Subject", id_card.trust_anchor.subject ?? "");
-            key_file.set_string (id_card.display_name, "SubjectAlt", id_card.trust_anchor.subject_alt ?? "");
-            key_file.set_string (id_card.display_name, "ServerCert", id_card.trust_anchor.server_cert ?? "");
-        }
-
-        var text = key_file.to_data (null);
-
-        try
-        {
-            var path = get_data_dir ();
-            var filename = Path.build_filename (path, FILE_NAME);
-            FileUtils.set_contents (filename, text, -1);
-        }
-        catch (Error e)
-        {
-            stdout.printf ("Error:  %s\n", e.message);
-        }
-    }
+     public void update_card(IdCard card) {
+        store.update_card(card);
+        card_list_changed();
+     }
 
-    private string get_data_dir()
-    {
-        string path;
+     public void remove_card(IdCard card) {
+        store.remove_card(card);
+        card_list_changed();
+     }
 
-        path = Path.build_filename (Environment.get_user_data_dir (),
-                                    Config.PACKAGE_TARNAME);
-        if (!FileUtils.test (path, FileTest.EXISTS))
-        {
-            DirUtils.create (path, 0700);
-        }
+    private IdentityManagerApp parent;
 
-        return path;
+    public IdentityManagerModel(IdentityManagerApp parent_app) {
+        parent = parent_app;
+        store = new LocalFlatFileStore();
     }
 }
similarity index 86%
rename from src/moonshot-window.vala
rename to src/moonshot-identity-management-view.vala
index f1be90a..b0e1db2 100644 (file)
@@ -1,10 +1,10 @@
+using Gee;
 using Gtk;
 
-class MainWindow : Window
-{
+class IdentityManagerView : Window {
     private const int WINDOW_WIDTH = 400;
     private const int WINDOW_HEIGHT = 500;
-
+    protected IdentityManagerApp parent_app;
     private UIManager ui_manager = new UIManager();
     private Entry search_entry;
     private VBox vbox_right;
@@ -14,16 +14,14 @@ class MainWindow : Window
     private Entry username_entry;
     private Entry password_entry;
 
-    private ListStore listmodel;
+    private ListStore* listmodel;
     private TreeModelFilter filter;
 
-    public IdentitiesManager identities_manager;
+    public IdentityManagerModel identities_manager;
     private SList<IdCard>    candidates;
 
-    private MoonshotServer ipc_server;
-
     private IdCard default_id_card;
-    public Queue<IdentityRequest> request_queue;
+    public GLib.Queue<IdentityRequest> request_queue;
 
     private HashTable<Gtk.Button, string> service_button_map;
 
@@ -50,21 +48,22 @@ class MainWindow : Window
 "        </menu>" +
 "</menubar>";
 
-    public MainWindow()
-    {
-        request_queue = new Queue<IdentityRequest>();
-        
-        service_button_map = new HashTable<Gtk.Button, string> (direct_hash, direct_equal);
-
-        this.title = "Moonshoot";
-        this.set_position (WindowPosition.CENTER);
-        set_default_size (WINDOW_WIDTH, WINDOW_HEIGHT);
-
-        build_ui();
-        setup_identities_list();
+    public IdentityManagerView(IdentityManagerApp app) {
+       parent_app = app;
+       identities_manager = parent_app.model;
+       request_queue = new GLib.Queue<IdentityRequest>();
+       service_button_map = new HashTable<Gtk.Button, string> (direct_hash, direct_equal);
+       this.title = "Moonshoot";
+       this.set_position (WindowPosition.CENTER);
+       set_default_size (WINDOW_WIDTH, WINDOW_HEIGHT);
+       build_ui();
+       setup_list_model();
+        load_id_cards(); 
+       connect_signals();
+    }
+    
+    public void on_card_list_changed () {
         load_id_cards();
-        connect_signals();
-        init_ipc_server();
     }
     
     public void add_candidate (IdCard idcard)
@@ -138,9 +137,9 @@ class MainWindow : Window
         return false;
     }
 
-    private void setup_identities_list ()
+    private void setup_list_model ()
     {
-       this.listmodel = new ListStore (Columns.N_COLUMNS, typeof (IdCard),
+      this.listmodel = new ListStore (Columns.N_COLUMNS, typeof (IdCard),
                                                           typeof (Gdk.Pixbuf),
                                                           typeof (string),
                                                           typeof (string),
@@ -184,22 +183,28 @@ class MainWindow : Window
         return false;
     }
 
-    private void load_id_cards ()
-    {
-        identities_manager = new IdentitiesManager ();
-        
-        if (identities_manager.id_card_list == null)
-          return;
+    private void load_id_cards () {
+        var children = this.custom_vbox.get_children ();
+        foreach (var id_card_widget in children) {
+        remove_id_card_widget((IdCardWidget)id_card_widget);
+        }   
+
+        this.default_id_card = null;
+        LinkedList<IdCard> card_list = identities_manager.get_card_list() ;
+        if (card_list == null) {
+            return;
+        }
 
-        foreach (IdCard id_card in identities_manager.id_card_list)
-        {
+        foreach (IdCard id_card in card_list) {
             add_id_card_data (id_card);
             add_id_card_widget (id_card);
         }
 
-        this.default_id_card = identities_manager.id_card_list.data;
+        if (card_list.size > 0){
+            this.default_id_card = card_list.first();
+        }
     }
-
+    
     private void fill_details (IdCardWidget id_card_widget)
     {
        var id_card = id_card_widget.id_card;
@@ -210,7 +215,7 @@ class MainWindow : Window
        foreach (var hbox in children)
            hbox.destroy();
        fill_services_vbox (id_card_widget.id_card);
-       identities_manager.store_id_cards();
+//       identities_manager.store_id_cards();
     }
 
     private void show_details (IdCard id_card)
@@ -249,10 +254,9 @@ class MainWindow : Window
     {
         TreeIter   iter;
         Gdk.Pixbuf pixbuf;
-
-        this.listmodel.append (out iter);
+        this.listmodel->append (out iter);
         pixbuf = id_card.get_data("pixbuf");
-        listmodel.set (iter,
+        listmodel->set (iter,
                        Columns.IDCARD_COL, id_card,
                        Columns.LOGO_COL, pixbuf,
                        Columns.ISSUER_COL, id_card.issuer,
@@ -265,29 +269,27 @@ class MainWindow : Window
         TreeIter iter;
         string issuer;
 
-        if (listmodel.get_iter_first (out iter))
+        if (listmodel->get_iter_first (out iter))
         {
             do
             {
-                listmodel.get (iter,
+                listmodel->get (iter,
                                Columns.ISSUER_COL, out issuer);
 
                 if (id_card.issuer == issuer)
                 {
-                    listmodel.remove (iter);
+                    listmodel->remove (iter);
                     break;
                 }
             }
-            while (listmodel.iter_next (ref iter));
+            while (listmodel->iter_next (ref iter));
         }
     }
 
     private void add_id_card_widget (IdCard id_card)
     {
         var id_card_widget = new IdCardWidget (id_card);
-
         this.custom_vbox.add_id_card_widget (id_card_widget);
-
         id_card_widget.details_id.connect (details_identity_cb);
         id_card_widget.remove_id.connect (remove_identity_cb);
         id_card_widget.send_id.connect ((w) => send_identity_cb (w.id_card));
@@ -299,7 +301,7 @@ class MainWindow : Window
     public bool display_name_is_valid (string name,
                                        out string? candidate)
     {
-        foreach (IdCard id_card in identities_manager.id_card_list)
+        foreach (IdCard id_card in identities_manager.get_card_list())
         {
           if (id_card.display_name == name)
           {
@@ -331,11 +333,7 @@ class MainWindow : Window
           id_card.display_name = candidate;
         }
     
-        this.identities_manager.id_card_list.prepend (id_card);
-        this.identities_manager.store_id_cards ();
-
-        add_id_card_data (id_card);
-        add_id_card_widget (id_card);
+    this.identities_manager.add_card(id_card);
     }
 
     public bool add_identity (IdCard id_card)
@@ -377,21 +375,16 @@ class MainWindow : Window
         dialog.destroy ();
     }
 
-    private void remove_id_card_widget (IdCardWidget id_card_widget)
-    {
-        remove_id_card_data (id_card_widget.id_card);
-
-        this.custom_vbox.remove_id_card_widget (id_card_widget);
+    private void remove_id_card_widget (IdCardWidget id_card_widget) {
+       this.custom_vbox.remove_id_card_widget (id_card_widget);
     }
 
     private void remove_identity (IdCardWidget id_card_widget)
     {
         var id_card = id_card_widget.id_card;
-
-        this.identities_manager.id_card_list.remove (id_card);
-        this.identities_manager.store_id_cards ();
-
         remove_id_card_widget (id_card_widget);
+
+        this.identities_manager.remove_card(id_card);
     }
 
     private void redraw_id_card_widgets ()
@@ -458,7 +451,7 @@ class MainWindow : Window
             bool confirm = false;
             IdCard nai_provided = null;
 
-            foreach (IdCard id in identities_manager.id_card_list)
+            foreach (IdCard id in identities_manager.get_card_list())
             {
                 /* If NAI matches we add id card to the candidate list */
                 if (has_nai && request.nai == id.nai)
@@ -521,12 +514,12 @@ class MainWindow : Window
                 }
             }
 
-            identities_manager.store_id_cards ();
+//            identities_manager.store_id_cards ();
 
             /* If there are no candidates we use the service matching rules */
             if (candidates.length () == 0)
             {
-                foreach (IdCard id in identities_manager.id_card_list)
+                foreach (IdCard id in identities_manager.get_card_list())
                 {
                     foreach (Rule rule in id.rules)
                     {
@@ -594,7 +587,7 @@ class MainWindow : Window
 
             identity.services = services;
 
-            identities_manager.store_id_cards();
+//            identities_manager.store_id_cards();
         }
 
         if (identity.password == null)
@@ -947,84 +940,8 @@ SUCH DAMAGE.
     private void connect_signals()
     {
         this.destroy.connect (Gtk.main_quit);
+        this.identities_manager.card_list_changed.connect(this.on_card_list_changed);
     }
+}
 
-#if IPC_MSRPC
-    private void init_ipc_server ()
-    {
-        /* Errors will currently be sent via g_log - ie. to an
-         * obtrusive message box, on Windows
-         */
-        this.ipc_server = MoonshotServer.get_instance ();
-        MoonshotServer.start (this);
-    }
-#elif IPC_DBUS_GLIB
-    private void init_ipc_server ()
-    {
-        try {
-            var conn = DBus.Bus.get (DBus.BusType.SESSION);
-            dynamic DBus.Object bus = conn.get_object ("org.freedesktop.DBus",
-                                                       "/org/freedesktop/DBus",
-                                                       "org.freedesktop.DBus");
-
-            // try to register service in session bus
-            uint reply = bus.request_name ("org.janet.Moonshot", (uint) 0);
-            assert (reply == DBus.RequestNameReply.PRIMARY_OWNER);
-
-            this.ipc_server = new MoonshotServer (this);
-            conn.register_object ("/org/janet/moonshot", ipc_server);
-        }
-        catch (DBus.Error e)
-        {
-            stderr.printf ("%s\n", e.message);
-        }
-    }
-#else
-    private void bus_acquired_cb (DBusConnection conn)
-    {
-        try {
-            conn.register_object ("/org/janet/moonshot", ipc_server);
-        }
-        catch (Error e)
-        {
-            stderr.printf ("%s\n", e.message);
-        }
-    }
-
-    private void init_ipc_server ()
-    {
-        this.ipc_server = new MoonshotServer (this);
-        GLib.Bus.own_name (GLib.BusType.SESSION,
-                           "org.janet.Moonshot",
-                           GLib.BusNameOwnerFlags.NONE,
-                           bus_acquired_cb,
-                           (conn, name) => {},
-                           (conn, name) => {
-                               error ("Couldn't own name %s on DBus.", name);
-                           });
-    }
-#endif
-
-    public static int main(string[] args)
-    {
-        Gtk.init(ref args);
-
-#if OS_WIN32
-        // Force specific theme settings on Windows without requiring a gtkrc file
-        Gtk.Settings settings = Gtk.Settings.get_default ();
-        settings.set_string_property ("gtk-theme-name", "ms-windows", "moonshot");
-        settings.set_long_property ("gtk-menu-images", 0, "moonshot");
-#endif
-
-        Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
-        Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8");
-        Intl.textdomain (Config.GETTEXT_PACKAGE);
-
-        var window = new MainWindow();
-        window.show ();
-
-        Gtk.main();
 
-        return 0;
-    }
-}
diff --git a/src/moonshot-identity-manager-app.vala b/src/moonshot-identity-manager-app.vala
new file mode 100644 (file)
index 0000000..390e934
--- /dev/null
@@ -0,0 +1,100 @@
+using Gtk;
+
+class IdentityManagerApp : Window {
+    public IdentityManagerModel model;
+    private IdentityManagerView view;
+    private MoonshotServer ipc_server;
+    private const int WINDOW_WIDTH = 400;
+    private const int WINDOW_HEIGHT = 500;
+    public void show() {
+        view.show();    
+    }
+    public IdentityManagerApp () {
+        model = new IdentityManagerModel(this);
+        view = new IdentityManagerView(this);
+        init_ipc_server ();
+        view.show();
+    }   
+    
+#if IPC_MSRPC
+    private void init_ipc_server ()
+    {
+        // Errors will currently be sent via g_log - ie. to an
+        // obtrusive message box, on Windows
+        //
+        this.ipc_server = MoonshotServer.get_instance ();
+        MoonshotServer.start (this.view);
+    }
+#elif IPC_DBUS_GLIB
+    private void init_ipc_server ()
+    {
+        try {
+            var conn = DBus.Bus.get (DBus.BusType.SESSION);
+            dynamic DBus.Object bus = conn.get_object ("org.freedesktop.DBus",
+                                                       "/org/freedesktop/DBus",
+                                                       "org.freedesktop.DBus");
+
+            // try to register service in session bus
+            uint reply = bus.request_name ("org.janet.Moonshot", (uint) 0);
+            assert (reply == DBus.RequestNameReply.PRIMARY_OWNER);
+
+            this.ipc_server = new MoonshotServer (this.view);
+            conn.register_object ("/org/janet/moonshot", ipc_server);
+        }
+        catch (DBus.Error e)
+        {
+            stderr.printf ("%s\n", e.message);
+        }
+    }
+#else
+    private void bus_acquired_cb (DBusConnection conn)
+    {
+        try {
+            conn.register_object ("/org/janet/moonshot", ipc_server);
+        }
+        catch (Error e)
+        {
+            stderr.printf ("%s\n", e.message);
+        }
+    }
+
+    private void init_ipc_server ()
+    {
+        this.ipc_server = new MoonshotServer (this.view);
+        GLib.Bus.own_name (GLib.BusType.SESSION,
+                           "org.janet.Moonshot",
+                           GLib.BusNameOwnerFlags.NONE,
+                           bus_acquired_cb,
+                           (conn, name) => {},
+                           (conn, name) => {
+                               error ("Couldn't own name %s on DBus.", name);
+                           });
+    }
+#endif
+}
+
+
+public static int main(string[] args){
+        Gtk.init(ref args);
+
+#if OS_WIN32
+        // Force specific theme settings on Windows without requiring a gtkrc file
+        Gtk.Settings settings = Gtk.Settings.get_default ();
+        settings.set_string_property ("gtk-theme-name", "ms-windows", "moonshot");
+        settings.set_long_property ("gtk-menu-images", 0, "moonshot");
+#endif
+
+        Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
+        Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8");
+        Intl.textdomain (Config.GETTEXT_PACKAGE);
+       
+        var app = new IdentityManagerApp();
+        
+        app.show();
+
+        Gtk.main();
+
+        return 0;
+    }
+
index 8415048..bb67997 100644 (file)
@@ -5,14 +5,14 @@ class IdentityRequest : Object {
     public bool complete = false;
     public bool select_default = false;
 
-    private MainWindow main_window;
+    private IdentityManagerView main_window;
     public string nai;
     public string password;
     public string service;
 
     ReturnIdentityCallback callback = null;
 
-    public IdentityRequest (MainWindow                   main_window,
+    public IdentityRequest (IdentityManagerView                   main_window,
                             string                       nai,
                             string                       password,
                             string                       service)
@@ -23,7 +23,7 @@ class IdentityRequest : Object {
         this.service = service;
     }
 
-    public IdentityRequest.default (MainWindow main_window)
+    public IdentityRequest.default (IdentityManagerView main_window)
     {
         this.main_window = main_window;
         this.select_default = true;
diff --git a/src/moonshot-local-flat-file-store.vala b/src/moonshot-local-flat-file-store.vala
new file mode 100644 (file)
index 0000000..22981f5
--- /dev/null
@@ -0,0 +1,141 @@
+using Gee; 
+
+public class LocalFlatFileStore : Object, IIdentityCardStore {
+    private LinkedList<IdCard> id_card_list;
+    private const string FILE_NAME = "identities.txt";
+
+    public void add_card(IdCard card) {
+        id_card_list.add(card);
+        store_id_cards ();
+    }
+
+    public void update_card(IdCard card) {
+        id_card_list.remove(card);
+        id_card_list.add(card);
+        store_id_cards ();
+     }
+
+     public void remove_card(IdCard card) {
+        id_card_list.remove(card);
+        store_id_cards ();
+    }
+
+     public LinkedList<IdCard> get_card_list() {
+          return id_card_list; 
+     }
+     
+     private void load_id_cards() {
+        id_card_list.clear();
+        var key_file = new KeyFile ();
+        var path = get_data_dir ();
+        var filename = Path.build_filename (path, FILE_NAME);
+        
+        try {
+            key_file.load_from_file (filename, KeyFileFlags.NONE);
+        }
+        catch (Error e) {
+            stdout.printf("Error: %s\n", e.message);
+            return;
+        }
+
+        var identities_uris = key_file.get_groups ();
+        foreach (string identity in identities_uris) {
+            try {
+                IdCard id_card = new IdCard ();
+
+                id_card.issuer = key_file.get_string (identity, "Issuer");
+                id_card.username = key_file.get_string (identity, "Username");
+                id_card.password = key_file.get_string (identity, "Password");
+                id_card.services = key_file.get_string_list (identity, "Services");
+                id_card.display_name = key_file.get_string (identity, "DisplayName");
+                id_card.set_data ("pixbuf", find_icon ("avatar-default", 48));
+                
+                
+                if (key_file.has_key (identity, "Rules-Patterns") &&
+                    key_file.has_key (identity, "Rules-AlwaysConfirm")) {
+                    string [] rules_patterns =    key_file.get_string_list (identity, "Rules-Patterns");
+                    string [] rules_always_conf = key_file.get_string_list (identity, "Rules-AlwaysConfirm");
+                    
+                    if (rules_patterns.length == rules_always_conf.length) {
+                      Rule[] rules = new Rule[rules_patterns.length];
+                      for (int i = 0; i < rules_patterns.length; i++) {
+                        rules[i] = {rules_patterns[i], rules_always_conf[i]};
+                      }
+                      id_card.rules = rules;
+                    }
+                }
+                
+                // Trust anchor 
+                id_card.trust_anchor.ca_cert = key_file.get_string (identity, "CA-Cert");
+                id_card.trust_anchor.subject = key_file.get_string (identity, "Subject");
+                id_card.trust_anchor.subject_alt = key_file.get_string (identity, "SubjectAlt");
+                id_card.trust_anchor.server_cert = key_file.get_string (identity, "ServerCert");
+
+                id_card_list.add (id_card);
+            }
+            catch (Error e) {
+                stdout.printf ("Error:  %s\n", e.message);
+            }
+        }
+     }
+
+    private string get_data_dir() {
+        string path;
+        path = Path.build_filename (Environment.get_user_data_dir (),
+                                    Config.PACKAGE_TARNAME);
+                                    
+        if (!FileUtils.test (path, FileTest.EXISTS)) {
+            DirUtils.create (path, 0700);
+        }
+        return path;
+    }
+    
+    public void store_id_cards () {
+        var key_file = new KeyFile ();
+        foreach (IdCard id_card in this.id_card_list) {
+            string[] rules_patterns = new string[id_card.rules.length];
+            string[] rules_always_conf = new string[id_card.rules.length];
+            
+            for (int i=0; i<id_card.rules.length; i++) {
+              rules_patterns[i] = id_card.rules[i].pattern;
+              rules_always_conf[i] = id_card.rules[i].always_confirm;
+            }
+
+            key_file.set_string (id_card.display_name, "Issuer", id_card.issuer ?? "");
+            key_file.set_string (id_card.display_name, "DisplayName", id_card.display_name ?? "");
+            key_file.set_string (id_card.display_name, "Username", id_card.username ?? "");
+            key_file.set_string (id_card.display_name, "Password", id_card.password ?? "");
+            key_file.set_string_list (id_card.display_name, "Services", id_card.services ?? {});
+
+            if (id_card.rules.length > 0) {
+              key_file.set_string_list (id_card.display_name, "Rules-Patterns", rules_patterns);
+              key_file.set_string_list (id_card.display_name, "Rules-AlwaysConfirm", rules_always_conf);
+            }
+            
+            // Trust anchor 
+            key_file.set_string (id_card.display_name, "CA-Cert", id_card.trust_anchor.ca_cert ?? "");
+            key_file.set_string (id_card.display_name, "Subject", id_card.trust_anchor.subject ?? "");
+            key_file.set_string (id_card.display_name, "SubjectAlt", id_card.trust_anchor.subject_alt ?? "");
+            key_file.set_string (id_card.display_name, "ServerCert", id_card.trust_anchor.server_cert ?? "");
+        }
+
+        var text = key_file.to_data (null);
+
+        try {
+            var path = get_data_dir ();
+            var filename = Path.build_filename (path, FILE_NAME);
+            FileUtils.set_contents (filename, text, -1);
+        } 
+        catch (Error e) {
+            stdout.printf ("Error:  %s\n", e.message);
+        }
+
+        load_id_cards();
+    }
+
+     public LocalFlatFileStore () {
+        id_card_list = new LinkedList<IdCard>();
+        load_id_cards();
+     }
+ }
+
index c5cae18..abae433 100644 (file)
@@ -3,11 +3,11 @@
 [DBus (name = "org.janet.Moonshot")]
 public class MoonshotServer : Object {
 
-    private MainWindow main_window;
+    private IdentityManagerView main_window;
 
     public MoonshotServer (Gtk.Window window)
     {
-        this.main_window = (MainWindow) window;
+        this.main_window = (IdentityManagerView) window;
     }
 
     public async bool get_identity (string nai,
@@ -166,13 +166,13 @@ using MoonshotRpcInterface;
  * process ends
  */
 public class MoonshotServer : Object {
-    private static MainWindow main_window;
+    private static IdentityManagerView main_window;
 
     private static MoonshotServer instance = null;
 
     public static void start (Gtk.Window window)
     {
-        main_window = (MainWindow) window;
+        main_window = (IdentityManagerView) window;
         Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
     }