Add get_default_identity()
authorSam Thursfield <samthursfield@codethink.co.uk>
Thu, 30 Jun 2011 13:22:07 +0000 (14:22 +0100)
committerSam Thursfield <samthursfield@codethink.co.uk>
Thu, 30 Jun 2011 14:24:24 +0000 (15:24 +0100)
src/dbus-client.vala
src/moonshot-identity-request.vala
src/moonshot-msrpc.acf
src/moonshot-msrpc.idl
src/moonshot-msrpc.vapi
src/moonshot-server.vala
src/moonshot-window.vala
src/msrpc-client.vala

index ed34f8b..ef4cbe8 100644 (file)
@@ -2,6 +2,7 @@
 interface Moonshot : Object {
     public abstract bool get_identity (string nai, string password, string service,
                                        out string nai_out, out string password_out, out string certificate_out) throws DBus.Error;
+    public abstract bool get_default_identity (out string nai_out, out string password_out) throws DBus.Error;
 }
 
 void main () {
@@ -12,6 +13,17 @@ void main () {
         var demo = (Moonshot) conn.get_object ("org.janet.Moonshot",
                                                "/org/janet/moonshot");
 
+
+        if (demo.get_default_identity (out nai_out, out password_out))
+        {
+            stdout.printf ("default identity: %s %s\n", nai_out, password_out);
+        }
+        else
+        {
+            stdout.printf ("Unable to get default identity.\n");
+        }
+
+
         if (demo.get_identity ("username@issuer", "pass", "service", out nai_out, out password_out, out certificate_out))
         {
             stdout.printf ("%s %s %s\n", nai_out, password_out, certificate_out);
index 9568f4c..17f8b5e 100644 (file)
@@ -3,6 +3,7 @@ delegate void ReturnIdentityCallback (IdentityRequest request);
 class IdentityRequest : Object {
     public IdCard? id_card = null;
     public bool complete = false;
+    public bool select_default = false;
 
     private MainWindow main_window;
     private string nai;
@@ -22,6 +23,12 @@ class IdentityRequest : Object {
         this.certificate = certificate;
     }
 
+    public IdentityRequest.default (MainWindow main_window)
+    {
+        this.main_window = main_window;
+        this.select_default = true;
+    }
+
     public void set_callback (owned ReturnIdentityCallback cb)
     {
 #if VALA_0_12
index af441f2..cf5ed31 100644 (file)
@@ -4,6 +4,7 @@
 ]
 interface moonshot
 {
-       [async] moonshot_get_identity();
+    [async] moonshot_get_identity();
+    [async] moonshot_get_default_identity();
 }
 
index 1bcf181..7ed579c 100644 (file)
@@ -10,5 +10,8 @@ interface moonshot
                                [out, string] char **nai_out,
                                [out, string] char **password_out,
                                [out, string] char **certificate_out);
+
+    int moonshot_get_default_identity ([out, string] char **nai_out,
+                                       [out, string] char **password_out);
 }
 
index cef1097..d943c82 100644 (file)
@@ -18,4 +18,9 @@ namespace MoonshotRpcInterface {
                                      ref string nai_out,
                                      ref string password_out,
                                      ref string certificate_out);
+
+    [CCode (cname = "moonshot_get_default_identity")]
+    public extern void get_default_identity (Rpc.AsyncCall call,
+                                             ref string nai_out,
+                                             ref string password_out);
 }
index 8770b63..46dd6b5 100644 (file)
@@ -62,12 +62,50 @@ public class MoonshotServer : Object {
                 password_out = id_card.password;
                 certificate_out = "certificate";
 
+                // User should have been prompted if there was no p/w.
+                return_if_fail (nai_out != null);
+                return_if_fail (password_out != null);
+
                 return true;
             }
         }
 
         return false;
     }
+
+    /**
+     * Returns the default identity - most recently used.
+     *
+     * @param nai_out NAI stored in the ID card
+     * @param password_out Password stored in the ID card
+     *
+     * @return true on success, false if no identities are stored
+     */
+    public async bool get_default_identity (out string nai_out,
+                                            out string password_out)
+    {
+        var request = new IdentityRequest.default (main_window);
+        request.set_callback ((IdentityRequest) => get_default_identity.callback());
+        request.execute ();
+        yield;
+
+        nai_out = "";
+        password_out = "";
+
+        if (request.id_card != null)
+        {
+            nai_out = request.id_card.nai;
+            password_out = request.id_card.password;
+
+            // User should have been prompted if there was no p/w.
+            return_val_if_fail (nai_out != null, false);
+            return_val_if_fail (password_out != null, false);
+
+            return true;
+        }
+
+        return false;
+    }
 }
 
 #elif IPC_MSRPC
@@ -102,13 +140,13 @@ public class MoonshotServer : Object {
     }
 
     [CCode (cname = "moonshot_get_identity")]
-    public static void moonshot_get_identity (Rpc.AsyncCall call,
-                                              string nai,
-                                              string password,
-                                              string service,
-                                              ref string nai_out,
-                                              ref string password_out,
-                                              ref string certificate_out)
+    public static void get_identity (Rpc.AsyncCall call,
+                                     string nai,
+                                     string password,
+                                     string service,
+                                     ref string nai_out,
+                                     ref string password_out,
+                                     ref string certificate_out)
     {
         bool result = false;
 
@@ -149,6 +187,9 @@ public class MoonshotServer : Object {
                 password_out = id_card.password;
                 certificate_out = "certificate";
 
+                return_if_fail (nai_out != null);
+                return_if_fail (password_out != null);
+
                 result = true;
             }
         }
@@ -168,14 +209,9 @@ public class MoonshotServer : Object {
                                              ref string nai_out,
                                              ref string password_out)
     {
-        bool result = false;
+        bool result;
 
         var request = new IdentityRequest.default (main_window);
-
-        // This is really a lot of work to get a default identity.
-        // However, it's really best to do so in the main loop to avoid
-        // races (the alternative is add a mutex to the ID card data,
-        // but this is the only place it would be used).
         request.mutex = new Mutex ();
         request.cond = new Cond ();
         request.set_callback (return_identity_cb);
@@ -188,33 +224,22 @@ public class MoonshotServer : Object {
 
         nai_out = "";
         password_out = "";
-        certificate_out = "";
 
-        var id_card = request.id_card;
-        bool has_service = false;
+        if (request.id_card != null)
+        {
+            nai_out = request.id_card.nai;
+            password_out = request.id_card.password;
 
-        if (id_card == null) {
-            foreach (string id_card_service in id_card.services)
-            {
-                if (id_card_service == service)
-                    has_service = true;
-            }
+            return_if_fail (nai_out != null);
+            return_if_fail (password_out != null);
 
-            if (has_service)
-            {
-                // The strings are freed by the RPC runtime
-                nai_out = id_card.nai;
-                password_out = id_card.password;
-                certificate_out = "certificate";
-
-                result = true;
-            }
+            result = true;
+        }
+        else
+        {
+            result = false;
         }
 
-        // The outputs must be set before this function is called. For this
-        // reason they are 'ref' not 'out' parameters - Vala assigns to the
-        // 'out' parameters only at the end of the function, which is too
-        // late.
         call.return (&result);
 
         request.cond.signal ();
index 975f7ab..c62f6ff 100644 (file)
@@ -21,8 +21,7 @@ class MainWindow : Window
 
     private MoonshotServer ipc_server;
 
-    public IdCardWidget selected_id_card_widget;
-
+    private IdCard default_id_card;
     private Queue<IdentityRequest> request_queue;
 
     private enum Columns
@@ -148,6 +147,8 @@ class MainWindow : Window
             add_id_card_data (id_card);
             add_id_card_widget (id_card);
         }
+
+        this.default_id_card = id_card;
     }
 
     private void load_id_cards ()
@@ -159,6 +160,8 @@ class MainWindow : Window
             add_id_card_data (id_card);
             add_id_card_widget (id_card);
         }
+
+        this.default_id_card = identities_manager.id_card_list.data;
     }
 
     private void fill_details (IdCardWidget id_card_widget)
@@ -248,7 +251,7 @@ class MainWindow : Window
 
         id_card_widget.details_id.connect (details_identity_cb);
         id_card_widget.remove_id.connect (remove_identity_cb);
-        id_card_widget.send_id.connect (send_identity_cb);
+        id_card_widget.send_id.connect ((w) => send_identity_cb (w.id_card));
         id_card_widget.expanded.connect (this.custom_vbox.receive_expanded_event);
         id_card_widget.expanded.connect (fill_details);
     }
@@ -342,21 +345,36 @@ class MainWindow : Window
 
     public void select_identity (IdentityRequest request)
     {
-        /* Automatic service matching rules can go here */
+        IdCard identity = null;
 
-        /* Resort to manual selection */
         this.request_queue.push_tail (request);
-        this.show ();
+
+        if (request.select_default)
+        {
+            identity = this.default_id_card;
+        }
+
+        /* Automatic service matching rules can go here */
+
+        if (identity == null)
+        {
+            // Resort to manual selection
+            this.show ();
+        }
+        else
+        {
+            // Send back the identity (we can't directly run the
+            // callback because we may be being called from a 'yield')
+            Idle.add (() => { send_identity_cb (identity); return false; });
+            return;
+        }
     }
 
-    public void send_identity_cb (IdCardWidget id_card_widget)
+    public void send_identity_cb (IdCard identity)
     {
         return_if_fail (request_queue.length > 0);
 
-        this.selected_id_card_widget = id_card_widget;
-
         var request = this.request_queue.pop_head ();
-        var identity = id_card_widget.id_card;
         bool reset_password = false;
 
         if (identity.password == null)
@@ -380,6 +398,9 @@ class MainWindow : Window
         if (this.request_queue.is_empty())
             this.hide ();
 
+        if (identity != null)
+            this.default_id_card = identity;
+
         request.return_identity (identity);
 
         if (reset_password)
index fc44a51..6b4ba37 100644 (file)
@@ -9,6 +9,17 @@ void main () {
     string nai = null, password = null, certificate = null;
     bool result = false;
 
+    /* Get default identity */
+    Rpc.AsyncCall call = Rpc.AsyncCall();
+    get_default_identity (call, ref nai, ref password);
+    result = call.complete_bool ();
+
+    if (result == false)
+        error ("Unable to get default identity");
+    else
+        stdout.printf ("default: %s %s\n", nai, password);
+
+    /* Prompt for identity */
     Rpc.AsyncCall call = Rpc.AsyncCall();
     get_identity (call, "username@issuer", "pass", "service", ref nai, ref password, ref certificate);
     result = call.complete_bool ();