First tlm release
[platform/core/system/tlm.git] / src / daemon / dbus / tlm-dbus-login-adapter.c
1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of tlm
5  *
6  * Copyright (C) 2014 Intel Corporation.
7  *
8  * Contact: Imran Zaman <imran.zaman@intel.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23  * 02110-1301 USA
24  */
25
26 #include "config.h"
27 #include "common/tlm-log.h"
28 #include "common/tlm-error.h"
29 #include "common/dbus/tlm-dbus.h"
30
31 #include "tlm-dbus-login-adapter.h"
32 #include "tlm-dbus-utils.h"
33
34 enum
35 {
36     PROP_0,
37
38     PROP_CONNECTION,
39
40     N_PROPERTIES
41 };
42
43 static GParamSpec *properties[N_PROPERTIES];
44
45 struct _TlmDbusLoginAdapterPrivate
46 {
47     GDBusConnection *connection;
48     TlmDbusLogin *dbus_obj;
49 };
50
51 G_DEFINE_TYPE (TlmDbusLoginAdapter, tlm_dbus_login_adapter, G_TYPE_OBJECT)
52
53 #define TLM_DBUS_LOGIN_ADAPTER_GET_PRIV(obj) \
54     G_TYPE_INSTANCE_GET_PRIVATE ((obj), TLM_TYPE_LOGIN_ADAPTER, \
55             TlmDbusLoginAdapterPrivate)
56
57 enum {
58     SIG_LOGIN_USER,
59     SIG_LOGOUT_USER,
60     SIG_SWITCH_USER,
61
62     SIG_MAX
63 };
64
65 static guint signals[SIG_MAX];
66
67 static gboolean
68 _handle_login_user (
69         TlmDbusLoginAdapter *self,
70         GDBusMethodInvocation *invocation,
71         const gchar *seat_id,
72         const gchar *username,
73         const gchar *password,
74         const GVariant *environ,
75         gpointer user_data);
76
77 static gboolean
78 _handle_switch_user (
79         TlmDbusLoginAdapter *self,
80         GDBusMethodInvocation *invocation,
81         const gchar *seat_id,
82         const gchar *username,
83         const gchar *password,
84         const GVariant *environ,
85         gpointer user_data);
86
87 static gboolean
88 _handle_logout_user (
89         TlmDbusLoginAdapter *self,
90         GDBusMethodInvocation *invocation,
91         const gchar *seat_id,
92         gpointer user_data);
93
94 static void
95 _set_property (
96         GObject *object,
97         guint property_id,
98         const GValue *value,
99         GParamSpec *pspec)
100 {
101     TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
102
103     switch (property_id) {
104         case PROP_CONNECTION:
105             self->priv->connection = g_value_get_object(value);
106             break;
107         default:
108             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
109     }
110 }
111
112 static void
113 _get_property (
114         GObject *object,
115         guint property_id,
116         GValue *value,
117         GParamSpec *pspec)
118 {
119     TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
120
121     switch (property_id) {
122         case PROP_CONNECTION:
123             g_value_set_object (value, self->priv->connection);
124             break;
125         default:
126             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
127     }
128 }
129
130 static void
131 _dispose (
132         GObject *object)
133 {
134     TlmDbusLoginAdapter *self = TLM_DBUS_LOGIN_ADAPTER (object);
135
136     DBG("- unregistering dbus login adaptor.");
137
138     if (self->priv->dbus_obj) {
139         g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (
140                 self->priv->dbus_obj));
141         g_object_unref (self->priv->dbus_obj);
142         self->priv->dbus_obj = NULL;
143     }
144
145     G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->dispose (
146             object);
147 }
148
149 static void
150 _finalize (
151         GObject *object)
152 {
153
154     G_OBJECT_CLASS (tlm_dbus_login_adapter_parent_class)->finalize (
155             object);
156 }
157
158 static void
159 tlm_dbus_login_adapter_class_init (
160         TlmDbusLoginAdapterClass *klass)
161 {
162     GObjectClass* object_class = G_OBJECT_CLASS (klass);
163
164     g_type_class_add_private (object_class,
165             sizeof (TlmDbusLoginAdapterPrivate));
166
167     object_class->get_property = _get_property;
168     object_class->set_property = _set_property;
169     object_class->dispose = _dispose;
170     object_class->finalize = _finalize;
171
172     properties[PROP_CONNECTION] = g_param_spec_object (
173             "connection",
174             "Bus connection",
175             "DBus connection used",
176             G_TYPE_DBUS_CONNECTION,
177             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
178
179     g_object_class_install_properties (object_class, N_PROPERTIES, properties);
180
181     signals[SIG_LOGIN_USER] = g_signal_new ("login-user",
182             TLM_TYPE_LOGIN_ADAPTER,
183             G_SIGNAL_RUN_LAST,
184             0,
185             NULL,
186             NULL,
187             NULL,
188             G_TYPE_NONE,
189             5,
190             G_TYPE_STRING,
191             G_TYPE_STRING,
192             G_TYPE_STRING,
193             G_TYPE_VARIANT,
194             G_TYPE_DBUS_METHOD_INVOCATION);
195
196     signals[SIG_LOGOUT_USER] = g_signal_new ("logout-user",
197             TLM_TYPE_LOGIN_ADAPTER,
198             G_SIGNAL_RUN_LAST,
199             0,
200             NULL,
201             NULL,
202             NULL,
203             G_TYPE_NONE,
204             2,
205             G_TYPE_STRING,
206             G_TYPE_DBUS_METHOD_INVOCATION);
207
208     signals[SIG_SWITCH_USER] = g_signal_new ("switch-user",
209             TLM_TYPE_LOGIN_ADAPTER,
210             G_SIGNAL_RUN_LAST,
211             0,
212             NULL,
213             NULL,
214             NULL,
215             G_TYPE_NONE,
216             5,
217             G_TYPE_STRING,
218             G_TYPE_STRING,
219             G_TYPE_STRING,
220             G_TYPE_VARIANT,
221             G_TYPE_DBUS_METHOD_INVOCATION);
222 }
223
224 static void
225 tlm_dbus_login_adapter_init (TlmDbusLoginAdapter *self)
226 {
227     self->priv = TLM_DBUS_LOGIN_ADAPTER_GET_PRIV(self);
228
229     self->priv->connection = 0;
230     self->priv->dbus_obj = tlm_dbus_login_skeleton_new ();
231 }
232
233 static gboolean
234 _handle_login_user (
235         TlmDbusLoginAdapter *self,
236         GDBusMethodInvocation *invocation,
237         const gchar *seat_id,
238         const gchar *username,
239         const gchar *password,
240         const GVariant *environment,
241         gpointer emitter)
242 {
243     GError *error = NULL;
244
245     DBG ("");
246     g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self), FALSE);
247
248     if (!seat_id || !username || !password) {
249         error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
250                 "Invalid input");
251         g_dbus_method_invocation_return_gerror (invocation, error);
252         g_error_free (error);
253         return TRUE;
254     }
255
256     g_signal_emit (self, signals[SIG_LOGIN_USER], 0, seat_id, username,
257             password, environment, invocation);
258
259     return TRUE;
260 }
261
262 static gboolean
263 _handle_logout_user (
264         TlmDbusLoginAdapter *self,
265         GDBusMethodInvocation *invocation,
266         const gchar *seat_id,
267         gpointer emitter)
268 {
269     GError *error = NULL;
270
271     DBG ("");
272     g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
273             FALSE);
274
275     if (!seat_id) {
276         error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
277                 "Invalid input");
278         g_dbus_method_invocation_return_gerror (invocation, error);
279         g_error_free (error);
280         return TRUE;
281     }
282
283     g_signal_emit (self, signals[SIG_LOGOUT_USER], 0, seat_id, invocation);
284
285     return TRUE;
286 }
287
288 static gboolean
289 _handle_switch_user (
290         TlmDbusLoginAdapter *self,
291         GDBusMethodInvocation *invocation,
292         const gchar *seat_id,
293         const gchar *username,
294         const gchar *password,
295         const GVariant *environment,
296         gpointer emitter)
297 {
298     GError *error = NULL;
299
300     DBG ("");
301     g_return_val_if_fail (self && TLM_IS_DBUS_LOGIN_ADAPTER(self),
302             FALSE);
303
304     if (!seat_id || !username || !password) {
305         error = TLM_GET_ERROR_FOR_ID (TLM_ERROR_INVALID_INPUT,
306                 "Invalid input");
307         g_dbus_method_invocation_return_gerror (invocation, error);
308         g_error_free (error);
309         return TRUE;
310     }
311
312     g_signal_emit (self, signals[SIG_SWITCH_USER], 0, seat_id, username,
313             password, environment, invocation);
314
315     return TRUE;
316 }
317
318 TlmDbusLoginAdapter *
319 tlm_dbus_login_adapter_new_with_connection (
320         GDBusConnection *bus_connection)
321 {
322     GError *err = NULL;
323     TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (g_object_new (
324             TLM_TYPE_LOGIN_ADAPTER, "connection", bus_connection, NULL));
325
326     if (!g_dbus_interface_skeleton_export (
327             G_DBUS_INTERFACE_SKELETON(adapter->priv->dbus_obj),
328             adapter->priv->connection, TLM_LOGIN_OBJECTPATH, &err)) {
329         WARN ("failed to register object: %s", err->message);
330         g_error_free (err);
331         g_object_unref (adapter);
332         return NULL;
333     }
334
335     DBG("(+) started login interface '%p' at path '%s' on connection"
336             " '%p'", adapter, TLM_LOGIN_OBJECTPATH, bus_connection);
337
338     g_signal_connect_swapped (adapter->priv->dbus_obj,
339         "handle-login-user", G_CALLBACK (_handle_login_user), adapter);
340     g_signal_connect_swapped (adapter->priv->dbus_obj,
341         "handle-logout-user", G_CALLBACK(_handle_logout_user), adapter);
342     g_signal_connect_swapped (adapter->priv->dbus_obj,
343         "handle-switch-user", G_CALLBACK(_handle_switch_user), adapter);
344
345     return adapter;
346 }
347
348 void
349 tlm_dbus_login_adapter_request_completed (
350         TlmDbusRequest *request,
351         GError *error)
352 {
353     g_return_if_fail (request && request->dbus_adapter &&
354             TLM_IS_DBUS_LOGIN_ADAPTER(request->dbus_adapter));
355
356     TlmDbusLoginAdapter *adapter = TLM_DBUS_LOGIN_ADAPTER (
357             request->dbus_adapter);
358     if (error) {
359         g_dbus_method_invocation_return_gerror (request->invocation, error);
360         return;
361     }
362
363     switch (request->type) {
364     case TLM_DBUS_REQUEST_TYPE_LOGIN_USER:
365         tlm_dbus_login_complete_login_user (adapter->priv->dbus_obj,
366                 request->invocation);
367         break;
368     case TLM_DBUS_REQUEST_TYPE_LOGOUT_USER:
369         tlm_dbus_login_complete_logout_user (adapter->priv->dbus_obj,
370                 request->invocation);
371         break;
372     case TLM_DBUS_REQUEST_TYPE_SWITCH_USER:
373         tlm_dbus_login_complete_switch_user (adapter->priv->dbus_obj,
374                 request->invocation);
375         break;
376     }
377 }