permissions: implement _remove_role
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-permissions.c
1 /* GStreamer
2  * Copyright (C) 2013 Wim Taymans <wim.taymans at gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 /**
20  * SECTION:rtsp-permissions
21  * @short_description: Roles and associated permissions
22  * @see_also: #GstRTSPToken, #GstRTSPAuth
23  *
24  * The #GstRTSPPermission object contains an array of roles and associated
25  * permissions. The roles are represented with a string and the permissions with
26  * a generic #GstStructure.
27  *
28  * The permissions are deliberately kept generic. The possible values of the
29  * roles and #GstStructure keys and values are only determined by the #GstRTSPAuth
30  * object that performs the checks on the permissions and the current
31  * #GstRTSPToken.
32  *
33  * As a convenience function, gst_rtsp_permissions_is_allowed() can be used to
34  * check if the permissions contains a role that contains the boolean value
35  * %TRUE for the the given key.
36  *
37  * Last reviewed on 2013-07-15 (1.0.0)
38  */
39
40 #include <string.h>
41
42 #include "rtsp-permissions.h"
43
44 typedef struct _GstRTSPPermissionsImpl
45 {
46   GstRTSPPermissions permissions;
47
48   /* Roles, array of GstStructure */
49   GPtrArray *roles;
50 } GstRTSPPermissionsImpl;
51
52 static void
53 free_structure (GstStructure * structure)
54 {
55   gst_structure_set_parent_refcount (structure, NULL);
56   gst_structure_free (structure);
57 }
58
59 //GST_DEBUG_CATEGORY_STATIC (rtsp_permissions_debug);
60 //#define GST_CAT_DEFAULT rtsp_permissions_debug
61
62 GST_DEFINE_MINI_OBJECT_TYPE (GstRTSPPermissions, gst_rtsp_permissions);
63
64 static void gst_rtsp_permissions_init (GstRTSPPermissionsImpl * permissions,
65     GstStructure * structure);
66
67 static void
68 _gst_rtsp_permissions_free (GstRTSPPermissions * permissions)
69 {
70   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
71
72   g_ptr_array_free (impl->roles, TRUE);
73
74   g_slice_free1 (sizeof (GstRTSPPermissionsImpl), permissions);
75 }
76
77 static GstRTSPPermissions *
78 _gst_rtsp_permissions_copy (GstRTSPPermissionsImpl * permissions)
79 {
80   GstRTSPPermissionsImpl *copy;
81   GstStructure *structure;
82
83   copy = g_slice_new0 (GstRTSPPermissionsImpl);
84   gst_rtsp_permissions_init (copy, structure);
85
86   return GST_RTSP_PERMISSIONS (copy);
87 }
88
89 static void
90 gst_rtsp_permissions_init (GstRTSPPermissionsImpl * permissions,
91     GstStructure * structure)
92 {
93   gst_mini_object_init (GST_MINI_OBJECT_CAST (permissions), 0,
94       GST_TYPE_RTSP_PERMISSIONS,
95       (GstMiniObjectCopyFunction) _gst_rtsp_permissions_copy, NULL,
96       (GstMiniObjectFreeFunction) _gst_rtsp_permissions_free);
97
98   permissions->roles =
99       g_ptr_array_new_with_free_func ((GDestroyNotify) free_structure);
100 }
101
102 /**
103  * gst_rtsp_permissions_new:
104  *
105  * Create a new empty Authorization permissions.
106  *
107  * Returns: (transfer full): a new empty authorization permissions.
108  */
109 GstRTSPPermissions *
110 gst_rtsp_permissions_new (void)
111 {
112   GstRTSPPermissionsImpl *permissions;
113
114   permissions = g_slice_new0 (GstRTSPPermissionsImpl);
115
116   gst_rtsp_permissions_init (permissions,
117       gst_structure_new_empty ("GstRTSPPermissions"));
118
119   return GST_RTSP_PERMISSIONS (permissions);
120 }
121
122 /**
123  * gst_rtsp_permissions_add_role:
124  * @permissions: a #GstRTSPPermissions
125  * @role: a role
126  * @fielname: the first field name
127  * @...: additional arguments
128  *
129  * Add a new @role to @permissions with the given variables. The fields
130  * are the same layout as gst_structure_new().
131  */
132 void
133 gst_rtsp_permissions_add_role (GstRTSPPermissions * permissions,
134     const gchar * role, const gchar * fieldname, ...)
135 {
136   va_list var_args;
137
138   va_start (var_args, fieldname);
139   gst_rtsp_permissions_add_role_valist (permissions, role, fieldname, var_args);
140   va_end (var_args);
141 }
142
143 /**
144  * gst_rtsp_permissions_add_role_valist:
145  * @permissions: a #GstRTSPPermissions
146  * @role: a role
147  * @fielname: the first field name
148  * @var_args: additional fields to add
149  *
150  * Add a new @role to @permissions with the given variables. Structure fields
151  * are set according to the varargs in a manner similar to gst_structure_new().
152  */
153 void
154 gst_rtsp_permissions_add_role_valist (GstRTSPPermissions * permissions,
155     const gchar * role, const gchar * fieldname, va_list var_args)
156 {
157   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
158   GstStructure *structure;
159   guint i, len;
160   gboolean found;
161
162   g_return_if_fail (GST_IS_RTSP_PERMISSIONS (permissions));
163   g_return_if_fail (gst_mini_object_is_writable (&permissions->mini_object));
164   g_return_if_fail (role != NULL);
165   g_return_if_fail (fieldname != NULL);
166
167   structure = gst_structure_new_valist (role, fieldname, var_args);
168   g_return_if_fail (structure != NULL);
169
170   len = impl->roles->len;
171   found = FALSE;
172   for (i = 0; i < len; i++) {
173     GstStructure *entry = g_ptr_array_index (impl->roles, i);
174
175     if (gst_structure_has_name (entry, role)) {
176       gst_structure_free (entry);
177       found = TRUE;
178       break;
179     }
180   }
181
182   gst_structure_set_parent_refcount (structure,
183       &impl->permissions.mini_object.refcount);
184   if (!found)
185     g_ptr_array_add (impl->roles, structure);
186   else
187     g_ptr_array_index (impl->roles, i) = structure;
188 }
189
190 /**
191  * gst_rtsp_permissions_remove_role:
192  * @permissions: a #GstRTSPPermissions
193  * @role: a role
194  *
195  * Remove all permissions for @role in @permissions.
196  */
197 void
198 gst_rtsp_permissions_remove_role (GstRTSPPermissions * permissions,
199     const gchar * role)
200 {
201   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
202   guint i, len;
203
204   g_return_if_fail (GST_IS_RTSP_PERMISSIONS (permissions));
205   g_return_if_fail (gst_mini_object_is_writable (&permissions->mini_object));
206   g_return_if_fail (role != NULL);
207
208   len = impl->roles->len;
209   for (i = 0; i < len; i++) {
210     GstStructure *entry = g_ptr_array_index (impl->roles, i);
211
212     if (gst_structure_has_name (entry, role)) {
213       g_ptr_array_remove_index_fast (impl->roles, i);
214       gst_structure_free (entry);
215       break;
216     }
217   }
218 }
219
220 /**
221  * gst_rtsp_permissions_get_role:
222  * @permissions: a #GstRTSPPermissions
223  * @role: a role
224  *
225  * Get all permissions for @role in @permissions.
226  *
227  * Returns: the structure with permissions for @role.
228  */
229 const GstStructure *
230 gst_rtsp_permissions_get_role (GstRTSPPermissions * permissions,
231     const gchar * role)
232 {
233   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
234   guint i, len;
235
236   g_return_val_if_fail (GST_IS_RTSP_PERMISSIONS (permissions), NULL);
237   g_return_val_if_fail (role != NULL, NULL);
238
239   len = impl->roles->len;
240   for (i = 0; i < len; i++) {
241     GstStructure *entry = g_ptr_array_index (impl->roles, i);
242
243     if (gst_structure_has_name (entry, role))
244       return entry;
245   }
246   return NULL;
247 }
248
249 /**
250  * gst_rtsp_permissions_is_allowed:
251  * @permissions: a #GstRTSPPermissions
252  * @role: a role
253  * @permission: a permission
254  *
255  * Check if @role in @permissions is given permission for @permission.
256  *
257  * Returns: %TRUE if @role is allowed @permission.
258  */
259 gboolean
260 gst_rtsp_permissions_is_allowed (GstRTSPPermissions * permissions,
261     const gchar * role, const gchar * permission)
262 {
263   const GstStructure *str;
264   gboolean result;
265
266   g_return_val_if_fail (GST_IS_RTSP_PERMISSIONS (permissions), FALSE);
267   g_return_val_if_fail (role != NULL, FALSE);
268   g_return_val_if_fail (permission != NULL, FALSE);
269
270   str = gst_rtsp_permissions_get_role (permissions, role);
271   if (str == NULL)
272     return FALSE;
273
274   if (!gst_structure_get_boolean (str, permission, &result))
275     result = FALSE;
276
277   return result;
278 }