Changes in spec file for WITH_PROCESS_EVENT flag
[platform/upstream/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 "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, stringArrayPair_t *out)
45 {
46     OCStackResult result = OC_STACK_NO_MEMORY;
47     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
48     OCRepPayload **heplerPayload  = NULL;
49     size_t i = 0;
50
51     if (!OCRepPayloadGetPropObjectArray(payload, name, &heplerPayload, dimensions))
52     {
53         OIC_LOG_V(ERROR, TAG, "Can't get: %s", name);
54         return OC_STACK_MALFORMED_RESPONSE;
55     }
56
57     size_t count = calcDimTotal(dimensions);
58
59     stringArray_t *gidlist = &out->gidlist;
60     stringArray_t *midlist = &out->midlist;
61
62     gidlist->length = count;
63     midlist->length = count;
64
65     gidlist->array = OICCalloc(gidlist->length, sizeof(char *));
66     if (NULL == gidlist->array)
67     {
68         OIC_LOG(ERROR, TAG, "Can't allocate gidlist->array");
69         goto exit;
70     }
71
72     midlist->array = OICCalloc(midlist->length, sizeof(char *));
73     if (NULL == midlist->array)
74     {
75         OIC_LOG(ERROR, TAG, "Can't allocate midlist->array");
76         goto exit;
77     }
78
79     for (i = 0; i < gidlist->length; i++)
80     {
81         const OCRepPayload *payload = heplerPayload[i];
82
83         if (!OCRepPayloadGetPropString(payload, OC_RSRVD_GROUP_ID, &gidlist->array[i]))
84         {
85             OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_GROUP_ID);
86             result = OC_STACK_MALFORMED_RESPONSE;
87             goto exit;
88         }
89
90         if (!OCRepPayloadGetPropString(payload, OC_RSRVD_MEMBER_ID, &midlist->array[i]))
91         {
92             OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_MEMBER_ID);
93             result = OC_STACK_MALFORMED_RESPONSE;
94             goto exit;
95         }
96         OCRepPayloadDestroy(heplerPayload[i]);
97     }
98
99     result = OC_STACK_OK;
100
101 exit:
102     if (result != OC_STACK_OK)
103     {
104         clearStringArray(gidlist);
105         clearStringArray(midlist);
106
107         for (size_t k = i; k < gidlist->length; k++)
108         {
109             OCRepPayloadDestroy(heplerPayload[i]);
110         }
111     }
112     OICFree(heplerPayload);
113     return result;
114 }
115
116 /**
117  * ACL get invitation request received data handler
118  *
119  * @param[in] ctx       context
120  * @param[out] data     data required to external application
121  * @param[in] response  peer response
122  * @return  OCStackResult application result
123  */
124 static OCStackResult handleAclGetInvitationResponse(void *ctx, void **data, OCClientResponse *response)
125 {
126     OC_UNUSED(ctx);
127     OCStackResult result = OC_STACK_OK;
128
129     if (NULL == response->payload)
130     {
131         OIC_LOG(ERROR, TAG, "Receive NULL payload");
132         return OC_STACK_INVALID_PARAM;
133     }
134
135     inviteResponse_t *answer = OICCalloc(1, sizeof(inviteResponse_t));
136     if (NULL == answer)
137     {
138         OIC_LOG(ERROR, TAG, "Can't allocate answer");
139         return OC_STACK_NO_MEMORY;
140     }
141
142     const OCRepPayload *payload = (const OCRepPayload *)response->payload;
143
144     result = parseInvitePayload(payload, OC_RSRVD_INVITE, &answer->invite);
145     if (result != OC_STACK_OK)
146     {
147         goto exit;
148     }
149
150     result = parseInvitePayload(payload, OC_RSRVD_INVITED, &answer->invited);
151     if (result != OC_STACK_OK)
152     {
153         goto exit;
154     }
155
156     *data = answer;
157 exit:
158     return result;
159 }
160
161 /**
162  * ACL policy check request received data handler
163  *
164  * @param[in] ctx       context
165  * @param[out] data     data required to external application
166  * @param[in] response  peer response
167  * @return  OCStackResult application result
168  */
169 static OCStackResult handleAclPolicyCheckResponse(void *ctx, void **data, OCClientResponse *response)
170 {
171     OC_UNUSED(ctx);
172
173     if (NULL == response->payload)
174     {
175         OIC_LOG(ERROR, TAG, "Receive NULL payload");
176         return OC_STACK_INVALID_PARAM;
177     }
178
179     char *gp = NULL;
180
181     if (!OCRepPayloadGetPropString((const OCRepPayload *)response->payload, OC_RSRVD_GROUP_PERMISSION, &gp))
182     {
183         OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_GROUP_PERMISSION);
184         return OC_STACK_MALFORMED_RESPONSE;
185     }
186
187     *data = gp;
188     return OC_STACK_OK;
189 }
190
191 OCStackResult OCCloudAclInviteUser(void* ctx,
192                                    const char *userId,
193                                    const stringArray_t *groupIds,
194                                    const stringArray_t *memberIds,
195                                    const OCDevAddr *endPoint,
196                                    OCCloudResponseCB callback)
197 {
198     OCStackResult result = OC_STACK_ERROR;
199     char uri[MAX_URI_LENGTH] = { 0 };
200     size_t i = 0;
201
202     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
203     VERIFY_NON_NULL_RET(groupIds, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
204     VERIFY_NON_NULL_RET(memberIds, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
205
206     if (groupIds->length != memberIds->length)
207     {
208         OIC_LOG(ERROR, TAG, "members and groups lists should have the same length!!!");
209         return OC_STACK_INVALID_PARAM;
210     }
211
212     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s", DEFAULT_PREFIX,
213             endPoint->addr, endPoint->port, OC_RSRVD_ACL_INVITE_URL);
214
215     OCCallbackData cbData;
216     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
217
218     OCRepPayload *payload = OCRepPayloadCreate();
219     if (!payload)
220     {
221         return OC_STACK_NO_MEMORY;
222     }
223
224     OCRepPayload **heplerPayload = OICCalloc(groupIds->length, sizeof(OCRepPayload *));
225
226     for (i = 0; i < groupIds->length; i++)
227     {
228         heplerPayload[i] = OCRepPayloadCreate();
229         if (!heplerPayload[i])
230         {
231             goto no_memory;
232         }
233         OCRepPayloadSetPropString(heplerPayload[i], OC_RSRVD_GROUP_ID, groupIds->array[i]);
234         OCRepPayloadSetPropString(heplerPayload[i], OC_RSRVD_MEMBER_ID, memberIds->array[i]);
235     }
236
237     //add next fields if they were filled
238     if (userId) OCRepPayloadSetPropString(payload, OC_RSRVD_USER_UUID, userId);
239
240     size_t dimensions[MAX_REP_ARRAY_DEPTH] = {groupIds->length, 0, 0};
241     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_INVITE,
242             (const struct OCRepPayload **)heplerPayload, dimensions);
243
244     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
245                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
246 no_memory:
247     OCRepPayloadDestroy(payload);
248     for (size_t k = 0; k < i; k++)
249     {
250         OCRepPayloadDestroy(heplerPayload[k]);
251     }
252     OCRepPayloadDestroy(*heplerPayload);
253     return result;
254 }
255
256 OCStackResult OCCloudAclGetInvitation(void* ctx,
257                                       const char *userId,
258                                       const OCDevAddr *endPoint,
259                                       OCCloudResponseCB callback)
260 {
261     char uri[MAX_URI_LENGTH] = { 0 };
262
263     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
264
265     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s", DEFAULT_PREFIX,
266             endPoint->addr, endPoint->port, OC_RSRVD_ACL_INVITE_URL);
267
268     if (userId)
269     {
270         size_t len = strlen(uri);
271         snprintf(uri + len, MAX_URI_LENGTH -len, "?%s=%s", OC_RSRVD_USER_UUID, userId);
272     }
273
274     OCCallbackData cbData;
275     fillCallbackData(&cbData, ctx, callback, handleAclGetInvitationResponse, NULL);
276
277     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
278                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
279 }
280
281 OCStackResult OCCloudAclDeleteInvitation(void* ctx,
282                                          const char *userId,
283                                          const char *groupId,
284                                          const OCDevAddr *endPoint,
285                                          OCCloudResponseCB callback)
286 {
287     char uri[MAX_URI_LENGTH] = { 0 };
288
289     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
290     VERIFY_NON_NULL_RET(groupId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
291
292     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s", DEFAULT_PREFIX,
293             endPoint->addr, endPoint->port, OC_RSRVD_ACL_INVITE_URL);
294
295     if (userId)
296     {
297         size_t len = strlen(uri);
298         snprintf(uri + len, MAX_URI_LENGTH - len, "?%s=%s", OC_RSRVD_USER_UUID, userId);
299     }
300
301     size_t len = strlen(uri);
302     snprintf(uri + len, MAX_URI_LENGTH - len, "%c%s=%s", userId?'&':'?', OC_RSRVD_GROUP_ID, groupId);
303
304     OCCallbackData cbData;
305     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
306
307     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
308                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
309 }
310
311 OCStackResult OCCloudAclCancelInvitation(void* ctx,
312                                          const char *userId,
313                                          const char *groupId,
314                                          const char *memberId,
315                                          const OCDevAddr *endPoint,
316                                          OCCloudResponseCB callback)
317 {
318     char uri[MAX_URI_LENGTH] = { 0 };
319     size_t len = 0 ;
320
321     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
322     VERIFY_NON_NULL_RET(groupId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
323     VERIFY_NON_NULL_RET(memberId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
324
325     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s", DEFAULT_PREFIX,
326             endPoint->addr, endPoint->port, OC_RSRVD_ACL_INVITE_URL);
327
328     if (userId)
329     {
330         size_t len = strlen(uri);
331         snprintf(uri + len, MAX_URI_LENGTH - len, "?%s=%s", OC_RSRVD_USER_UUID, userId);
332     }
333
334     len = strlen(uri);
335     snprintf(uri + len, MAX_URI_LENGTH - len, "%c%s=%s", userId?'&':'?', OC_RSRVD_GROUP_ID, groupId);
336     len = strlen(uri);
337     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_MEMBER_ID, memberId);
338
339     OCCallbackData cbData;
340     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
341
342     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
343                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
344 }
345
346 OCStackResult OCCloudAclPolicyCheck(void* ctx,
347                                     const char *subjectId,
348                                     const char *deviceId,
349                                     const char *method,
350                                     const char *user_uri,
351                                     const OCDevAddr *endPoint,
352                                     OCCloudResponseCB callback)
353 {
354     char uri[MAX_URI_LENGTH] = { 0 };
355     size_t len = 0;
356
357     VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
358     VERIFY_NON_NULL_RET(subjectId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
359     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
360     VERIFY_NON_NULL_RET(method, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
361     VERIFY_NON_NULL_RET(user_uri, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
362
363     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s", DEFAULT_PREFIX,
364             endPoint->addr, endPoint->port, OC_RSRVD_ACL_VERIFY_URL);
365
366     len = strlen(uri);
367     snprintf(uri + len, MAX_URI_LENGTH - len, "?%s=%s", OC_RSRVD_SUBJECT_ID, subjectId);
368     len = strlen(uri);
369     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_DEVICE_ID, deviceId);
370     len = strlen(uri);
371     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_REQUEST_METHOD, method);
372     len = strlen(uri);
373     snprintf(uri + len, MAX_URI_LENGTH - len, "&%s=%s", OC_RSRVD_REQUEST_URI, user_uri);
374
375     OCCallbackData cbData;
376     fillCallbackData(&cbData, ctx, callback, handleAclPolicyCheckResponse, NULL);
377
378     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
379                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
380 }