2
* A demonstration plugin that acts as a channel filter.
4
* Copyright (C) 2008-2009 Nokia Corporation
5
* Copyright (C) 2009 Collabora Ltd.
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.
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.
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
22
#include <mission-control-plugins/mission-control-plugins.h>
24
#include <dbus/dbus.h>
25
#include <dbus/dbus-glib-lowlevel.h>
27
#include <telepathy-glib/dbus.h>
28
#include <telepathy-glib/interfaces.h>
29
#include <telepathy-glib/util.h>
33
/* ------ TestPermissionPlugin -------------------------------------- */
37
} TestPermissionPlugin;
40
GObjectClass parent_class;
41
} TestPermissionPluginClass;
43
GType test_permission_plugin_get_type (void) G_GNUC_CONST;
44
static void cdo_policy_iface_init (McpDispatchOperationPolicyIface *,
47
G_DEFINE_TYPE_WITH_CODE (TestPermissionPlugin, test_permission_plugin,
49
G_IMPLEMENT_INTERFACE (MCP_TYPE_DISPATCH_OPERATION_POLICY,
50
cdo_policy_iface_init))
53
test_permission_plugin_init (TestPermissionPlugin *self)
58
test_permission_plugin_class_init (TestPermissionPluginClass *cls)
63
McpDispatchOperation *dispatch_operation;
64
McpDispatchOperationDelay *delay;
68
permission_context_free (gpointer p)
70
PermissionContext *ctx = p;
72
mcp_dispatch_operation_end_delay (ctx->dispatch_operation, ctx->delay);
73
g_object_unref (ctx->dispatch_operation);
74
g_slice_free (PermissionContext, ctx);
78
permission_cb (DBusPendingCall *pc,
81
PermissionContext *ctx = data;
82
DBusMessage *message = dbus_pending_call_steal_reply (pc);
84
if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
86
DEBUG ("Permission denied");
87
mcp_dispatch_operation_leave_channels (ctx->dispatch_operation,
88
TRUE, TP_CHANNEL_GROUP_CHANGE_REASON_PERMISSION_DENIED,
93
DEBUG ("Permission granted");
96
dbus_message_unref (message);
97
dbus_pending_call_unref (pc);
101
test_permission_plugin_check_cdo (McpDispatchOperationPolicy *policy,
102
McpDispatchOperation *dispatch_operation)
104
GHashTable *properties = mcp_dispatch_operation_ref_nth_channel_properties (
105
dispatch_operation, 0);
106
PermissionContext *ctx = NULL;
110
if (properties == NULL)
112
DEBUG ("no channels!?");
116
/* currently this example just checks the first channel */
118
if (!tp_strdiff (tp_asv_get_string (properties,
119
TP_IFACE_CHANNEL ".TargetID"),
120
"policy@example.net"))
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;
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);
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");
137
if (!dbus_connection_send_with_reply (libdbus, message,
140
g_error ("out of memory");
143
dbus_message_unref (message);
147
DEBUG ("got disconnected from D-Bus...");
152
/* pc is unreffed by permission_cb */
154
DEBUG ("Waiting for permission");
156
if (dbus_pending_call_get_completed (pc))
158
permission_cb (pc, ctx);
162
if (!dbus_pending_call_set_notify (pc, permission_cb, ctx,
163
permission_context_free))
165
g_error ("Out of memory");
168
/* ctx will be freed later */
174
permission_context_free (ctx);
176
g_hash_table_unref (properties);
180
cdo_policy_iface_init (McpDispatchOperationPolicyIface *iface,
181
gpointer unused G_GNUC_UNUSED)
183
mcp_dispatch_operation_policy_iface_implement_check (iface,
184
test_permission_plugin_check_cdo);
187
/* ------ TestRejectionPlugin --------------------------------------- */
191
} TestRejectionPlugin;
194
GObjectClass parent_class;
195
} TestRejectionPluginClass;
197
GType test_rejection_plugin_get_type (void) G_GNUC_CONST;
198
static void rej_cdo_policy_iface_init (McpDispatchOperationPolicyIface *,
200
static void rej_req_policy_iface_init (McpRequestPolicyIface *,
203
G_DEFINE_TYPE_WITH_CODE (TestRejectionPlugin, test_rejection_plugin,
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))
211
test_rejection_plugin_init (TestRejectionPlugin *self)
216
test_rejection_plugin_class_init (TestRejectionPluginClass *cls)
221
test_rejection_plugin_check_cdo (McpDispatchOperationPolicy *policy,
222
McpDispatchOperation *dispatch_operation)
224
GHashTable *properties = mcp_dispatch_operation_ref_nth_channel_properties (
225
dispatch_operation, 0);
226
const gchar *target_id;
230
if (properties == NULL)
232
DEBUG ("no channels!?");
236
/* currently this example just checks the first channel */
238
target_id = tp_asv_get_string (properties, TP_IFACE_CHANNEL ".TargetID");
240
if (!tp_strdiff (target_id, "rick.astley@example.net"))
242
DEBUG ("rickrolling detected, destroying channels immediately!");
243
mcp_dispatch_operation_destroy_channels (dispatch_operation, FALSE);
245
else if (!tp_strdiff (target_id, "mc.hammer@example.net"))
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,
253
g_hash_table_unref (properties);
257
rej_cdo_policy_iface_init (McpDispatchOperationPolicyIface *iface,
258
gpointer unused G_GNUC_UNUSED)
260
mcp_dispatch_operation_policy_iface_implement_check (iface,
261
test_rejection_plugin_check_cdo);
265
test_rejection_plugin_check_request (McpRequestPolicy *policy,
268
GHashTable *properties = mcp_request_ref_nth_request (request, 0);
270
DEBUG ("%s", G_STRFUNC);
273
tp_asv_get_string (properties, TP_IFACE_CHANNEL ".ChannelType"),
274
"com.example.ForbiddenChannel"))
276
DEBUG ("Forbidden channel detected, denying request");
277
mcp_request_deny (request, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
281
if (mcp_request_find_request_by_type (request,
282
0, g_quark_from_static_string ("com.example.ForbiddenChannel"),
285
DEBUG ("Forbidden channel detected, denying request");
286
mcp_request_deny (request, TP_ERRORS, TP_ERROR_PERMISSION_DENIED,
290
g_hash_table_unref (properties);
294
rej_req_policy_iface_init (McpRequestPolicyIface *iface,
295
gpointer unused G_GNUC_UNUSED)
297
mcp_request_policy_iface_implement_check (iface,
298
test_rejection_plugin_check_request);
301
/* ------ Initialization -------------------------------------------- */
304
mcp_plugin_ref_nth_object (guint n)
306
DEBUG ("Initializing mcp-plugin (n=%u)", n);
311
return g_object_new (test_permission_plugin_get_type (),
315
return g_object_new (test_rejection_plugin_get_type (),