422fb12ce55214aef9a6c88eed58c3a99dab9b8a
[platform/upstream/glib.git] / gio / gpermission.c
1 /*
2  * Copyright © 2010 Codethink Limited
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the licence, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Author: Ryan Lortie <desrt@desrt.ca>
20  */
21
22 #include "config.h"
23
24 #include "gpermission.h"
25 #include "glibintl.h"
26
27
28 /**
29  * SECTION:gpermission
30  * @title: GPermission
31  * @short_description: An object representing the permission to perform
32  *                     a certain action
33  *
34  * A #GPermission represents the status of the caller's permission to
35  * perform a certain action.
36  *
37  * You can query if the action is currently allowed and if it is
38  * possible to acquire the permission so that the action will be allowed
39  * in the future.
40  *
41  * There is also an API to actually acquire the permission and one to
42  * release it.
43  *
44  * As an example, a #GPermission might represent the ability for the
45  * user to write to a #GSettings object.  This #GPermission object could
46  * then be used to decide if it is appropriate to show a "Click here to
47  * unlock" button in a dialog and to provide the mechanism to invoke
48  * when that button is clicked.
49  **/
50
51 /**
52  * GPermission:
53  *
54  * #GPermission is an opaque data structure and can only be accessed
55  * using the following functions.
56  **/
57
58 G_DEFINE_ABSTRACT_TYPE (GPermission, g_permission, G_TYPE_OBJECT)
59
60 struct _GPermissionPrivate
61 {
62   gboolean allowed;
63   gboolean can_acquire;
64   gboolean can_release;
65 };
66
67 enum  {
68   PROP_NONE,
69   PROP_ALLOWED,
70   PROP_CAN_ACQUIRE,
71   PROP_CAN_RELEASE
72 };
73
74 /**
75  * g_permission_acquire:
76  * @permission: a #GPermission instance
77  * @cancellable: (allow-none): a #GCancellable, or %NULL
78  * @error: a pointer to a %NULL #GError, or %NULL
79  *
80  * Attempts to acquire the permission represented by @permission.
81  *
82  * The precise method by which this happens depends on the permission
83  * and the underlying authentication mechanism.  A simple example is
84  * that a dialog may appear asking the user to enter their password.
85  *
86  * You should check with g_permission_get_can_acquire() before calling
87  * this function.
88  *
89  * If the permission is acquired then %TRUE is returned.  Otherwise,
90  * %FALSE is returned and @error is set appropriately.
91  *
92  * This call is blocking, likely for a very long time (in the case that
93  * user interaction is required).  See g_permission_acquire_async() for
94  * the non-blocking version.
95  *
96  * Returns: %TRUE if the permission was successfully acquired
97  *
98  * Since: 2.26
99  */
100 gboolean
101 g_permission_acquire (GPermission   *permission,
102                       GCancellable  *cancellable,
103                       GError       **error)
104 {
105   return G_PERMISSION_GET_CLASS (permission)
106     ->acquire (permission, cancellable, error);
107 }
108
109 /**
110  * g_permission_acquire_async:
111  * @permission: a #GPermission instance
112  * @cancellable: (allow-none): a #GCancellable, or %NULL
113  * @callback: the #GAsyncReadyCallback to call when done
114  * @user_data: the user data to pass to @callback
115  *
116  * Attempts to acquire the permission represented by @permission.
117  *
118  * This is the first half of the asynchronous version of
119  * g_permission_acquire().
120  *
121  * Since: 2.26
122  **/
123 void
124 g_permission_acquire_async (GPermission         *permission,
125                             GCancellable        *cancellable,
126                             GAsyncReadyCallback  callback,
127                             gpointer             user_data)
128 {
129   G_PERMISSION_GET_CLASS (permission)
130     ->acquire_async (permission, cancellable, callback, user_data);
131 }
132
133 /**
134  * g_permission_acquire_finish:
135  * @permission: a #GPermission instance
136  * @result: the #GAsyncResult given to the #GAsyncReadyCallback
137  * @error: a pointer to a %NULL #GError, or %NULL
138  *
139  * Collects the result of attempting to acquire the permission
140  * represented by @permission.
141  *
142  * This is the second half of the asynchronous version of
143  * g_permission_acquire().
144  *
145  * Returns: %TRUE if the permission was successfully acquired
146  *
147  * Since: 2.26
148  **/
149 gboolean
150 g_permission_acquire_finish (GPermission   *permission,
151                              GAsyncResult  *result,
152                              GError       **error)
153 {
154   return G_PERMISSION_GET_CLASS (permission)
155     ->acquire_finish (permission, result, error);
156 }
157
158 /**
159  * g_permission_release:
160  * @permission: a #GPermission instance
161  * @cancellable: (allow-none): a #GCancellable, or %NULL
162  * @error: a pointer to a %NULL #GError, or %NULL
163  *
164  * Attempts to release the permission represented by @permission.
165  *
166  * The precise method by which this happens depends on the permission
167  * and the underlying authentication mechanism.  In most cases the
168  * permission will be dropped immediately without further action.
169  *
170  * You should check with g_permission_get_can_release() before calling
171  * this function.
172  *
173  * If the permission is released then %TRUE is returned.  Otherwise,
174  * %FALSE is returned and @error is set appropriately.
175  *
176  * This call is blocking, likely for a very long time (in the case that
177  * user interaction is required).  See g_permission_release_async() for
178  * the non-blocking version.
179  *
180  * Returns: %TRUE if the permission was successfully released
181  *
182  * Since: 2.26
183  **/
184 gboolean
185 g_permission_release (GPermission   *permission,
186                       GCancellable  *cancellable,
187                       GError       **error)
188 {
189   return G_PERMISSION_GET_CLASS (permission)
190     ->release (permission, cancellable, error);
191 }
192
193 /**
194  * g_permission_release_async:
195  * @permission: a #GPermission instance
196  * @cancellable: (allow-none): a #GCancellable, or %NULL
197  * @callback: the #GAsyncReadyCallback to call when done
198  * @user_data: the user data to pass to @callback
199  *
200  * Attempts to release the permission represented by @permission.
201  *
202  * This is the first half of the asynchronous version of
203  * g_permission_release().
204  *
205  * Since: 2.26
206  **/
207 void
208 g_permission_release_async (GPermission         *permission,
209                             GCancellable        *cancellable,
210                             GAsyncReadyCallback  callback,
211                             gpointer             user_data)
212 {
213   G_PERMISSION_GET_CLASS (permission)
214     ->release_async (permission, cancellable, callback, user_data);
215 }
216
217 /**
218  * g_permission_release_finish:
219  * @permission: a #GPermission instance
220  * @result: the #GAsyncResult given to the #GAsyncReadyCallback
221  * @error: a pointer to a %NULL #GError, or %NULL
222  *
223  * Collects the result of attempting to release the permission
224  * represented by @permission.
225  *
226  * This is the second half of the asynchronous version of
227  * g_permission_release().
228  *
229  * Returns: %TRUE if the permission was successfully released
230  *
231  * Since: 2.26
232  **/
233 gboolean
234 g_permission_release_finish (GPermission   *permission,
235                              GAsyncResult  *result,
236                              GError       **error)
237 {
238   return G_PERMISSION_GET_CLASS (permission)
239     ->release_finish (permission, result, error);
240 }
241
242 /**
243  * g_permission_get_allowed:
244  * @permission: a #GPermission instance
245  *
246  * Gets the value of the 'allowed' property.  This property is %TRUE if
247  * the caller currently has permission to perform the action that
248  * @permission represents the permission to perform.
249  *
250  * Returns: the value of the 'allowed' property
251  *
252  * Since: 2.26
253  **/
254 gboolean
255 g_permission_get_allowed (GPermission *permission)
256 {
257   return permission->priv->allowed;
258 }
259
260 /**
261  * g_permission_get_can_acquire:
262  * @permission: a #GPermission instance
263  *
264  * Gets the value of the 'can-acquire' property.  This property is %TRUE
265  * if it is generally possible to acquire the permission by calling
266  * g_permission_acquire().
267  *
268  * Returns: the value of the 'can-acquire' property
269  *
270  * Since: 2.26
271  **/
272 gboolean
273 g_permission_get_can_acquire (GPermission *permission)
274 {
275   return permission->priv->can_acquire;
276 }
277
278 /**
279  * g_permission_get_can_release:
280  * @permission: a #GPermission instance
281  *
282  * Gets the value of the 'can-release' property.  This property is %TRUE
283  * if it is generally possible to release the permission by calling
284  * g_permission_release().
285  *
286  * Returns: the value of the 'can-release' property
287  *
288  * Since: 2.26
289  **/
290 gboolean
291 g_permission_get_can_release (GPermission *permission)
292 {
293   return permission->priv->can_release;
294 }
295
296 /**
297  * g_permission_impl_update:
298  * @permission: a #GPermission instance
299  * @allowed: the new value for the 'allowed' property
300  * @can_acquire: the new value for the 'can-acquire' property
301  * @can_release: the new value for the 'can-release' property
302  *
303  * This function is called by the #GPermission implementation to update
304  * the properties of the permission.  You should never call this
305  * function except from a #GPermission implementation.
306  *
307  * GObject notify signals are generated, as appropriate.
308  *
309  * Since: 2.26
310  **/
311 void
312 g_permission_impl_update (GPermission *permission,
313                           gboolean     allowed,
314                           gboolean     can_acquire,
315                           gboolean     can_release)
316 {
317   GObject *object = G_OBJECT (permission);
318
319   g_object_freeze_notify (object);
320
321   if (allowed != permission->priv->allowed)
322     {
323       permission->priv->allowed = !!allowed;
324       g_object_notify (object, "allowed");
325     }
326
327   if (can_acquire != permission->priv->can_acquire)
328     {
329       permission->priv->can_acquire = !!can_acquire;
330       g_object_notify (object, "can-acquire");
331     }
332
333   if (can_release != permission->priv->can_release)
334     {
335       permission->priv->can_release = !!can_release;
336       g_object_notify (object, "can-release");
337     }
338
339   g_object_thaw_notify (object);
340 }
341
342 static void
343 g_permission_get_property (GObject *object, guint prop_id,
344                            GValue *value, GParamSpec *pspec)
345 {
346   GPermission *permission = G_PERMISSION (object);
347
348   switch (prop_id)
349     {
350     case PROP_ALLOWED:
351       g_value_set_boolean (value, permission->priv->allowed);
352       break;
353
354     case PROP_CAN_ACQUIRE:
355       g_value_set_boolean (value, permission->priv->can_acquire);
356       break;
357
358     case PROP_CAN_RELEASE:
359       g_value_set_boolean (value, permission->priv->can_release);
360       break;
361
362     default:
363       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
364   }
365 }
366
367 static void
368 g_permission_init (GPermission *permission)
369 {
370   permission->priv = G_TYPE_INSTANCE_GET_PRIVATE (permission,
371                                                   G_TYPE_PERMISSION,
372                                                   GPermissionPrivate);
373 }
374
375 static void
376 g_permission_class_init (GPermissionClass *class)
377 {
378   GObjectClass *object_class = G_OBJECT_CLASS (class);
379
380   object_class->get_property = g_permission_get_property;
381
382   /**
383    * GPermission:allowed:
384    *
385    * %TRUE if the caller currently has permission to perform the action that
386    * @permission represents the permission to perform.
387    */
388    g_object_class_install_property (object_class, PROP_ALLOWED,
389      g_param_spec_boolean ("allowed",
390                            P_("Is allowed"),
391                            P_("If the caller is allowed to perform the action"),
392                            FALSE,
393                            G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
394
395   /**
396    * GPermission:can-acquire:
397    *
398    * %TRUE if it is generally possible to acquire the permission by calling
399    * g_permission_acquire().
400    */
401    g_object_class_install_property (object_class, PROP_CAN_ACQUIRE,
402      g_param_spec_boolean ("can-acquire",
403                            P_("Can acquire"),
404                            P_("If calling g_permission_acquire() makes sense"),
405                            FALSE,
406                            G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
407
408   /**
409    * GPermission:can-release:
410    *
411    * %TRUE if it is generally possible to release the permission by calling
412    * g_permission_release().
413    */
414    g_object_class_install_property (object_class, PROP_CAN_RELEASE,
415      g_param_spec_boolean ("can-release",
416                            P_("Can release"),
417                            P_("If calling g_permission_release() makes sense"),
418                            FALSE,
419                            G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
420
421   g_type_class_add_private (class, sizeof (GPermissionPrivate));
422 }