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