~ubuntu-branches/ubuntu/precise/telepathy-mission-control-5/precise

« back to all changes in this revision

Viewing changes to test/twisted/mcp-plugin.c

Tags: upstream-5.5.0
ImportĀ upstreamĀ versionĀ 5.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * A demonstration plugin that acts as a channel filter.
 
3
 *
 
4
 * Copyright (C) 2008-2009 Nokia Corporation
 
5
 * Copyright (C) 2009 Collabora Ltd.
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
20
 */
 
21
 
 
22
#include <mission-control-plugins/mission-control-plugins.h>
 
23
 
 
24
#include <dbus/dbus.h>
 
25
#include <dbus/dbus-glib-lowlevel.h>
 
26
 
 
27
#include <telepathy-glib/dbus.h>
 
28
#include <telepathy-glib/interfaces.h>
 
29
#include <telepathy-glib/util.h>
 
30
 
 
31
#define DEBUG g_debug
 
32
 
 
33
/* ------ TestPermissionPlugin -------------------------------------- */
 
34
 
 
35
typedef struct {
 
36
    GObject parent;
 
37
} TestPermissionPlugin;
 
38
 
 
39
typedef struct {
 
40
    GObjectClass parent_class;
 
41
} TestPermissionPluginClass;
 
42
 
 
43
GType test_permission_plugin_get_type (void) G_GNUC_CONST;
 
44
static void cdo_policy_iface_init (McpDispatchOperationPolicyIface *,
 
45
    gpointer);
 
46
 
 
47
G_DEFINE_TYPE_WITH_CODE (TestPermissionPlugin, test_permission_plugin,
 
48
    G_TYPE_OBJECT,
 
49
    G_IMPLEMENT_INTERFACE (MCP_TYPE_DISPATCH_OPERATION_POLICY,
 
50
      cdo_policy_iface_init))
 
51
 
 
52
static void
 
53
test_permission_plugin_init (TestPermissionPlugin *self)
 
54
{
 
55
}
 
56
 
 
57
static void
 
58
test_permission_plugin_class_init (TestPermissionPluginClass *cls)
 
59
{
 
60
}
 
61
 
 
62
typedef struct {
 
63
    McpDispatchOperation *dispatch_operation;
 
64
    McpDispatchOperationDelay *delay;
 
65
} PermissionContext;
 
66
 
 
67
static void
 
68
permission_context_free (gpointer p)
 
69
{
 
70
  PermissionContext *ctx = p;
 
71
 
 
72
  mcp_dispatch_operation_end_delay (ctx->dispatch_operation, ctx->delay);
 
73
  g_object_unref (ctx->dispatch_operation);
 
74
  g_slice_free (PermissionContext, ctx);
 
75
}
 
76
 
 
77
static void
 
78
permission_cb (DBusPendingCall *pc,
 
79
    gpointer data)
 
80
{
 
81
  PermissionContext *ctx = data;
 
82
  DBusMessage *message = dbus_pending_call_steal_reply (pc);
 
83
 
 
84
  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
 
85
    {
 
86
      DEBUG ("Permission denied");
 
87
      mcp_dispatch_operation_leave_channels (ctx->dispatch_operation,
 
88
          TRUE, TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED,
 
89
          "Computer says no");
 
90
    }
 
91
  else
 
92
    {
 
93
      DEBUG ("Permission granted");
 
94
    }
 
95
 
 
96
  dbus_message_unref (message);
 
97
  dbus_pending_call_unref (pc);
 
98
}
 
99
 
 
100
static void
 
101
test_permission_plugin_check_cdo (McpDispatchOperationPolicy *policy,
 
102
    McpDispatchOperation *dispatch_operation)
 
103
{
 
104
  GHashTable *properties = mcp_dispatch_operation_ref_nth_channel_properties (
 
105
      dispatch_operation, 0);
 
106
  PermissionContext *ctx = NULL;
 
107
 
 
108
  DEBUG ("enter");
 
109
 
 
110
  if (properties == NULL)
 
111
    {
 
112
      DEBUG ("no channels!?");
 
113
      return;
 
114
    }
 
115
 
 
116
  /* currently this example just checks the first channel */
 
117
 
 
118
  if (!tp_strdiff (tp_asv_get_string (properties,
 
119
          TP_IFACE_CHANNEL ".TargetID"),
 
120
        "policy@example.net"))
 
121
    {
 
122
      TpDBusDaemon *dbus_daemon = tp_dbus_daemon_dup (NULL);
 
123
      DBusGConnection *gconn = tp_proxy_get_dbus_connection (dbus_daemon);
 
124
      DBusConnection *libdbus = dbus_g_connection_get_connection (gconn);
 
125
      DBusPendingCall *pc = NULL;
 
126
      DBusMessage *message;
 
127
 
 
128
      ctx = g_slice_new0 (PermissionContext);
 
129
      ctx->dispatch_operation = g_object_ref (dispatch_operation);
 
130
      ctx->delay = mcp_dispatch_operation_start_delay (dispatch_operation);
 
131
 
 
132
      /* in a real policy-mechanism you'd give some details, like the
 
133
       * channel's properties or object path */
 
134
      message = dbus_message_new_method_call ("com.example.Policy",
 
135
          "/com/example/Policy", "com.example.Policy", "RequestPermission");
 
136
 
 
137
      if (!dbus_connection_send_with_reply (libdbus, message,
 
138
            &pc, -1))
 
139
        {
 
140
          g_error ("out of memory");
 
141
        }
 
142
 
 
143
      dbus_message_unref (message);
 
144
 
 
145
      if (pc == NULL)
 
146
        {
 
147
          DEBUG ("got disconnected from D-Bus...");
 
148
 
 
149
          goto finally;
 
150
        }
 
151
 
 
152
      /* pc is unreffed by permission_cb */
 
153
 
 
154
      DEBUG ("Waiting for permission");
 
155
 
 
156
      if (dbus_pending_call_get_completed (pc))
 
157
        {
 
158
          permission_cb (pc, ctx);
 
159
          goto finally;
 
160
        }
 
161
 
 
162
      if (!dbus_pending_call_set_notify (pc, permission_cb, ctx,
 
163
            permission_context_free))
 
164
        {
 
165
          g_error ("Out of memory");
 
166
        }
 
167
 
 
168
      /* ctx will be freed later */
 
169
      ctx = NULL;
 
170
  }
 
171
 
 
172
finally:
 
173
  if (ctx != NULL)
 
174
    permission_context_free (ctx);
 
175
 
 
176
  g_hash_table_unref (properties);
 
177
}
 
178
 
 
179
static void
 
180
cdo_policy_iface_init (McpDispatchOperationPolicyIface *iface,
 
181
    gpointer unused G_GNUC_UNUSED)
 
182
{
 
183
  mcp_dispatch_operation_policy_iface_implement_check (iface,
 
184
      test_permission_plugin_check_cdo);
 
185
}
 
186
 
 
187
/* ------ TestRejectionPlugin --------------------------------------- */
 
188
 
 
189
typedef struct {
 
190
    GObject parent;
 
191
} TestRejectionPlugin;
 
192
 
 
193
typedef struct {
 
194
    GObjectClass parent_class;
 
195
} TestRejectionPluginClass;
 
196
 
 
197
GType test_rejection_plugin_get_type (void) G_GNUC_CONST;
 
198
static void rej_cdo_policy_iface_init (McpDispatchOperationPolicyIface *,
 
199
    gpointer);
 
200
static void rej_req_policy_iface_init (McpRequestPolicyIface *,
 
201
    gpointer);
 
202
 
 
203
G_DEFINE_TYPE_WITH_CODE (TestRejectionPlugin, test_rejection_plugin,
 
204
    G_TYPE_OBJECT,
 
205
    G_IMPLEMENT_INTERFACE (MCP_TYPE_REQUEST_POLICY,
 
206
      rej_req_policy_iface_init);
 
207
    G_IMPLEMENT_INTERFACE (MCP_TYPE_DISPATCH_OPERATION_POLICY,
 
208
      rej_cdo_policy_iface_init))
 
209
 
 
210
static void
 
211
test_rejection_plugin_init (TestRejectionPlugin *self)
 
212
{
 
213
}
 
214
 
 
215
static void
 
216
test_rejection_plugin_class_init (TestRejectionPluginClass *cls)
 
217
{
 
218
}
 
219
 
 
220
static void
 
221
test_rejection_plugin_check_cdo (McpDispatchOperationPolicy *policy,
 
222
    McpDispatchOperation *dispatch_operation)
 
223
{
 
224
  GHashTable *properties = mcp_dispatch_operation_ref_nth_channel_properties (
 
225
      dispatch_operation, 0);
 
226
  const gchar *target_id;
 
227
 
 
228
  DEBUG ("enter");
 
229
 
 
230
  if (properties == NULL)
 
231
    {
 
232
      DEBUG ("no channels!?");
 
233
      return;
 
234
    }
 
235
 
 
236
  /* currently this example just checks the first channel */
 
237
 
 
238
  target_id = tp_asv_get_string (properties, TP_IFACE_CHANNEL ".TargetID");
 
239
 
 
240
  if (!tp_strdiff (target_id, "rick.astley@example.net"))
 
241
    {
 
242
      DEBUG ("rickrolling detected, destroying channels immediately!");
 
243
      mcp_dispatch_operation_destroy_channels (dispatch_operation, FALSE);
 
244
    }
 
245
  else if (!tp_strdiff (target_id, "mc.hammer@example.net"))
 
246
    {
 
247
      DEBUG ("MC Hammer detected, leaving channels when observers have run");
 
248
      mcp_dispatch_operation_leave_channels (dispatch_operation, TRUE,
 
249
          TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED,
 
250
          "Can't touch this");
 
251
    }
 
252
 
 
253
  g_hash_table_unref (properties);
 
254
}
 
255
 
 
256
static void
 
257
rej_cdo_policy_iface_init (McpDispatchOperationPolicyIface *iface,
 
258
    gpointer unused G_GNUC_UNUSED)
 
259
{
 
260
  mcp_dispatch_operation_policy_iface_implement_check (iface,
 
261
      test_rejection_plugin_check_cdo);
 
262
}
 
263
 
 
264
static void
 
265
test_rejection_plugin_check_request (McpRequestPolicy *policy,
 
266
    McpRequest *request)
 
267
{
 
268
  GHashTable *properties = mcp_request_ref_nth_request (request, 0);
 
269
 
 
270
  DEBUG ("%s", G_STRFUNC);
 
271
 
 
272
  if (!tp_strdiff (
 
273
        tp_asv_get_string (properties, TP_IFACE_CHANNEL ".ChannelType"),
 
274
        "com.example.ForbiddenChannel"))
 
275
    {
 
276
      DEBUG ("Forbidden channel detected, denying request");
 
277
      mcp_request_deny (request, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
 
278
          "No, you don't");
 
279
    }
 
280
 
 
281
  if (mcp_request_find_request_by_type (request,
 
282
        0, g_quark_from_static_string ("com.example.ForbiddenChannel"),
 
283
        NULL, NULL))
 
284
    {
 
285
      DEBUG ("Forbidden channel detected, denying request");
 
286
      mcp_request_deny (request, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
 
287
          "No, you don't");
 
288
    }
 
289
 
 
290
  g_hash_table_unref (properties);
 
291
}
 
292
 
 
293
static void
 
294
rej_req_policy_iface_init (McpRequestPolicyIface *iface,
 
295
    gpointer unused G_GNUC_UNUSED)
 
296
{
 
297
  mcp_request_policy_iface_implement_check (iface,
 
298
      test_rejection_plugin_check_request);
 
299
}
 
300
 
 
301
/* ------ Initialization -------------------------------------------- */
 
302
 
 
303
GObject *
 
304
mcp_plugin_ref_nth_object (guint n)
 
305
{
 
306
  DEBUG ("Initializing mcp-plugin (n=%u)", n);
 
307
 
 
308
  switch (n)
 
309
    {
 
310
    case 0:
 
311
      return g_object_new (test_permission_plugin_get_type (),
 
312
          NULL);
 
313
 
 
314
    case 1:
 
315
      return g_object_new (test_rejection_plugin_get_type (),
 
316
          NULL);
 
317
 
 
318
    default:
 
319
      return NULL;
 
320
    }
 
321
}