Make get_identity() 'service' parameter optional
[moonshot-ui.git] / src / moonshot-server.vala
1 #if IPC_DBUS
2
3 [DBus (name = "org.janet.Moonshot")]
4 public class MoonshotServer : Object {
5
6     private MainWindow main_window;
7
8     public MoonshotServer (Gtk.Window window)
9     {
10         this.main_window = (MainWindow) window;
11     }
12
13     /**
14      * This is the function used by the GSS mechanism to get the NAI,
15      * password and certificate of the ID card for the specificated service.
16      *
17      * The function will block until the user choose the ID card.
18      *
19      * @param nai NAI of the ID Card (optional)
20      * @param password Password of the ID Card (optional)
21      * @param service Service application request an ID Card for (optional)
22      * @param nai_out NAI stored in the ID Card
23      * @param password_out Password stored in the ID Card
24      * @param certificate Certificate stored in th ID Card
25      *
26      * @return true if the user choose a correct ID card for that service,
27      *         false otherwise.
28      */
29     public async bool get_identity (string nai,
30                                     string password,
31                                     string service,
32                                     out string nai_out,
33                                     out string password_out,
34                                     out string certificate_out)
35     {
36         var request = new IdentityRequest (main_window,
37                                            nai,
38                                            password,
39                                            service);
40         request.set_callback ((IdentityRequest) => get_identity.callback());
41         request.execute ();
42         yield;
43
44         nai_out = "";
45         password_out = "";
46         certificate_out = "";
47
48         var id_card = request.id_card;
49
50         if (id_card != null) {
51             nai_out = id_card.nai;
52             password_out = id_card.password;
53             certificate_out = "certificate";
54
55             // User should have been prompted if there was no p/w.
56             return_if_fail (nai_out != null);
57             return_if_fail (password_out != null);
58
59             return true;
60         }
61
62         return false;
63     }
64
65     /**
66      * Returns the default identity - most recently used.
67      *
68      * @param nai_out NAI stored in the ID card
69      * @param password_out Password stored in the ID card
70      *
71      * @return true on success, false if no identities are stored
72      */
73     public async bool get_default_identity (out string nai_out,
74                                             out string password_out)
75     {
76         var request = new IdentityRequest.default (main_window);
77         request.set_callback ((IdentityRequest) => get_default_identity.callback());
78         request.execute ();
79         yield;
80
81         nai_out = "";
82         password_out = "";
83
84         if (request.id_card != null)
85         {
86             nai_out = request.id_card.nai;
87             password_out = request.id_card.password;
88
89             // User should have been prompted if there was no p/w.
90             return_val_if_fail (nai_out != null, false);
91             return_val_if_fail (password_out != null, false);
92
93             return true;
94         }
95
96         return false;
97     }
98 }
99
100 #elif IPC_MSRPC
101
102 using Rpc;
103 using MoonshotRpcInterface;
104
105 /* This class must be a singleton, because we use a global RPC
106  * binding handle. I cannot picture a situation where more than
107  * one instance of the same interface would be needed so this
108  * shouldn't be a problem.
109  *
110  * Shutdown is automatically done by the RPC runtime when the
111  * process ends
112  */
113 public class MoonshotServer : Object {
114     private static MainWindow main_window;
115
116     private static MoonshotServer instance = null;
117
118     public static void start (Gtk.Window window)
119     {
120         main_window = (MainWindow) window;
121         Rpc.server_start (MoonshotRpcInterface.spec, "/org/janet/Moonshot", Rpc.Flags.PER_USER);
122     }
123
124     public static MoonshotServer get_instance ()
125     {
126         if (instance == null)
127             instance = new MoonshotServer ();
128         return instance;
129     }
130
131     [CCode (cname = "moonshot_get_identity")]
132     public static void get_identity (Rpc.AsyncCall call,
133                                      string nai,
134                                      string password,
135                                      string service,
136                                      ref string nai_out,
137                                      ref string password_out,
138                                      ref string certificate_out)
139     {
140         bool result = false;
141
142         var request = new IdentityRequest (main_window,
143                                            nai,
144                                            password,
145                                            service);
146
147         // Pass execution to the main loop and block the RPC thread
148         request.mutex = new Mutex ();
149         request.cond = new Cond ();
150         request.set_callback (return_identity_cb);
151
152         request.mutex.lock ();
153         Idle.add (request.execute);
154
155         while (request.complete == false)
156             request.cond.wait (request.mutex);
157
158         nai_out = "";
159         password_out = "";
160         certificate_out = "";
161
162         var id_card = request.id_card;
163
164         if (id_card == null) {
165             // The strings are freed by the RPC runtime
166             nai_out = id_card.nai;
167             password_out = id_card.password;
168             certificate_out = "certificate";
169
170             return_if_fail (nai_out != null);
171             return_if_fail (password_out != null);
172
173             result = true;
174         }
175
176         // The outputs must be set before this function is called. For this
177         // reason they are 'ref' not 'out' parameters - Vala assigns to the
178         // 'out' parameters only at the end of the function, which is too
179         // late.
180         call.return (&result);
181
182         request.cond.signal ();
183         request.mutex.unlock ();
184     }
185
186     [CCode (cname = "moonshot_get_default_identity")]
187     public static void get_default_identity (Rpc.AsyncCall call,
188                                              ref string nai_out,
189                                              ref string password_out)
190     {
191         bool result;
192
193         var request = new IdentityRequest.default (main_window);
194         request.mutex = new Mutex ();
195         request.cond = new Cond ();
196         request.set_callback (return_identity_cb);
197
198         request.mutex.lock ();
199         Idle.add (request.execute);
200
201         while (request.complete == false)
202             request.cond.wait (request.mutex);
203
204         nai_out = "";
205         password_out = "";
206
207         if (request.id_card != null)
208         {
209             nai_out = request.id_card.nai;
210             password_out = request.id_card.password;
211
212             return_if_fail (nai_out != null);
213             return_if_fail (password_out != null);
214
215             result = true;
216         }
217         else
218         {
219             result = false;
220         }
221
222         call.return (&result);
223
224         request.cond.signal ();
225         request.mutex.unlock ();
226     }
227
228     // Called from the main loop thread when an identity has
229     // been selected
230     static void return_identity_cb (IdentityRequest request) {
231         // Notify the RPC thread that the request is complete
232         request.mutex.lock ();
233         request.cond.signal ();
234
235         // Block the main loop until the RPC call has returned
236         // to avoid any races
237         request.cond.wait (request.mutex);
238         request.mutex.unlock ();
239     }
240 }
241
242 #endif