Coverage Report

Created: 2025-07-11 06:47

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