]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blob - tests/src/test-gobject-greeter.c
Refactor shared data tests so they don't require root.
[sojka/lightdm.git] / tests / src / test-gobject-greeter.c
1 /* -*- Mode: C; indent-tabs-mode: nil; tab-width: 4 -*- */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <xcb/xcb.h>
7 #include <lightdm.h>
8 #include <glib-unix.h>
9 #include <ctype.h>
10
11 #include "status.h"
12
13 static gchar *greeter_id;
14 static GMainLoop *loop;
15 static LightDMGreeter *greeter;
16 static xcb_connection_t *connection = NULL;
17 static GKeyFile *config;
18
19 static void
20 show_message_cb (LightDMGreeter *greeter, const gchar *text, LightDMMessageType type)
21 {
22     status_notify ("%s SHOW-MESSAGE TEXT=\"%s\"", greeter_id, text);
23 }
24
25 static void
26 show_prompt_cb (LightDMGreeter *greeter, const gchar *text, LightDMPromptType type)
27 {
28     status_notify ("%s SHOW-PROMPT TEXT=\"%s\"", greeter_id, text);
29 }
30
31 static void
32 authentication_complete_cb (LightDMGreeter *greeter)
33 {
34     if (lightdm_greeter_get_authentication_user (greeter))
35         status_notify ("%s AUTHENTICATION-COMPLETE USERNAME=%s AUTHENTICATED=%s",
36                        greeter_id,
37                        lightdm_greeter_get_authentication_user (greeter),
38                        lightdm_greeter_get_is_authenticated (greeter) ? "TRUE" : "FALSE");
39     else
40         status_notify ("%s AUTHENTICATION-COMPLETE AUTHENTICATED=%s",
41                        greeter_id,
42                        lightdm_greeter_get_is_authenticated (greeter) ? "TRUE" : "FALSE");
43 }
44
45 static void
46 autologin_timer_expired_cb (LightDMGreeter *greeter)
47 {
48     status_notify ("%s AUTOLOGIN-TIMER-EXPIRED", greeter_id);
49 }
50
51 static gboolean
52 sigint_cb (gpointer user_data)
53 {
54     status_notify ("%s TERMINATE SIGNAL=%d", greeter_id, SIGINT);
55     g_main_loop_quit (loop);
56     return TRUE;
57 }
58
59 static gboolean
60 sigterm_cb (gpointer user_data)
61 {
62     status_notify ("%s TERMINATE SIGNAL=%d", greeter_id, SIGTERM);
63     g_main_loop_quit (loop);
64     return TRUE;
65 }
66
67 static void
68 user_changed_cb (LightDMUser *user)
69 {
70     status_notify ("%s USER-CHANGED USERNAME=%s", greeter_id, lightdm_user_get_name (user));
71 }
72
73 static void
74 request_cb (const gchar *request)
75 {
76     const gchar *c, *start;
77     int l;
78     gchar *id, *name = NULL;
79     gboolean id_matches;
80     GHashTable *params;
81
82     if (!request)
83     {
84         g_main_loop_quit (loop);
85         return;
86     }
87
88     c = request;
89     start = c;
90     l = 0;
91     while (*c && !isspace (*c))
92     {
93         c++;
94         l++;
95     }
96     id = g_strdup_printf ("%.*s", l, start);
97     id_matches = strcmp (id, greeter_id) == 0;
98     g_free (id);
99     if (!id_matches)
100         return;
101
102     while (isspace (*c))
103         c++;
104     start = c;
105     l = 0;
106     while (*c && !isspace (*c))
107     {
108         c++;
109         l++;
110     }
111     name = g_strdup_printf ("%.*s", l, start);
112
113     params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
114     while (TRUE)
115     {
116         const gchar *start;
117         gchar *param_name, *param_value;
118
119         while (isspace (*c))
120             c++;
121         start = c;
122         while (*c && !isspace (*c) && *c != '=')
123             c++;
124         if (*c == '\0')
125             break;
126
127         param_name = g_strdup_printf ("%.*s", (int) (c - start), start);
128
129         if (*c == '=')
130         {
131             c++;
132             while (isspace (*c))
133                 c++;
134             if (*c == '\"')
135             {
136                 gboolean escaped = FALSE;
137                 GString *value;
138
139                 c++;
140                 value = g_string_new ("");
141                 while (*c)
142                 {
143                     if (*c == '\\')
144                     {
145                         if (escaped)
146                         {
147                             g_string_append_c (value, '\\');
148                             escaped = FALSE;
149                         }
150                         else
151                             escaped = TRUE;
152                     }
153                     else if (!escaped && *c == '\"')
154                         break;
155                     if (!escaped)
156                         g_string_append_c (value, *c);
157                     c++;
158                 }
159                 param_value = value->str;
160                 g_string_free (value, FALSE);
161                 if (*c == '\"')
162                     c++;
163             }
164             else
165             {
166                 start = c;
167                 while (*c && !isspace (*c))
168                     c++;
169                 param_value = g_strdup_printf ("%.*s", (int) (c - start), start);
170             }
171         }
172         else
173             param_value = g_strdup ("");
174
175         g_hash_table_insert (params, param_name, param_value);
176     }
177   
178     if (strcmp (name, "AUTHENTICATE") == 0)
179         lightdm_greeter_authenticate (greeter, g_hash_table_lookup (params, "USERNAME"));
180
181     if (strcmp (name, "AUTHENTICATE-GUEST") == 0)
182         lightdm_greeter_authenticate_as_guest (greeter);
183
184     if (strcmp (name, "AUTHENTICATE-AUTOLOGIN") == 0)
185         lightdm_greeter_authenticate_autologin (greeter);
186
187     if (strcmp (name, "AUTHENTICATE-REMOTE") == 0)
188         lightdm_greeter_authenticate_remote (greeter, g_hash_table_lookup (params, "SESSION"), NULL);
189
190     if (strcmp (name, "RESPOND") == 0)
191         lightdm_greeter_respond (greeter, g_hash_table_lookup (params, "TEXT"));
192
193     if (strcmp (name, "CANCEL-AUTHENTICATION") == 0)
194         lightdm_greeter_cancel_authentication (greeter);
195
196     if (strcmp (name, "START-SESSION") == 0)
197         if (!lightdm_greeter_start_session_sync (greeter, g_hash_table_lookup (params, "SESSION"), NULL))
198             status_notify ("%s SESSION-FAILED", greeter_id); 
199
200     if (strcmp (name, "LOG-DEFAULT-SESSION") == 0)
201         status_notify ("%s LOG-DEFAULT-SESSION SESSION=%s", greeter_id, lightdm_greeter_get_default_session_hint (greeter));
202
203     if (strcmp (name, "LOG-USER-LIST-LENGTH") == 0)
204         status_notify ("%s LOG-USER-LIST-LENGTH N=%d", greeter_id, lightdm_user_list_get_length (lightdm_user_list_get_instance ()));
205
206     if (strcmp (name, "WRITE-SHARED-DATA") == 0)
207     {
208         gchar *dir;
209
210         dir = lightdm_greeter_ensure_shared_data_dir_sync (greeter, g_hash_table_lookup (params, "USERNAME"));
211         if (dir)
212         {
213             gchar *path;
214             FILE *f;
215
216             g_printerr ("dir='%s'\n", dir);
217
218             path = g_build_filename (dir, "data", NULL);
219             if (!(f = fopen (path, "w")) || fprintf (f, "%s", (const gchar *) g_hash_table_lookup (params, "DATA")) < 0)
220                 status_notify ("%s WRITE-SHARED-DATA ERROR=%s", greeter_id, strerror (errno));
221             else
222                 status_notify ("%s WRITE-SHARED-DATA RESULT=TRUE", greeter_id);
223
224             if (f)
225                 fclose (f);
226             g_free (path);
227             g_free (dir);
228         }
229         else
230             status_notify ("%s WRITE-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id);
231     }
232
233     if (strcmp (name, "READ-SHARED-DATA") == 0)
234     {
235         gchar *dir;
236
237         dir = lightdm_greeter_ensure_shared_data_dir_sync (greeter, g_hash_table_lookup (params, "USERNAME"));
238         if (dir)
239         {
240             gchar *path;
241             gchar *contents = NULL;
242             GError *error = NULL;
243
244             g_printerr ("dir='%s'\n", dir);
245
246             path = g_build_filename (dir, "data", NULL);
247             if (g_file_get_contents (path, &contents, NULL, &error))
248                 status_notify ("%s READ-SHARED-DATA DATA=%s", greeter_id, contents);
249             else
250                 status_notify ("%s READ-SHARED-DATA ERROR=%s", greeter_id, error->message);
251             g_free (path);
252             g_free (contents);
253             g_clear_error (&error);
254         }
255         else
256             status_notify ("%s READ-SHARED-DATA ERROR=NO_SHARED_DIR", greeter_id);
257     }
258
259     if (strcmp (name, "WATCH-USER") == 0)
260     {
261         LightDMUser *user;
262         const gchar *username;
263
264         username = g_hash_table_lookup (params, "USERNAME");
265         user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
266         if (user)
267             g_signal_connect (user, "changed", G_CALLBACK (user_changed_cb), NULL);
268         status_notify ("%s WATCH-USER USERNAME=%s", greeter_id, username);
269     }
270
271     if (strcmp (name, "LOG-USER") == 0)
272     {
273         LightDMUser *user;
274         const gchar *username, *image, *background, *language, *layout, *session;
275         const gchar * const * layouts;
276         gchar **fields = NULL;
277         gchar *layouts_text;
278         GString *status_text;
279         int i;
280
281         username = g_hash_table_lookup (params, "USERNAME");
282         if (g_hash_table_lookup (params, "FIELDS"))
283             fields = g_strsplit (g_hash_table_lookup (params, "FIELDS"), ",", -1);
284         if (!fields)
285         {
286             fields = g_malloc (sizeof (gchar *) * 1);
287             fields[0] = NULL;
288         }
289
290         user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
291         image = lightdm_user_get_image (user);
292         background = lightdm_user_get_background (user);
293         language = lightdm_user_get_language (user);
294         layout = lightdm_user_get_layout (user);
295         layouts = lightdm_user_get_layouts (user);
296         layouts_text = g_strjoinv (";", (gchar **) layouts);
297         session = lightdm_user_get_session (user);
298
299         status_text = g_string_new ("");
300         g_string_append_printf (status_text, "%s LOG-USER USERNAME=%s", greeter_id, username);
301         for (i = 0; fields[i]; i++)
302         {
303             if (strcmp (fields[i], "REAL-NAME") == 0)
304                 g_string_append_printf (status_text, " REAL-NAME=%s", lightdm_user_get_real_name (user));
305             else if (strcmp (fields[i], "DISPLAY-NAME") == 0)
306                 g_string_append_printf (status_text, " DISPLAY-NAME=%s", lightdm_user_get_display_name (user));
307             else if (strcmp (fields[i], "IMAGE") == 0)
308                 g_string_append_printf (status_text, " IMAGE=%s", image ? image : "");
309             else if (strcmp (fields[i], "BACKGROUND") == 0)
310                 g_string_append_printf (status_text, " BACKGROUND=%s", background ? background : "");
311             else if (strcmp (fields[i], "LANGUAGE") == 0)
312                 g_string_append_printf (status_text, " LANGUAGE=%s", language ? language : "");
313             else if (strcmp (fields[i], "LAYOUT") == 0)
314                 g_string_append_printf (status_text, " LAYOUT=%s", layout ? layout : "");
315             else if (strcmp (fields[i], "LAYOUTS") == 0)
316                 g_string_append_printf (status_text, " LAYOUTS=%s", layouts_text);
317             else if (strcmp (fields[i], "SESSION") == 0)
318                 g_string_append_printf (status_text, " SESSION=%s", session ? session : "");
319             else if (strcmp (fields[i], "LOGGED-IN") == 0)
320                 g_string_append_printf (status_text, " LOGGED-IN=%s", lightdm_user_get_logged_in (user) ? "TRUE" : "FALSE");
321             else if (strcmp (fields[i], "HAS-MESSAGES") == 0)
322                 g_string_append_printf (status_text, " HAS-MESSAGES=%s", lightdm_user_get_has_messages (user) ? "TRUE" : "FALSE");
323         }
324         g_strfreev (fields);
325         g_free (layouts_text);
326
327         status_notify (status_text->str);
328         g_string_free (status_text, TRUE);
329     }
330
331     if (strcmp (name, "LOG-USER-LIST") == 0)
332     {
333         GList *users, *link;
334
335         users = lightdm_user_list_get_users (lightdm_user_list_get_instance ());
336         for (link = users; link; link = link->next)
337         {
338             LightDMUser *user = link->data;
339             status_notify ("%s LOG-USER USERNAME=%s", greeter_id, lightdm_user_get_name (user));
340         }
341     }
342
343     if (strcmp (name, "GET-CAN-SUSPEND") == 0)
344     {
345         gboolean can_suspend = lightdm_get_can_suspend ();
346         status_notify ("%s CAN-SUSPEND ALLOWED=%s", greeter_id, can_suspend ? "TRUE" : "FALSE");
347     }
348
349     if (strcmp (name, "SUSPEND") == 0)
350     {
351         GError *error = NULL;
352         if (!lightdm_suspend (&error))
353             status_notify ("%s FAIL-SUSPEND", greeter_id);
354         g_clear_error (&error);
355     }
356
357     if (strcmp (name, "GET-CAN-HIBERNATE") == 0)
358     {
359         gboolean can_hibernate = lightdm_get_can_hibernate ();
360         status_notify ("%s CAN-HIBERNATE ALLOWED=%s", greeter_id, can_hibernate ? "TRUE" : "FALSE");
361     }
362
363     if (strcmp (name, "HIBERNATE") == 0)
364     {
365         GError *error = NULL;
366         if (!lightdm_hibernate (&error))
367             status_notify ("%s FAIL-HIBERNATE", greeter_id);
368         g_clear_error (&error);
369     }
370
371     if (strcmp (name, "GET-CAN-RESTART") == 0)
372     {
373         gboolean can_restart = lightdm_get_can_restart ();
374         status_notify ("%s CAN-RESTART ALLOWED=%s", greeter_id, can_restart ? "TRUE" : "FALSE");
375     }
376
377     if (strcmp (name, "RESTART") == 0)
378     {
379         GError *error = NULL;
380         if (!lightdm_restart (&error))
381             status_notify ("%s FAIL-RESTART", greeter_id);
382         g_clear_error (&error);
383     }
384
385     if (strcmp (name, "GET-CAN-SHUTDOWN") == 0)
386     {
387         gboolean can_shutdown = lightdm_get_can_shutdown ();
388         status_notify ("%s CAN-SHUTDOWN ALLOWED=%s", greeter_id, can_shutdown ? "TRUE" : "FALSE");
389     }
390
391     if (strcmp (name, "SHUTDOWN") == 0)
392     {
393         GError *error = NULL;
394         if (!lightdm_shutdown (&error))
395             status_notify ("%s FAIL-SHUTDOWN", greeter_id);
396         g_clear_error (&error);
397     }
398
399     g_free (name);
400     g_hash_table_unref (params);
401 }
402
403 static void
404 user_added_cb (LightDMUserList *user_list, LightDMUser *user)
405 {
406     status_notify ("%s USER-ADDED USERNAME=%s", greeter_id, lightdm_user_get_name (user));
407 }
408
409 static void
410 user_removed_cb (LightDMUserList *user_list, LightDMUser *user)
411 {
412     status_notify ("%s USER-REMOVED USERNAME=%s", greeter_id, lightdm_user_get_name (user));
413 }
414
415 int
416 main (int argc, char **argv)
417 {
418     gchar *display, *xdg_seat, *xdg_vtnr, *xdg_session_cookie, *xdg_session_class, *mir_socket, *mir_vt, *mir_id;
419     GString *status_text;
420
421 #if !defined(GLIB_VERSION_2_36)
422     g_type_init ();
423 #endif
424
425     display = getenv ("DISPLAY");
426     xdg_seat = getenv ("XDG_SEAT");
427     xdg_vtnr = getenv ("XDG_VTNR");
428     xdg_session_cookie = getenv ("XDG_SESSION_COOKIE");
429     xdg_session_class = getenv ("XDG_SESSION_CLASS");
430     mir_socket = getenv ("MIR_SOCKET");
431     mir_vt = getenv ("MIR_SERVER_VT");
432     mir_id = getenv ("MIR_SERVER_NAME");
433     if (display)
434     {
435         if (display[0] == ':')
436             greeter_id = g_strdup_printf ("GREETER-X-%s", display + 1);
437         else
438             greeter_id = g_strdup_printf ("GREETER-X-%s", display);
439     }
440     else if (mir_id)
441         greeter_id = g_strdup_printf ("GREETER-MIR-%s", mir_id);
442     else if (mir_socket || mir_vt)
443         greeter_id = g_strdup ("GREETER-MIR");
444     else
445         greeter_id = g_strdup ("GREETER-?");
446
447     loop = g_main_loop_new (NULL, FALSE);
448
449     g_unix_signal_add (SIGINT, sigint_cb, NULL);
450     g_unix_signal_add (SIGTERM, sigterm_cb, NULL);
451
452     status_connect (request_cb);
453
454     status_text = g_string_new ("");
455     g_string_printf (status_text, "%s START", greeter_id);
456     if (xdg_seat)
457         g_string_append_printf (status_text, " XDG_SEAT=%s", xdg_seat);
458     if (xdg_vtnr)
459         g_string_append_printf (status_text, " XDG_VTNR=%s", xdg_vtnr);
460     if (xdg_session_cookie)
461         g_string_append_printf (status_text, " XDG_SESSION_COOKIE=%s", xdg_session_cookie);
462     if (xdg_session_class)
463         g_string_append_printf (status_text, " XDG_SESSION_CLASS=%s", xdg_session_class);
464     if (mir_vt > 0)
465         g_string_append_printf (status_text, " MIR_SERVER_VT=%s", mir_vt);
466     status_notify (status_text->str);
467     g_string_free (status_text, TRUE);
468
469     config = g_key_file_new ();
470     g_key_file_load_from_file (config, g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "script", NULL), G_KEY_FILE_NONE, NULL);
471
472     if (g_key_file_has_key (config, "test-greeter-config", "return-value", NULL))
473     {
474         int return_value = g_key_file_get_integer (config, "test-greeter-config", "return-value", NULL);
475         status_notify ("%s EXIT CODE=%d", greeter_id, return_value);
476         return return_value;
477     }
478
479     if (display)
480     {
481         connection = xcb_connect (NULL, NULL);
482         if (xcb_connection_has_error (connection))
483         {
484             status_notify ("%s FAIL-CONNECT-XSERVER", greeter_id);
485             return EXIT_FAILURE;
486         }
487         status_notify ("%s CONNECT-XSERVER", greeter_id);
488     }
489
490     greeter = lightdm_greeter_new ();
491     g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
492     g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);
493     g_signal_connect (greeter, "authentication-complete", G_CALLBACK (authentication_complete_cb), NULL);
494     g_signal_connect (greeter, "autologin-timer-expired", G_CALLBACK (autologin_timer_expired_cb), NULL);
495
496     if (g_key_file_get_boolean (config, "test-greeter-config", "log-user-changes", NULL))
497     {
498         g_signal_connect (lightdm_user_list_get_instance (), "user-added", G_CALLBACK (user_added_cb), NULL);
499         g_signal_connect (lightdm_user_list_get_instance (), "user-removed", G_CALLBACK (user_removed_cb), NULL);
500     }
501
502     status_notify ("%s CONNECT-TO-DAEMON", greeter_id);
503     if (!lightdm_greeter_connect_sync (greeter, NULL))
504     {
505         status_notify ("%s FAIL-CONNECT-DAEMON", greeter_id);
506         return EXIT_FAILURE;
507     }
508
509     status_notify ("%s CONNECTED-TO-DAEMON", greeter_id);
510
511     if (lightdm_greeter_get_select_user_hint (greeter))
512         status_notify ("%s SELECT-USER-HINT USERNAME=%s", greeter_id, lightdm_greeter_get_select_user_hint (greeter));
513     if (lightdm_greeter_get_select_guest_hint (greeter))
514         status_notify ("%s SELECT-GUEST-HINT", greeter_id);
515     if (lightdm_greeter_get_lock_hint (greeter))
516         status_notify ("%s LOCK-HINT", greeter_id);
517     if (!lightdm_greeter_get_has_guest_account_hint (greeter))
518         status_notify ("%s HAS-GUEST-ACCOUNT-HINT=FALSE", greeter_id);
519     if (lightdm_greeter_get_hide_users_hint (greeter))
520         status_notify ("%s HIDE-USERS-HINT", greeter_id);
521     if (lightdm_greeter_get_show_manual_login_hint (greeter))
522         status_notify ("%s SHOW-MANUAL-LOGIN-HINT", greeter_id);
523     if (!lightdm_greeter_get_show_remote_login_hint (greeter))
524         status_notify ("%s SHOW-REMOTE-LOGIN-HINT=FALSE", greeter_id);
525
526     g_main_loop_run (loop);
527
528     return EXIT_SUCCESS;
529 }