Initial release including wifi display based on gst-rtsp-server-1.4.1
[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 #GstRTSPPermissions 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
66 static void
67 _gst_rtsp_permissions_free (GstRTSPPermissions * permissions)
68 {
69   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
70
71   g_ptr_array_free (impl->roles, TRUE);
72
73   g_slice_free1 (sizeof (GstRTSPPermissionsImpl), permissions);
74 }
75
76 static GstRTSPPermissions *
77 _gst_rtsp_permissions_copy (GstRTSPPermissionsImpl * permissions)
78 {
79   GstRTSPPermissionsImpl *copy;
80   guint i;
81
82   copy = (GstRTSPPermissionsImpl *) gst_rtsp_permissions_new ();
83
84   for (i = 0; i < permissions->roles->len; i++) {
85     GstStructure *entry = g_ptr_array_index (permissions->roles, i);
86     GstStructure *entry_copy = gst_structure_copy (entry);
87
88     gst_structure_set_parent_refcount (entry_copy,
89         &copy->permissions.mini_object.refcount);
90     g_ptr_array_add (copy->roles, entry_copy);
91   }
92
93   return GST_RTSP_PERMISSIONS (copy);
94 }
95
96 static void
97 gst_rtsp_permissions_init (GstRTSPPermissionsImpl * permissions)
98 {
99   gst_mini_object_init (GST_MINI_OBJECT_CAST (permissions), 0,
100       GST_TYPE_RTSP_PERMISSIONS,
101       (GstMiniObjectCopyFunction) _gst_rtsp_permissions_copy, NULL,
102       (GstMiniObjectFreeFunction) _gst_rtsp_permissions_free);
103
104   permissions->roles =
105       g_ptr_array_new_with_free_func ((GDestroyNotify) free_structure);
106 }
107
108 /**
109  * gst_rtsp_permissions_new:
110  *
111  * Create a new empty Authorization permissions.
112  *
113  * Returns: (transfer full): a new empty authorization permissions.
114  */
115 GstRTSPPermissions *
116 gst_rtsp_permissions_new (void)
117 {
118   GstRTSPPermissionsImpl *permissions;
119
120   permissions = g_slice_new0 (GstRTSPPermissionsImpl);
121   gst_rtsp_permissions_init (permissions);
122
123   return GST_RTSP_PERMISSIONS (permissions);
124 }
125
126 /**
127  * gst_rtsp_permissions_add_role:
128  * @permissions: a #GstRTSPPermissions
129  * @role: a role
130  * @fieldname: the first field name
131  * @...: additional arguments
132  *
133  * Add a new @role to @permissions with the given variables. The fields
134  * are the same layout as gst_structure_new().
135  */
136 void
137 gst_rtsp_permissions_add_role (GstRTSPPermissions * permissions,
138     const gchar * role, const gchar * fieldname, ...)
139 {
140   va_list var_args;
141
142   va_start (var_args, fieldname);
143   gst_rtsp_permissions_add_role_valist (permissions, role, fieldname, var_args);
144   va_end (var_args);
145 }
146
147 /**
148  * gst_rtsp_permissions_add_role_valist:
149  * @permissions: a #GstRTSPPermissions
150  * @role: a role
151  * @fieldname: the first field name
152  * @var_args: additional fields to add
153  *
154  * Add a new @role to @permissions with the given variables. Structure fields
155  * are set according to the varargs in a manner similar to gst_structure_new().
156  */
157 void
158 gst_rtsp_permissions_add_role_valist (GstRTSPPermissions * permissions,
159     const gchar * role, const gchar * fieldname, va_list var_args)
160 {
161   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
162   GstStructure *structure;
163   guint i, len;
164
165   g_return_if_fail (GST_IS_RTSP_PERMISSIONS (permissions));
166   g_return_if_fail (gst_mini_object_is_writable (&permissions->mini_object));
167   g_return_if_fail (role != NULL);
168   g_return_if_fail (fieldname != NULL);
169
170   structure = gst_structure_new_valist (role, fieldname, var_args);
171   g_return_if_fail (structure != NULL);
172
173   len = impl->roles->len;
174   for (i = 0; i < len; i++) {
175     GstStructure *entry = g_ptr_array_index (impl->roles, i);
176
177     if (gst_structure_has_name (entry, role)) {
178       g_ptr_array_remove_index_fast (impl->roles, i);
179       break;
180     }
181   }
182
183   gst_structure_set_parent_refcount (structure,
184       &impl->permissions.mini_object.refcount);
185   g_ptr_array_add (impl->roles, structure);
186 }
187
188 /**
189  * gst_rtsp_permissions_remove_role:
190  * @permissions: a #GstRTSPPermissions
191  * @role: a role
192  *
193  * Remove all permissions for @role in @permissions.
194  */
195 void
196 gst_rtsp_permissions_remove_role (GstRTSPPermissions * permissions,
197     const gchar * role)
198 {
199   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
200   guint i, len;
201
202   g_return_if_fail (GST_IS_RTSP_PERMISSIONS (permissions));
203   g_return_if_fail (gst_mini_object_is_writable (&permissions->mini_object));
204   g_return_if_fail (role != NULL);
205
206   len = impl->roles->len;
207   for (i = 0; i < len; i++) {
208     GstStructure *entry = g_ptr_array_index (impl->roles, i);
209
210     if (gst_structure_has_name (entry, role)) {
211       g_ptr_array_remove_index_fast (impl->roles, i);
212       break;
213     }
214   }
215 }
216
217 /**
218  * gst_rtsp_permissions_get_role:
219  * @permissions: a #GstRTSPPermissions
220  * @role: a role
221  *
222  * Get all permissions for @role in @permissions.
223  *
224  * Returns: (transfer none): the structure with permissions for @role. It
225  * remains valid for as long as @permissions is valid.
226  */
227 const GstStructure *
228 gst_rtsp_permissions_get_role (GstRTSPPermissions * permissions,
229     const gchar * role)
230 {
231   GstRTSPPermissionsImpl *impl = (GstRTSPPermissionsImpl *) permissions;
232   guint i, len;
233
234   g_return_val_if_fail (GST_IS_RTSP_PERMISSIONS (permissions), NULL);
235   g_return_val_if_fail (role != NULL, NULL);
236
237   len = impl->roles->len;
238   for (i = 0; i < len; i++) {
239     GstStructure *entry = g_ptr_array_index (impl->roles, i);
240
241     if (gst_structure_has_name (entry, role))
242       return entry;
243   }
244   return NULL;
245 }
246
247 /**
248  * gst_rtsp_permissions_is_allowed:
249  * @permissions: a #GstRTSPPermissions
250  * @role: a role
251  * @permission: a permission
252  *
253  * Check if @role in @permissions is given permission for @permission.
254  *
255  * Returns: %TRUE if @role is allowed @permission.
256  */
257 gboolean
258 gst_rtsp_permissions_is_allowed (GstRTSPPermissions * permissions,
259     const gchar * role, const gchar * permission)
260 {
261   const GstStructure *str;
262   gboolean result;
263
264   g_return_val_if_fail (GST_IS_RTSP_PERMISSIONS (permissions), FALSE);
265   g_return_val_if_fail (role != NULL, FALSE);
266   g_return_val_if_fail (permission != NULL, FALSE);
267
268   str = gst_rtsp_permissions_get_role (permissions, role);
269   if (str == NULL)
270     return FALSE;
271
272   if (!gst_structure_get_boolean (str, permission, &result))
273     result = FALSE;
274
275   return result;
276 }