Merge lp:~ted/remote-login-service/signal-ready into lp:~ted/remote-login-service/oo-cleanup
- signal-ready
- Merge into oo-cleanup
Proposed by
Ted Gould
Status: | Superseded |
---|---|
Proposed branch: | lp:~ted/remote-login-service/signal-ready |
Merge into: | lp:~ted/remote-login-service/oo-cleanup |
Diff against target: |
807 lines (+379/-41) 12 files modified
src/citrix-server.c (+71/-4) src/citrix-server.h (+5/-0) src/defines.h (+2/-0) src/main.c (+52/-14) src/rdp-server.c (+71/-4) src/rdp-server.h (+5/-0) src/server.c (+17/-0) src/server.h (+13/-0) src/uccs-server.c (+45/-6) tests/dbus-interface.c (+54/-12) tests/server-test.c (+43/-0) tests/slmock (+1/-1) |
To merge this branch: | bzr merge lp:~ted/remote-login-service/signal-ready |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould | Pending | ||
Review via email: mp+123644@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-09-10.
Commit message
Add a state to the servers to know if they're configured
Description of the change
To post a comment you must log in.
Unmerged revisions
- 77. By Ted Gould
-
Attaching bug
- 76. By Ted Gould
-
Add an executable for the build system that don't have thin-client-
config- agent - 75. By Ted Gould
-
Don't need a tuple there apparently
- 74. By Ted Gould
-
Add a test to ensure we signaled updates
- 73. By Ted Gould
-
Pulling out the set_exec code so that we can test the signal stuff
- 72. By Ted Gould
-
When the server list changes emit the dbus signal
- 71. By Ted Gould
-
Handle a race with an extra DBus message
- 70. By Ted Gould
-
Moving where the config file is parsed to the servers aren't created until we've connected to DBus
- 69. By Ted Gould
-
Watching for servers updating themselves
- 68. By Ted Gould
-
Better handle the case of zero all good servers
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/citrix-server.c' |
2 | --- src/citrix-server.c 2012-08-29 19:09:54 +0000 |
3 | +++ src/citrix-server.c 2012-09-10 21:37:19 +0000 |
4 | @@ -20,6 +20,8 @@ |
5 | #include "config.h" |
6 | #endif |
7 | |
8 | +#include <string.h> |
9 | + |
10 | #include "citrix-server.h" |
11 | #include "defines.h" |
12 | |
13 | @@ -49,6 +51,10 @@ |
14 | static void |
15 | citrix_server_init (CitrixServer *self) |
16 | { |
17 | + self->username = NULL; |
18 | + self->password = NULL; |
19 | + self->domain = NULL; |
20 | + self->domain_required = FALSE; |
21 | |
22 | return; |
23 | } |
24 | @@ -61,9 +67,24 @@ |
25 | return; |
26 | } |
27 | |
28 | +/* Unlocks the memory before freeing */ |
29 | +static void |
30 | +password_clear (gpointer data) |
31 | +{ |
32 | + char * pass = (char *)data; |
33 | + munlock(pass, strlen(pass)); |
34 | + g_free(pass); |
35 | + return; |
36 | +} |
37 | + |
38 | static void |
39 | citrix_server_finalize (GObject *object) |
40 | { |
41 | + CitrixServer * server = CITRIX_SERVER(object); |
42 | + |
43 | + g_clear_pointer(&server->username, g_free); |
44 | + g_clear_pointer(&server->password, password_clear); |
45 | + g_clear_pointer(&server->domain, g_free); |
46 | |
47 | G_OBJECT_CLASS (citrix_server_parent_class)->finalize (object); |
48 | return; |
49 | @@ -72,6 +93,8 @@ |
50 | static GVariant * |
51 | get_properties (Server * server) |
52 | { |
53 | + CitrixServer * cserver = CITRIX_SERVER(server); |
54 | + |
55 | GVariantBuilder propbuilder; |
56 | g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY); |
57 | |
58 | @@ -79,7 +102,11 @@ |
59 | g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE); |
60 | g_variant_builder_add_value(&namebuilder, g_variant_new_string("username")); |
61 | g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE)); |
62 | - g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(""))); |
63 | + if (cserver->username == NULL) { |
64 | + g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(""))); |
65 | + } else { |
66 | + g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(cserver->username))); |
67 | + } |
68 | g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); |
69 | g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder)); |
70 | |
71 | @@ -87,15 +114,23 @@ |
72 | g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE); |
73 | g_variant_builder_add_value(&passbuilder, g_variant_new_string("password")); |
74 | g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE)); |
75 | - g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(""))); |
76 | + if (cserver->password == NULL) { |
77 | + g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(""))); |
78 | + } else { |
79 | + g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(cserver->password))); |
80 | + } |
81 | g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); |
82 | g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder)); |
83 | |
84 | GVariantBuilder domainbuilder; |
85 | g_variant_builder_init(&domainbuilder, G_VARIANT_TYPE_TUPLE); |
86 | g_variant_builder_add_value(&domainbuilder, g_variant_new_string("domain")); |
87 | - g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(TRUE)); |
88 | - g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(""))); |
89 | + g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(cserver->domain_required)); |
90 | + if (cserver->domain == NULL) { |
91 | + g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(""))); |
92 | + } else { |
93 | + g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(cserver->domain))); |
94 | + } |
95 | g_variant_builder_add_value(&domainbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); |
96 | g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&domainbuilder)); |
97 | |
98 | @@ -148,5 +183,37 @@ |
99 | } |
100 | } |
101 | |
102 | + if (json_object_has_member(object, JSON_USERNAME)) { |
103 | + JsonNode * node = json_object_get_member(object, JSON_USERNAME); |
104 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { |
105 | + const gchar * username = json_node_get_string(node); |
106 | + server->username = g_strdup(username); |
107 | + } |
108 | + } |
109 | + |
110 | + if (json_object_has_member(object, JSON_PASSWORD)) { |
111 | + JsonNode * node = json_object_get_member(object, JSON_PASSWORD); |
112 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { |
113 | + const gchar * password = json_node_get_string(node); |
114 | + server->password = g_strdup(password); |
115 | + mlock(server->password, strlen(server->password)); |
116 | + } |
117 | + } |
118 | + |
119 | + if (json_object_has_member(object, JSON_DOMAIN)) { |
120 | + JsonNode * node = json_object_get_member(object, JSON_DOMAIN); |
121 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { |
122 | + const gchar * domain = json_node_get_string(node); |
123 | + server->domain = g_strdup(domain); |
124 | + } |
125 | + } |
126 | + |
127 | + if (json_object_has_member(object, JSON_DOMAIN_REQ)) { |
128 | + JsonNode * node = json_object_get_member(object, JSON_DOMAIN_REQ); |
129 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_BOOLEAN) { |
130 | + server->domain_required = json_node_get_boolean(node); |
131 | + } |
132 | + } |
133 | + |
134 | return SERVER(server); |
135 | } |
136 | |
137 | === modified file 'src/citrix-server.h' |
138 | --- src/citrix-server.h 2012-08-16 18:44:58 +0000 |
139 | +++ src/citrix-server.h 2012-09-10 21:37:19 +0000 |
140 | @@ -41,6 +41,11 @@ |
141 | |
142 | struct _CitrixServer { |
143 | Server parent; |
144 | + |
145 | + gchar * username; |
146 | + gchar * password; |
147 | + gchar * domain; |
148 | + gboolean domain_required; |
149 | }; |
150 | |
151 | GType citrix_server_get_type (void); |
152 | |
153 | === modified file 'src/defines.h' |
154 | --- src/defines.h 2012-08-29 19:09:54 +0000 |
155 | +++ src/defines.h 2012-09-10 21:37:19 +0000 |
156 | @@ -37,5 +37,7 @@ |
157 | #define JSON_URI "URL" |
158 | #define JSON_USERNAME "Username" |
159 | #define JSON_PASSWORD "Password" |
160 | +#define JSON_DOMAIN_REQ "DomainRequired" |
161 | +#define JSON_DOMAIN "WindowsDomain" |
162 | |
163 | #endif /* __DEFINES_H__ */ |
164 | |
165 | === modified file 'src/main.c' |
166 | --- src/main.c 2012-08-29 19:09:44 +0000 |
167 | +++ src/main.c 2012-09-10 21:37:19 +0000 |
168 | @@ -26,6 +26,8 @@ |
169 | #include "citrix-server.h" |
170 | #include "uccs-server.h" |
171 | |
172 | +gint server_list_to_array (GVariantBuilder * builder, GList * items); |
173 | + |
174 | enum { |
175 | ERROR_SERVER_URI, |
176 | ERROR_LOGIN |
177 | @@ -44,8 +46,31 @@ |
178 | return value; |
179 | } |
180 | |
181 | -static void |
182 | -find_config_file (GKeyFile * parsed, const gchar * cmnd_line) |
183 | +/* When one of the state changes on the server emit that so that everone knows there |
184 | + might be a new server available. */ |
185 | +static void |
186 | +server_status_updated (Server * server, ServerState newstate, RemoteLogin * rl) |
187 | +{ |
188 | + GVariant * array = NULL; |
189 | + |
190 | + GVariantBuilder builder; |
191 | + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); |
192 | + |
193 | + if (server_list_to_array(&builder, config_file_servers) > 0) { |
194 | + array = g_variant_builder_end(&builder); |
195 | + } else { |
196 | + g_variant_builder_clear(&builder); |
197 | + array = g_variant_new_array(G_VARIANT_TYPE("(sssba(sbva{sv})a(si))"), NULL, 0); |
198 | + } |
199 | + |
200 | + remote_login_emit_servers_updated(rl, array); |
201 | + return; |
202 | +} |
203 | + |
204 | +/* Looks for the config file and does some basic parsing to pull out the UCCS servers |
205 | + that are configured in it */ |
206 | +static void |
207 | +find_config_file (GKeyFile * parsed, const gchar * cmnd_line, RemoteLogin * rl) |
208 | { |
209 | GError * error = NULL; |
210 | const gchar * file = DEFAULT_CONFIG_FILE; |
211 | @@ -82,25 +107,37 @@ |
212 | } |
213 | |
214 | config_file_servers = g_list_append(config_file_servers, server); |
215 | + g_signal_connect(server, SERVER_SIGNAL_STATE_CHANGED, G_CALLBACK(server_status_updated), rl); |
216 | } |
217 | |
218 | g_strfreev(grouplist); |
219 | } |
220 | |
221 | + /* Signal the list of servers so that we're sure everyone's got them. This is to |
222 | + solve a possible race where someone could ask while we're configuring these. */ |
223 | + server_status_updated(NULL, SERVER_STATE_ALLGOOD, rl); |
224 | return; |
225 | } |
226 | |
227 | -void |
228 | +gint |
229 | server_list_to_array (GVariantBuilder * builder, GList * items) |
230 | { |
231 | + gint servercnt = 0; |
232 | GList * head = NULL; |
233 | for (head = items; head != NULL; head = g_list_next(head)) { |
234 | Server * server = SERVER(head->data); |
235 | + |
236 | + /* We only want servers that are all good */ |
237 | + if (server->state != SERVER_STATE_ALLGOOD) { |
238 | + continue; |
239 | + } |
240 | + |
241 | + servercnt++; |
242 | GVariant * variant = server_get_variant(server); |
243 | g_variant_builder_add_value(builder, variant); |
244 | } |
245 | |
246 | - return; |
247 | + return servercnt; |
248 | } |
249 | |
250 | static gboolean |
251 | @@ -108,14 +145,13 @@ |
252 | { |
253 | GVariant * array = NULL; |
254 | |
255 | - if (g_list_length(config_file_servers) > 0) { |
256 | - GVariantBuilder builder; |
257 | - g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); |
258 | - |
259 | - server_list_to_array(&builder, config_file_servers); |
260 | - |
261 | + GVariantBuilder builder; |
262 | + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); |
263 | + |
264 | + if (server_list_to_array(&builder, config_file_servers) > 0) { |
265 | array = g_variant_builder_end(&builder); |
266 | } else { |
267 | + g_variant_builder_clear(&builder); |
268 | array = g_variant_new_array(G_VARIANT_TYPE("(sssba(sbva{sv})a(si))"), NULL, 0); |
269 | } |
270 | |
271 | @@ -279,7 +315,7 @@ |
272 | { |
273 | GMainLoop * mainloop = (GMainLoop *)user_data; |
274 | |
275 | - g_error("Unable to get name '%s'", name); |
276 | + g_warning("Unable to get name '%s'. Exiting.", name); |
277 | g_main_loop_quit(mainloop); |
278 | |
279 | return; |
280 | @@ -313,9 +349,6 @@ |
281 | return 1; |
282 | } |
283 | |
284 | - /* Parse config file */ |
285 | - find_config_file(config, cmnd_line_config); |
286 | - |
287 | /* Start up D' Bus */ |
288 | GDBusConnection * session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL /* cancel */, &error); |
289 | if (error != NULL) { |
290 | @@ -324,7 +357,9 @@ |
291 | return -1; |
292 | } |
293 | |
294 | + /* Build Dbus Interface */ |
295 | RemoteLogin * skel = remote_login_skeleton_new(); |
296 | + /* Export it */ |
297 | g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skel), |
298 | session_bus, |
299 | "/com/canonical/RemoteLogin", |
300 | @@ -341,6 +376,9 @@ |
301 | mainloop, |
302 | NULL); /* mainloop free */ |
303 | |
304 | + /* Parse config file */ |
305 | + find_config_file(config, cmnd_line_config, skel); |
306 | + |
307 | /* Loop forever */ |
308 | g_main_loop_run(mainloop); |
309 | |
310 | |
311 | === modified file 'src/rdp-server.c' |
312 | --- src/rdp-server.c 2012-08-29 19:09:54 +0000 |
313 | +++ src/rdp-server.c 2012-09-10 21:37:19 +0000 |
314 | @@ -20,6 +20,8 @@ |
315 | #include "config.h" |
316 | #endif |
317 | |
318 | +#include <string.h> |
319 | + |
320 | #include "rdp-server.h" |
321 | #include "defines.h" |
322 | |
323 | @@ -49,6 +51,10 @@ |
324 | static void |
325 | rdp_server_init (RdpServer *self) |
326 | { |
327 | + self->username = NULL; |
328 | + self->password = NULL; |
329 | + self->domain = NULL; |
330 | + self->domain_required = FALSE; |
331 | |
332 | return; |
333 | } |
334 | @@ -61,9 +67,24 @@ |
335 | return; |
336 | } |
337 | |
338 | +/* Unlocks the memory before freeing */ |
339 | +static void |
340 | +password_clear (gpointer data) |
341 | +{ |
342 | + char * pass = (char *)data; |
343 | + munlock(pass, strlen(pass)); |
344 | + g_free(pass); |
345 | + return; |
346 | +} |
347 | + |
348 | static void |
349 | rdp_server_finalize (GObject *object) |
350 | { |
351 | + RdpServer * server = RDP_SERVER(object); |
352 | + |
353 | + g_clear_pointer(&server->username, g_free); |
354 | + g_clear_pointer(&server->password, password_clear); |
355 | + g_clear_pointer(&server->domain, g_free); |
356 | |
357 | G_OBJECT_CLASS (rdp_server_parent_class)->finalize (object); |
358 | return; |
359 | @@ -72,6 +93,8 @@ |
360 | static GVariant * |
361 | get_properties (Server * server) |
362 | { |
363 | + RdpServer * rserver = RDP_SERVER(server); |
364 | + |
365 | GVariantBuilder propbuilder; |
366 | g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY); |
367 | |
368 | @@ -79,7 +102,11 @@ |
369 | g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE); |
370 | g_variant_builder_add_value(&namebuilder, g_variant_new_string("username")); |
371 | g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE)); |
372 | - g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(""))); |
373 | + if (rserver->username == NULL) { |
374 | + g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(""))); |
375 | + } else { |
376 | + g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(rserver->username))); |
377 | + } |
378 | g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); |
379 | g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder)); |
380 | |
381 | @@ -87,15 +114,23 @@ |
382 | g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE); |
383 | g_variant_builder_add_value(&passbuilder, g_variant_new_string("password")); |
384 | g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE)); |
385 | - g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(""))); |
386 | + if (rserver->password == NULL) { |
387 | + g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(""))); |
388 | + } else { |
389 | + g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(rserver->password))); |
390 | + } |
391 | g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); |
392 | g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder)); |
393 | |
394 | GVariantBuilder domainbuilder; |
395 | g_variant_builder_init(&domainbuilder, G_VARIANT_TYPE_TUPLE); |
396 | g_variant_builder_add_value(&domainbuilder, g_variant_new_string("domain")); |
397 | - g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(TRUE)); |
398 | - g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(""))); |
399 | + g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(rserver->domain_required)); |
400 | + if (rserver->domain == NULL) { |
401 | + g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(""))); |
402 | + } else { |
403 | + g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(rserver->domain))); |
404 | + } |
405 | g_variant_builder_add_value(&domainbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL)); |
406 | g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&domainbuilder)); |
407 | |
408 | @@ -148,5 +183,37 @@ |
409 | } |
410 | } |
411 | |
412 | + if (json_object_has_member(object, JSON_USERNAME)) { |
413 | + JsonNode * node = json_object_get_member(object, JSON_USERNAME); |
414 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { |
415 | + const gchar * username = json_node_get_string(node); |
416 | + server->username = g_strdup(username); |
417 | + } |
418 | + } |
419 | + |
420 | + if (json_object_has_member(object, JSON_PASSWORD)) { |
421 | + JsonNode * node = json_object_get_member(object, JSON_PASSWORD); |
422 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { |
423 | + const gchar * password = json_node_get_string(node); |
424 | + server->password = g_strdup(password); |
425 | + mlock(server->password, strlen(server->password)); |
426 | + } |
427 | + } |
428 | + |
429 | + if (json_object_has_member(object, JSON_DOMAIN)) { |
430 | + JsonNode * node = json_object_get_member(object, JSON_DOMAIN); |
431 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_STRING) { |
432 | + const gchar * domain = json_node_get_string(node); |
433 | + server->domain = g_strdup(domain); |
434 | + } |
435 | + } |
436 | + |
437 | + if (json_object_has_member(object, JSON_DOMAIN_REQ)) { |
438 | + JsonNode * node = json_object_get_member(object, JSON_DOMAIN_REQ); |
439 | + if (JSON_NODE_TYPE(node) == JSON_NODE_VALUE && json_node_get_value_type(node) == G_TYPE_BOOLEAN) { |
440 | + server->domain_required = json_node_get_boolean(node); |
441 | + } |
442 | + } |
443 | + |
444 | return SERVER(server); |
445 | } |
446 | |
447 | === modified file 'src/rdp-server.h' |
448 | --- src/rdp-server.h 2012-08-16 18:44:58 +0000 |
449 | +++ src/rdp-server.h 2012-09-10 21:37:19 +0000 |
450 | @@ -41,6 +41,11 @@ |
451 | |
452 | struct _RdpServer { |
453 | Server parent; |
454 | + |
455 | + gchar * username; |
456 | + gchar * password; |
457 | + gchar * domain; |
458 | + gboolean domain_required; |
459 | }; |
460 | |
461 | GType rdp_server_get_type (void); |
462 | |
463 | === modified file 'src/server.c' |
464 | --- src/server.c 2012-08-29 18:49:21 +0000 |
465 | +++ src/server.c 2012-09-10 21:37:19 +0000 |
466 | @@ -31,8 +31,16 @@ |
467 | static void server_dispose (GObject *object); |
468 | static void server_finalize (GObject *object); |
469 | |
470 | +/* Signals */ |
471 | +enum { |
472 | + STATE_CHANGED, |
473 | + LAST_SIGNAL |
474 | +}; |
475 | + |
476 | G_DEFINE_TYPE (Server, server, G_TYPE_OBJECT); |
477 | |
478 | +static guint signals[LAST_SIGNAL] = { 0 }; |
479 | + |
480 | static void |
481 | server_class_init (ServerClass *klass) |
482 | { |
483 | @@ -41,6 +49,14 @@ |
484 | object_class->dispose = server_dispose; |
485 | object_class->finalize = server_finalize; |
486 | |
487 | + signals[STATE_CHANGED] = g_signal_new(SERVER_SIGNAL_STATE_CHANGED, |
488 | + G_TYPE_FROM_CLASS(klass), |
489 | + G_SIGNAL_RUN_LAST, |
490 | + G_STRUCT_OFFSET(ServerClass, state_changed), |
491 | + NULL, NULL, |
492 | + g_cclosure_marshal_VOID__INT, |
493 | + G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_NONE); |
494 | + |
495 | return; |
496 | } |
497 | |
498 | @@ -50,6 +66,7 @@ |
499 | self->name = NULL; |
500 | self->uri = NULL; |
501 | self->last_used = FALSE; |
502 | + self->state = SERVER_STATE_ALLGOOD; |
503 | |
504 | return; |
505 | } |
506 | |
507 | === modified file 'src/server.h' |
508 | --- src/server.h 2012-08-29 18:34:04 +0000 |
509 | +++ src/server.h 2012-09-10 21:37:19 +0000 |
510 | @@ -31,8 +31,16 @@ |
511 | #define IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SERVER_TYPE)) |
512 | #define SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SERVER_TYPE, ServerClass)) |
513 | |
514 | +#define SERVER_SIGNAL_STATE_CHANGED "state-changed" |
515 | + |
516 | typedef struct _Server Server; |
517 | typedef struct _ServerClass ServerClass; |
518 | +typedef enum _ServerState ServerState; |
519 | + |
520 | +enum _ServerState { |
521 | + SERVER_STATE_ALLGOOD, |
522 | + SERVER_STATE_UNAVAILABLE |
523 | +}; |
524 | |
525 | struct _ServerClass { |
526 | GObjectClass parent_class; |
527 | @@ -40,6 +48,9 @@ |
528 | GVariant * (*get_applications) (Server * server); |
529 | GVariant * (*get_domains) (Server * server); |
530 | Server * (*find_uri) (Server * server, const gchar * uri); |
531 | + |
532 | + /* signals */ |
533 | + void (*state_changed) (Server * server, ServerState newstate, gpointer user_data); |
534 | }; |
535 | |
536 | struct _Server { |
537 | @@ -48,6 +59,8 @@ |
538 | gchar * name; |
539 | gchar * uri; |
540 | gboolean last_used; |
541 | + |
542 | + ServerState state; |
543 | }; |
544 | |
545 | GType server_get_type (void); |
546 | |
547 | === modified file 'src/uccs-server.c' |
548 | --- src/uccs-server.c 2012-08-29 19:09:54 +0000 |
549 | +++ src/uccs-server.c 2012-09-10 21:37:19 +0000 |
550 | @@ -90,6 +90,10 @@ |
551 | self->json_stream = NULL; |
552 | self->pass_stream = NULL; |
553 | |
554 | + if (self->exec == NULL) { |
555 | + self->parent.state = SERVER_STATE_UNAVAILABLE; |
556 | + } |
557 | + |
558 | return; |
559 | } |
560 | |
561 | @@ -234,6 +238,33 @@ |
562 | return g_variant_builder_end(&propbuilder); |
563 | } |
564 | |
565 | +/* Set the exec value for the server */ |
566 | +const gchar * |
567 | +uccs_server_set_exec (UccsServer * server, const gchar * exec) |
568 | +{ |
569 | + g_return_val_if_fail(IS_UCCS_SERVER(server), NULL); |
570 | + |
571 | + g_clear_pointer(&server->exec, g_free); |
572 | + |
573 | + if (exec != NULL) { |
574 | + server->exec = g_find_program_in_path(exec); |
575 | + } |
576 | + |
577 | + ServerState oldstate = server->parent.state; |
578 | + if (server->exec != NULL) { |
579 | + server->parent.state = SERVER_STATE_ALLGOOD; |
580 | + } else { |
581 | + server->parent.state = SERVER_STATE_UNAVAILABLE; |
582 | + } |
583 | + |
584 | + if (server->parent.state != oldstate) { |
585 | + g_signal_emit_by_name(server, SERVER_SIGNAL_STATE_CHANGED, server->parent.state); |
586 | + } |
587 | + |
588 | + return server->exec; |
589 | +} |
590 | + |
591 | +/* Build a new uccs server from a keyfile and a group in it */ |
592 | Server * |
593 | uccs_server_new_from_keyfile (GKeyFile * keyfile, const gchar * groupname) |
594 | { |
595 | @@ -256,9 +287,8 @@ |
596 | } |
597 | |
598 | if (g_key_file_has_key(keyfile, groupname, CONFIG_UCCS_EXEC, NULL)) { |
599 | - g_free(server->exec); |
600 | gchar * key = g_key_file_get_string(keyfile, groupname, CONFIG_UCCS_EXEC, NULL); |
601 | - server->exec = g_find_program_in_path(key); |
602 | + uccs_server_set_exec(server, key); |
603 | g_free(key); |
604 | } |
605 | |
606 | @@ -572,18 +602,27 @@ |
607 | return null_server_array(); |
608 | } |
609 | |
610 | - if (g_list_length(server->subservers) == 0) { |
611 | - return null_server_array(); |
612 | - } |
613 | - |
614 | GVariantBuilder array; |
615 | g_variant_builder_init(&array, G_VARIANT_TYPE_ARRAY); |
616 | GList * lserver; |
617 | + gint servercnt = 0; |
618 | for (lserver = server->subservers; lserver != NULL; lserver = g_list_next(lserver)) { |
619 | Server * serv = SERVER(lserver->data); |
620 | + |
621 | + /* We only want servers that are all good */ |
622 | + if (serv->state != SERVER_STATE_ALLGOOD) { |
623 | + continue; |
624 | + } |
625 | + |
626 | + servercnt++; |
627 | g_variant_builder_add_value(&array, server_get_variant(serv)); |
628 | } |
629 | |
630 | + if (servercnt == 0) { |
631 | + g_variant_builder_clear(&array); |
632 | + return null_server_array(); |
633 | + } |
634 | + |
635 | return g_variant_builder_end(&array); |
636 | } |
637 | |
638 | |
639 | === modified file 'tests/dbus-interface.c' |
640 | --- tests/dbus-interface.c 2012-08-27 15:45:46 +0000 |
641 | +++ tests/dbus-interface.c 2012-09-10 21:37:19 +0000 |
642 | @@ -16,28 +16,31 @@ |
643 | const gchar * name; |
644 | const gchar * uri; |
645 | const gchar * type; |
646 | - /* TODO: Add more as we get more working */ |
647 | + const gchar * username; |
648 | + const gchar * password; |
649 | + const gchar * domain; |
650 | }; |
651 | |
652 | slmock_server_t citrix_server_table[] = { |
653 | - {"Citrix USA", "107.21.17.35", "ica"}, |
654 | - {"Citrix 2", "107.21.17.35", "ica"}, |
655 | - {"Citrix 3", "107.21.17.35", "ica"}, |
656 | + {"Citrix USA", "107.21.17.35", "ica", "useradmin1", "", "IP-0A00001E"}, |
657 | + {"Citrix 2", "107.21.17.35", "ica", "useradmin2", "", "IP-0A00001E"}, |
658 | + {"Citrix 3", "107.21.17.35", "ica", "useradmin3", "", "IP-0A00001E"}, |
659 | + {"Citrix 4", "107.21.17.35", "ica", "useradmin4", "userpass", "IP-0A00001E"}, |
660 | {NULL, NULL, NULL} |
661 | }; |
662 | |
663 | slmock_server_t freerdp_server_table[] = { |
664 | - {"FreeRDP US", "23.21.151.133", "freerdp"}, |
665 | - {"FreeRDP Asia", "46.137.222.181", "freerdp"}, |
666 | - {"FreeRDP UK", "46.137.189.194", "freerdp"}, |
667 | + {"FreeRDP US", "23.21.151.133", "freerdp", "Administrator", "", ""}, |
668 | + {"FreeRDP Asia", "46.137.222.181", "freerdp", "Administrator", "", ""}, |
669 | + {"FreeRDP UK", "46.137.189.194", "freerdp", "Administrator", "", ""}, |
670 | {NULL, NULL, NULL} |
671 | }; |
672 | |
673 | slmock_server_t big_server_table[] = { |
674 | - {"XenServer", "107.21.17.35", "ica"}, |
675 | - {"Citrix2", "http://1.2.3.4", "ica"}, |
676 | - {"Accenture", "10.21.17.35", "freerdp"}, |
677 | - {"Accenture 2", "https://4.5.6.7", "freerdp"}, |
678 | + {"XenServer", "107.21.17.35", "ica", "", "", "ASIA"}, |
679 | + {"Citrix2", "http://1.2.3.4", "ica", "fakeuser", "fakepassword", "DOMAIN1"}, |
680 | + {"Accenture", "10.21.17.35", "freerdp", "fakeuser", "", "EUROPE"}, |
681 | + {"Accenture 2", "https://4.5.6.7", "freerdp", "", "", "domain2"}, |
682 | {NULL, NULL, NULL} |
683 | }; |
684 | |
685 | @@ -79,8 +82,47 @@ |
686 | continue; |
687 | } |
688 | |
689 | + gboolean match_username = FALSE; |
690 | + gboolean match_password = FALSE; |
691 | + gboolean match_domain = FALSE; |
692 | + |
693 | + GVariant * props = g_variant_get_child_value(child, 4); |
694 | + int iprop; |
695 | + for (iprop = 0; iprop < g_variant_n_children(props); iprop++) { |
696 | + GVariant * prop = g_variant_get_child_value(props, iprop); |
697 | + |
698 | + GVariant * prop_type = g_variant_get_child_value(prop, 0); |
699 | + GVariant * prop_value_wrap = g_variant_get_child_value(prop, 2); |
700 | + GVariant * prop_value = g_variant_get_variant(prop_value_wrap); |
701 | + |
702 | + if (g_strcmp0(g_variant_get_string(prop_type, NULL), "username") == 0) { |
703 | + if (g_strcmp0(g_variant_get_string(prop_value, NULL), server->username) == 0) { |
704 | + match_username = TRUE; |
705 | + } |
706 | + } else if (g_strcmp0(g_variant_get_string(prop_type, NULL), "password") == 0) { |
707 | + if (g_strcmp0(g_variant_get_string(prop_value, NULL), server->password) == 0) { |
708 | + match_password = TRUE; |
709 | + } |
710 | + } else if (g_strcmp0(g_variant_get_string(prop_type, NULL), "domain") == 0) { |
711 | + if (g_strcmp0(g_variant_get_string(prop_value, NULL), server->domain) == 0) { |
712 | + match_domain = TRUE; |
713 | + } |
714 | + } |
715 | + |
716 | + g_variant_unref(prop_value); |
717 | + g_variant_unref(prop_value_wrap); |
718 | + g_variant_unref(prop_type); |
719 | + g_variant_unref(prop); |
720 | + } |
721 | + g_variant_unref(props); |
722 | + |
723 | g_variant_unref(child); |
724 | - return TRUE; |
725 | + |
726 | + if (match_username && match_password && match_domain) { |
727 | + return TRUE; |
728 | + } else { |
729 | + continue; |
730 | + } |
731 | } |
732 | |
733 | return FALSE; |
734 | |
735 | === modified file 'tests/server-test.c' |
736 | --- tests/server-test.c 2012-08-29 19:44:17 +0000 |
737 | +++ tests/server-test.c 2012-09-10 21:37:19 +0000 |
738 | @@ -7,6 +7,48 @@ |
739 | #include "uccs-server.h" |
740 | |
741 | static void |
742 | +state_signal (Server * server, ServerState newstate, gboolean * signaled) |
743 | +{ |
744 | + *signaled = TRUE; |
745 | + return; |
746 | +} |
747 | + |
748 | +static void |
749 | +test_update_signal (void) |
750 | +{ |
751 | + GKeyFile * keyfile = g_key_file_new(); |
752 | + const gchar * groupname = CONFIG_SERVER_PREFIX " Server Name"; |
753 | + g_key_file_set_string(keyfile, groupname, CONFIG_SERVER_NAME, "My Server"); |
754 | + g_key_file_set_string(keyfile, groupname, CONFIG_SERVER_URI, "http://my.domain.com"); |
755 | + |
756 | + Server * server = NULL; |
757 | + server = server_new_from_keyfile(keyfile, groupname); |
758 | + g_assert(server != NULL); |
759 | + g_assert(g_strcmp0(server->name, "My Server") == 0); |
760 | + g_assert(g_strcmp0(server->uri, "http://my.domain.com") == 0); |
761 | + |
762 | + UccsServer * userver = UCCS_SERVER(server); |
763 | + g_assert(userver != NULL); |
764 | + |
765 | + gboolean signaled = FALSE; |
766 | + g_signal_connect(G_OBJECT(server), SERVER_SIGNAL_STATE_CHANGED, G_CALLBACK(state_signal), &signaled); |
767 | + |
768 | + if (server->state == SERVER_STATE_ALLGOOD) { |
769 | + signaled = FALSE; |
770 | + uccs_server_set_exec(userver, "thisshouldnotexist"); |
771 | + g_assert(signaled); |
772 | + g_assert(server->state == SERVER_STATE_UNAVAILABLE); |
773 | + } |
774 | + |
775 | + signaled = FALSE; |
776 | + uccs_server_set_exec(userver, "ls"); |
777 | + g_assert(signaled); |
778 | + g_assert(server->state == SERVER_STATE_ALLGOOD); |
779 | + |
780 | + return; |
781 | +} |
782 | + |
783 | +static void |
784 | test_uccs_domains (void) |
785 | { |
786 | GKeyFile * keyfile = g_key_file_new(); |
787 | @@ -199,6 +241,7 @@ |
788 | |
789 | g_test_add_func ("/server/uccs/exec", test_uccs_exec); |
790 | g_test_add_func ("/server/uccs/domains", test_uccs_domains); |
791 | + g_test_add_func ("/server/uccs/signal", test_update_signal); |
792 | |
793 | return; |
794 | } |
795 | |
796 | === modified file 'tests/slmock' |
797 | --- tests/slmock 2012-08-21 15:46:54 +0000 |
798 | +++ tests/slmock 2012-09-10 21:37:19 +0000 |
799 | @@ -93,7 +93,7 @@ |
800 | ts3 = TerminalServer("107.21.17.35", "Citrix 3", "ICA", True, |
801 | "useradmin3") |
802 | ts4 = TerminalServer("107.21.17.35", "Citrix 4", "ICA", True, |
803 | - "useradmin4") |
804 | + "useradmin4", "userpass") |
805 | ts1.add_domain("IP-0A00001E") |
806 | ts2.add_domain("IP-0A00001E") |
807 | ts3.add_domain("IP-0A00001E") |