Print Acl Id & minor updates
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / cloud / aclid.c
1 #include "utils.h"
2
3 #include "oic_malloc.h"
4 #include "logger.h"
5 #include "ocstack.h"
6 #include "ocpayload.h"
7 #include "pmutility.h"
8 #include "cacommonutil.h"
9 #include "aclresource.h"
10 #include "ocpayloadcbor.h"
11 #include "payload_logging.h"
12
13 #define TAG "CLOUD-ACL-ID"
14
15 /**
16  * ACL Id parse from received response
17  *
18  * @param[in] ctx       context
19  * @param[out] data     data required to external application
20  * @param[in] response  peer response
21  * @return  OCStackResult application result
22  */
23 static OCStackResult getAclIdFromResponse(void *ctx, void **data, OCClientResponse *response)
24 {
25     OC_UNUSED(ctx);
26     if (NULL == response->payload)
27     {
28         OIC_LOG(ERROR, TAG, "Receive NULL payload");
29         return OC_STACK_INVALID_PARAM;
30     }
31
32     char *aclid = NULL;
33
34     if (!OCRepPayloadGetPropString((const OCRepPayload *)response->payload, OC_RSRVD_ACL_ID, &aclid))
35     {
36         OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_ACL_ID);
37         return OC_STACK_MALFORMED_RESPONSE;
38     }
39
40     OIC_LOG_V(INFO, TAG, "Received Acl id = %s", aclid);
41
42     *data = aclid;
43     return OC_STACK_OK;
44 }
45
46 /**
47  * ACL Id by device request received data handler
48  *
49  * @param[in] ctx       context
50  * @param[out] data     data required to external application
51  * @param[in] response  peer response
52  * @return  OCStackResult application result
53  */
54 static OCStackResult handleGetAclIdByDeviceResponse(void *ctx, void **data,
55                                                     OCClientResponse *response)
56 {
57     return getAclIdFromResponse(ctx, data, response);
58 }
59
60 /**
61  * ACL Id create request received data handler
62  *
63  * @param[in] ctx       context
64  * @param[out] data     data required to external application
65  * @param[in] response  peer response
66  * @return  OCStackResult application result
67  */
68 static OCStackResult handleAclIdCreateResponse(void *ctx, void **data, OCClientResponse *response)
69 {
70     return getAclIdFromResponse(ctx, data, response);
71 }
72
73 OCStackResult OCCloudGetAclIdByDevice(void* ctx,
74                                       const char *deviceId,
75                                       const OCDevAddr *endPoint,
76                                       OCCloudResponseCB callback)
77 {
78     char uri[MAX_URI_LENGTH] = { 0 };
79
80     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
81
82     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
83             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_DEVICE_ID, deviceId);
84
85     OCCallbackData cbData;
86     fillCallbackData(&cbData, ctx, callback, handleGetAclIdByDeviceResponse, NULL);
87
88     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
89                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
90 }
91
92 OCStackResult OCCloudAclIdCreate(void* ctx,
93                                  const char *ownerId,
94                                  const char *deviceId,
95                                  const OCDevAddr *endPoint,
96                                  OCCloudResponseCB callback)
97 {
98     char uri[MAX_URI_LENGTH] = { 0 };
99
100     VERIFY_NON_NULL_RET(ownerId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
101     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
102
103     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s&%s=%s", DEFAULT_PREFIX,
104             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL,
105             OC_RSRVD_OWNER_ID, ownerId, OC_RSRVD_DEVICE_ID, deviceId);
106
107     OCCallbackData cbData;
108     fillCallbackData(&cbData, ctx, callback, handleAclIdCreateResponse, NULL);
109
110     return OCDoResource(NULL, OC_REST_PUT, uri, NULL, NULL,
111                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
112 }
113
114 OCStackResult OCCloudAclIdDelete(void* ctx,
115                                  const char *aclId,
116                                  const OCDevAddr *endPoint,
117                                  OCCloudResponseCB callback)
118 {
119     char uri[MAX_URI_LENGTH]  = { 0 };
120
121     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
122
123     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
124             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_ACL_ID, aclId);
125
126     OCCallbackData cbData;
127     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
128
129     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
130                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
131 }
132
133 /**
134  * ACL Get Info received data handler
135  *
136  * @param[in] ctx       context
137  * @param[out] data     data required to external application
138  * @param[in] response  peer response
139  * @return  OCStackResult application result
140  */
141 static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientResponse *response)
142 {
143     OCStackResult result = OC_STACK_OK;
144     uint8_t *cbor = NULL;
145     size_t size   = 0;
146
147     OC_UNUSED(ctx);
148     OC_UNUSED(data);
149
150     if (NULL == response->payload)
151     {
152         OIC_LOG(ERROR, TAG, "Receive NULL payload\n");
153         return OC_STACK_INVALID_PARAM;
154     }
155
156     result = OCConvertPayload(response->payload, &cbor, &size);
157     if (result != OC_STACK_OK)
158     {
159         OIC_LOG(ERROR, TAG, "Can't convert OCPayload to cbor");
160         goto exit;
161     }
162
163     OicSecAcl_t* acl = CBORPayloadToAcl2(cbor, size);
164     if (NULL == acl)
165     {
166         OIC_LOG(ERROR, TAG, "Can't parse CBOR payload");
167         goto exit;
168     }
169
170     result = InstallNewACL2(acl);
171     if (result != OC_STACK_OK)
172     {
173         OIC_LOG(ERROR, TAG, "Can't update ACL resource");
174     }
175
176 exit:
177     //can't delete acl because aces was added to gAcl
178     OICFree(cbor);
179     return result;
180 }
181
182 OCStackResult OCCloudAclIndividualGetInfo(void* ctx,
183                                           const char *aclId,
184                                           const OCDevAddr *endPoint,
185                                           OCCloudResponseCB callback)
186 {
187     char uri[MAX_URI_LENGTH]  = { 0 };
188
189     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
190
191     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
192             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
193
194     OCCallbackData cbData;
195     fillCallbackData(&cbData, ctx, callback, handleAclGetInfoResponse, NULL);
196
197     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
198                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
199 }
200
201 OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
202                                             const char *aclId,
203                                             const cloudAce_t *aces,
204                                             const OCDevAddr *endPoint,
205                                             OCCloudResponseCB callback)
206 {
207     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
208     char uri[MAX_URI_LENGTH]  = { 0 };
209
210     int i = 0, j = 0;
211
212     OCRepPayload **helperPayload  = NULL;
213     OCRepPayload **helperPayload2 = NULL;
214
215     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
216     VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
217
218     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
219             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
220
221     OCRepPayload *payload = OCRepPayloadCreate();
222     if (!payload)
223     {
224         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
225         goto no_memory;
226     }
227
228     int acllist_count = 0;
229     if (aces)
230     {
231         cloudAce_t *ace = (cloudAce_t *)&aces[acllist_count++];
232         while (ace->next)
233         {
234             ace = ace->next;
235             acllist_count++;
236         }
237     }
238
239     helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
240     if (!helperPayload)
241     {
242         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
243         goto no_memory;
244     }
245
246     for (int i = 0; i < acllist_count; i++)
247     {
248         OCRepPayload *payload = OCRepPayloadCreate();
249         if (!payload)
250         {
251             OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
252             goto no_memory;
253         }
254         helperPayload[i] = payload;
255
256         const cloudAce_t *ace = &aces[i];
257
258         OCRepPayloadSetPropString(payload, OC_RSRVD_ACE_ID, ace->aceId);
259         OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)ace->subjectuuid.id);
260         OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
261         OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
262
263         int reslist_count = 0;
264         if (ace->resources)
265         {
266             OicSecRsrc_t *res = &ace->resources[reslist_count++];
267             while (res->next)
268             {
269                 res = res->next;
270                 reslist_count++;
271             }
272         }
273
274         helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
275         if (!helperPayload2)
276         {
277             goto no_memory;
278         }
279
280         for (int j = 0; j < reslist_count; j++)
281         {
282             OCRepPayload *payload = OCRepPayloadCreate();
283             if (!payload)
284             {
285                 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
286                 goto no_memory;
287             }
288             helperPayload2[j] = payload;
289
290             const OicSecRsrc_t *res = &ace->resources[j];
291
292             OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
293
294             dimensions[0] = res->typeLen;
295             OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
296                                        (const char **)res->types, dimensions);
297
298             dimensions[0] = res->interfaceLen;
299             OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
300                                        (const char **)res->interfaces, dimensions);
301         }
302         dimensions[0] = reslist_count;
303         OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
304                 (const OCRepPayload **)helperPayload2, dimensions);
305     }
306     dimensions[0] = acllist_count;
307     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
308             (const OCRepPayload **)helperPayload, dimensions);
309
310     OCCallbackData cbData;
311     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
312
313     OIC_LOG(DEBUG, TAG, "Next payload created:");
314     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
315
316     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
317                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
318 no_memory:
319     if (helperPayload2)
320     {
321         for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
322         OICFree(helperPayload2);
323     }
324     if (helperPayload)
325     {
326         for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
327         OICFree(helperPayload);
328     }
329     OCRepPayloadDestroy(payload);
330     return OC_STACK_NO_MEMORY;
331 }
332
333 OCStackResult OCCloudAclIndividualDelete(void* ctx,
334                                          const char *aclId,
335                                          const OCDevAddr *endPoint,
336                                          OCCloudResponseCB callback)
337 {
338     char uri[MAX_URI_LENGTH]  = { 0 };
339
340     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
341
342     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
343             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
344
345     OCCallbackData cbData;
346     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
347
348     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
349                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
350 }