security provisioning cloud c++ fixs
[iotivity.git] / resource / csdk / security / provisioning / src / cloud / aclinvite.c
1 /* *****************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * *****************************************************************/
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include "occloudprovisioning.h"
25 #include "utils.h"
26
27 #include "oic_malloc.h"
28 #include "experimental/logger.h"
29 #include "ocstack.h"
30 #include "ocpayload.h"
31 #include "pmutility.h"
32 #include "cacommonutil.h"
33
34 #define TAG "OIC_CLOUD_ACL_INVITE"
35
36 /**
37  * This helper function parses "name" : { "gid":[], "mid":[] } payload
38  *
39  * @param[in] payload     received payload
40  * @param[in] name        property name
41  * @param[out] out        string array pair to fill
42  * @return  OCStackResult application result
43  */
44 static OCStackResult parseInvitePayload(const OCRepPayload *payload, const char *name,
45                                         stringArrayPair_t *out)
46 {
47     OCStackResult result = OC_STACK_NO_MEMORY;
48     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
49     OCRepPayload **helperPayload  = NULL;
50     size_t i = 0;
51     stringArray_t *gidlist = NULL;
52     stringArray_t *midlist = NULL;
53
54     if (!OCRepPayloadGetPropObjectArray(payload, name, &helperPayload, dimensions))
55     {
56         OIC_LOG_V(ERROR, TAG, "Can't get: %s", name);
57         return OC_STACK_MALFORMED_RESPONSE;
58     }
59
60     size_t count = calcDimTotal(dimensions);
61     if (0 == count)
62     {
63         OIC_LOG(ERROR, TAG, "zero list len");
64         goto exit;
65     }
66
67     gidlist = &out->gidlist;
68     midlist = &out->midlist;
69
70     gidlist->length = count;
71     midlist->length = count;
72
73     gidlist->array = (char**)OICCalloc(gidlist->length, sizeof(char *));
74     if (NULL == gidlist->array)
75     {
76         OIC_LOG(ERROR, TAG, "Can't allocate gidlist->array");
77         goto exit;
78     }
79
80     midlist->array = (char**)OICCalloc(midlist->length, sizeof(char *));
81     if (NULL == midlist->array)
82     {
83         OIC_LOG(ERROR, TAG, "Can't allocate midlist->array");
84         goto exit;
85     }
86
87     for (i = 0; i < gidlist->length; i++)
88     {
89         const OCRepPayload *gidPayload = helperPayload[i];
90
91         if (!OCRepPayloadGetPropString(gidPayload, OC_RSRVD_GROUP_ID, &gidlist->array[i]))
92         {
93             OIC_LOG_V(ERROR, TAG, "Can't get group id: %s", OC_RSRVD_GROUP_ID);
94             result = OC_STACK_MALFORMED_RESPONSE;
95             goto exit;
96         }
97
98         if (!OCRepPayloadGetPropString(gidPayload, OC_RSRVD_MEMBER_ID, &midlist->array[i]))
99         {
100             OIC_LOG_V(ERROR, TAG, "Can't get member id: %s", OC_RSRVD_MEMBER_ID);
101             result = OC_STACK_MALFORMED_RESPONSE;
102             goto exit;
103         }
104         OCRepPayloadDestroy(helperPayload[i]);
105     }
106
107     result = OC_STACK_OK;
108
109 exit:
110     if (result != OC_STACK_OK)
111     {
112         clearStringArray(gidlist);
113         clearStringArray(midlist);
114
115         for (size_t k = i; k < gidlist->length; k++)
116         {
117             OCRepPayloadDestroy(helperPayload[i]);
118         }
119     }
120     OICFree(helperPayload);
121     return result;
122 }
123
124 /**
125  * ACL get invitation request received data handler
126  *
127  * @param[in] ctx       context
128  * @param[out] data     data required to external application
129  * @param[in] response  peer response
130  * @return  OCStackResult application result
131  */
132 static OCStackResult handleAclGetInvitationResponse(void *ctx, void **data,
133         OCClientResponse *response)
134 {
135     OC_UNUSED(ctx);
136     OCStackResult result = OC_STACK_OK;
137
138     VERIFY_NON_NULL_RET(response, TAG, "NULL response", OC_STACK_INVALID_PARAM);
139     VERIFY_NON_NULL_RET(data, TAG, "NULL data", OC_STACK_INVALID_PARAM);
140
141     if (NULL == response->payload)
142     {
143         OIC_LOG(ERROR, TAG, "Receive NULL payload");
144         return OC_STACK_INVALID_PARAM;
145     }
146
147     inviteResponse_t *answer = (inviteResponse_t*)OICCalloc(1, sizeof(inviteResponse_t));
148     if (NULL == answer)
149     {
150         OIC_LOG(ERROR, TAG, "Can't allocate answer");
151         return OC_STACK_NO_MEMORY;
152     }
153
154     const OCRepPayload *payload = (const OCRepPayload *)response->payload;
155
156     result = parseInvitePayload(payload, OC_RSRVD_INVITE, &answer->invite);
157     if (result != OC_STACK_OK)
158     {
159         goto exit;
160     }
161
162     result = parseInvitePayload(payload, OC_RSRVD_INVITED, &answer->invited);
163     if (result != OC_STACK_OK)
164     {
165         goto exit;
166     }
167
168     *data = answer;
169 exit:
170     return result;
171 }
172
173 /**
174  * ACL policy check request received data handler
175  *
176  * @param[in] ctx       context
177  * @param[out] data     data required to external application
178  * @param[in] response  peer response
179  * @return  OCStackResult application result
180  */
181 static OCStackResult handleAclPolicyCheckResponse(void *ctx, void **data,
182                                                   OCClientResponse *response)
183 {
184     OC_UNUSED(ctx);
185
186     VERIFY_NON_NULL_RET(response, TAG, "NULL response", OC_STACK_INVALID_PARAM);
187     VERIFY_NON_NULL_RET(data, TAG, "NULL data", OC_STACK_INVALID_PARAM);
188
189     if (NULL == response->payload)
190     {
191         OIC_LOG(ERROR, TAG, "Receive NULL payload");
192         return OC_STACK_INVALID_PARAM;
193     }
194
195     char *gp = NULL;
196
197     if (!OCRepPayloadGetPropString((const OCRepPayload *)response->payload, OC_RSRVD_GROUP_PERMISSION,
198                                    &gp))
199     {
200         OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_GROUP_PERMISSION);
201         return OC_STACK_MALFORMED_RESPONSE;
202     }
203
204     *data = gp;
205     return OC_STACK_OK;
206 }
207
208 OCStackResult OCCloudAclInviteUser(void *ctx,
209                                    const char *userId,
210                                    const stringArray_t *groupIds,
211                                    const stringArray_t *memberIds,
212                                    const char *cloudUri,
213                                    OCCloudResponseCB callback)
214 {
215     OCStackResult result = OC_STACK_ERROR;
216     char uri[MAX_URI_LENGTH] = { 0 };
217     size_t i = 0;
218     size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0, 0, 0};
219
220     VERIFY_NON_NULL_RET(cloudUri, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
221     VERIFY_NON_NULL_RET(groupIds, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
222     VERIFY_NON_NULL_RET(memberIds, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
223
224     if (0 == groupIds->length)
225     {
226         OIC_LOG(ERROR, TAG, "groups length is 0");
227         return OC_STACK_INVALID_PARAM;
228     }
229
230     if (groupIds->length != memberIds->length)
231     {
232         OIC_LOG(ERROR, TAG, "members and groups lists should have the same length!!!");
233         return OC_STACK_INVALID_PARAM;
234     }
235
236     snprintf(uri, MAX_URI_LENGTH, "%s%s", cloudUri, OC_RSRVD_ACL_INVITE_URL);
237
238     OCCallbackData cbData;
239     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
240
241     OCRepPayload *payload = OCRepPayloadCreate();
242     if (!payload)
243     {
244         OIC_LOG(ERROR, TAG, "Memory Allocation failed!!!");
245         return OC_STACK_NO_MEMORY;
246     }
247
248     OCRepPayload **heplerPayload = (OCRepPayload**)OICCalloc(groupIds->length, sizeof(OCRepPayload *));
249     if (NULL == heplerPayload)
250     {
251         OCRepPayloadDestroy(payload);
252         OIC_LOG(ERROR, TAG, "Memory Allocation failed!!!");
253         return OC_STACK_NO_MEMORY;
254     }
255     for (i = 0; i < groupIds->length; i++)
256     {
257         heplerPayload[i] = OCRepPayloadCreate();
258         if (!heplerPayload[i])
259         {
260             goto no_memory;
261         }
262         OCRepPayloadSetPropString(heplerPayload[i], OC_RSRVD_GROUP_ID, groupIds->array[i]);
263         OCRepPayloadSetPropString(heplerPayload[i], OC_RSRVD_MEMBER_ID, memberIds->array[i]);
264     }
265
266     //add next fields if they were filled
267     if (userId) OCRepPayloadSetPropString(payload, OC_RSRVD_USER_UUID, userId);
268
269     dimensions[0] = groupIds->length;
270     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_INVITE,
271                                    (const struct OCRepPayload **)heplerPayload, dimensions);
272
273     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
274                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
275 no_memory:
276     OCRepPayloadDestroy(payload);
277     for (size_t k = 0; k < i; k++)
278     {
279         OCRepPayloadDestroy(heplerPayload[k]);
280     }
281     OCRepPayloadDestroy(*heplerPayload);
282     return result;
283 }
284
285 OCStackResult OCCloudAclGetInvitation(void *ctx,
286                                       const char *userId,
287                                       const char *cloudUri,
288                                       OCCloudResponseCB callback)
289 {
290     char uri[MAX_URI_LENGTH] = { 0 };
291
292     VERIFY_NON_NULL_RET(cloudUri, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
293
294     snprintf(uri, MAX_URI_LENGTH, "%s%s", cloudUri, OC_RSRVD_ACL_INVITE_URL);
295
296     if (userId)
297     {
298         size_t len = strlen(uri);
299         snprintf(uri + len, MAX_URI_LENGTH - len, "?%s=%s", OC_RSRVD_USER_UUID, userId);
300     }
301
302     OCCallbackData cbData;
303     fillCallbackData(&cbData, ctx, callback, handleAclGetInvitationResponse, NULL);
304
305     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
306                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
307 }
308
309 OCStackResult OCCloudAclDeleteInvitation(void *ctx,
310                                          const char *userId,
311                                          const char *groupId,
312                                          const char *cloudUri,
313                                          OCCloudResponseCB callback)
314 {
315     char uri[MAX_URI_LENGTH] = { 0 };
316
317     VERIFY_NON_NULL_RET(cloudUri, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
318     VERIFY_NON_NULL_RET(groupId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
319
320     snprintf(uri, MAX_URI_LENGTH, "%s%s", cloudUri, OC_RSRVD_ACL_INVITE_URL);
321
322     if (userId)
323     {
324         size_t len = strlen(uri);
325         snprintf(uri + len, MAX_URI_LENGTH - len, "?%s=%s", OC_RSRVD_USER_UUID, userId);
326     }
327
328     size_t len = strlen(uri);
329     snprintf(uri + len, MAX_URI_LENGTH - len, "%c%s=%s", userId ? '&' : '?', OC_RSRVD_GROUP_ID,
330              groupId);
331
332     OCCallbackData cbData;
333     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
334
335     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
336                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
337 }
338
339 OCStackResult OCCloudAclCancelInvitation(void *ctx,
340                                          const char *userId,
341                                          const char *groupId,
342                                          const char *memberId,
343                                          const char *cloudUri,
344                                          OCCloudResponseCB callback)
345 {
346     char uri[MAX_URI_LENGTH] = { 0 };
347     size_t len = 0 ;
348
349     VERIFY_NON_NULL_RET(cloudUri, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
350     VERIFY_NON_NULL_RET(groupId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
351     VERIFY_NON_NULL_RET(memberId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
352
353     snprintf(uri, MAX_URI_LENGTH, "%s%s", cloudUri, OC_RSRVD_ACL_INVITE_URL);
354
355     if (userId)
356     {
357         len = strlen(uri);
358         snprintf((uri + len), (MAX_URI_LENGTH - len), "?%s=%s", OC_RSRVD_USER_UUID, userId);
359     }
360
361     len = strlen(uri);
362     snprintf(uri + len, MAX_URI_LENGTH - len, "%c%s=%s", userId ? '&' : '?', OC_RSRVD_GROUP_ID,
363              groupId);
364     len = strlen(uri);
365     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_MEMBER_ID, memberId);
366
367     OCCallbackData cbData;
368     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
369
370     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
371                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
372 }
373
374 OCStackResult OCCloudAclPolicyCheck(void *ctx,
375                                     const char *subjectId,
376                                     const char *deviceId,
377                                     const char *method,
378                                     const char *user_uri,
379                                     const char *cloudUri,
380                                     OCCloudResponseCB callback)
381 {
382     char uri[MAX_URI_LENGTH] = { 0 };
383     size_t len = 0;
384
385     VERIFY_NON_NULL_RET(cloudUri, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
386     VERIFY_NON_NULL_RET(subjectId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
387     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
388     VERIFY_NON_NULL_RET(method, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
389     VERIFY_NON_NULL_RET(user_uri, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
390
391     snprintf(uri, MAX_URI_LENGTH, "%s%s", cloudUri, OC_RSRVD_ACL_VERIFY_URL);
392
393     len = strlen(uri);
394     snprintf(uri + len, MAX_URI_LENGTH - len, "?%s=%s", OC_RSRVD_SUBJECT_ID, subjectId);
395     len = strlen(uri);
396     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_DEVICE_ID, deviceId);
397     len = strlen(uri);
398     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_REQUEST_METHOD, method);
399     len = strlen(uri);
400     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_REQUEST_URI, user_uri);
401
402     OCCallbackData cbData;
403     fillCallbackData(&cbData, ctx, callback, handleAclPolicyCheckResponse, NULL);
404
405     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
406                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
407 }