Cloud Client
[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 create request received data handler
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 handleAclIdCreateResponse(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     *data = aclid;
41     return OC_STACK_OK;
42 }
43
44 OCStackResult OCCloudAclIdGetByDevice(void* ctx,
45                                       const char *deviceId,
46                                       const OCDevAddr *endPoint,
47                                       OCCloudResponseCB callback)
48 {
49     char uri[MAX_URI_LENGTH] = { 0 };
50
51     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
52
53     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
54             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_DEVICE_ID, deviceId);
55
56     OCCallbackData cbData;
57     fillCallbackData(&cbData, ctx, callback, handleAclIdCreateResponse, NULL);
58
59     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
60                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
61 }
62
63 OCStackResult OCCloudAclIdCreate(void* ctx,
64                                  const char *ownerId,
65                                  const char *deviceId,
66                                  const OCDevAddr *endPoint,
67                                  OCCloudResponseCB callback)
68 {
69     char uri[MAX_URI_LENGTH] = { 0 };
70
71     VERIFY_NON_NULL_RET(ownerId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
72     VERIFY_NON_NULL_RET(deviceId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
73
74     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s&%s=%s", DEFAULT_PREFIX,
75             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL,
76             OC_RSRVD_OWNER_ID, ownerId, OC_RSRVD_DEVICE_ID, deviceId);
77
78     OCCallbackData cbData;
79     fillCallbackData(&cbData, ctx, callback, handleAclIdCreateResponse, NULL);
80
81     return OCDoResource(NULL, OC_REST_PUT, uri, NULL, NULL,
82                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
83 }
84
85 OCStackResult OCCloudAclIdDelete(void* ctx,
86                                  const char *aclId,
87                                  const OCDevAddr *endPoint,
88                                  OCCloudResponseCB callback)
89 {
90     char uri[MAX_URI_LENGTH]  = { 0 };
91
92     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
93
94     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s?%s=%s", DEFAULT_PREFIX,
95             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, OC_RSRVD_ACL_ID, aclId);
96
97     OCCallbackData cbData;
98     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
99
100     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
101                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
102 }
103
104 /**
105  * ACL Get Info received data handler
106  *
107  * @param[in] ctx       context
108  * @param[out] data     data required to external application
109  * @param[in] response  peer response
110  * @return  OCStackResult application result
111  */
112 static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientResponse *response)
113 {
114     OCStackResult result = OC_STACK_OK;
115     uint8_t *cbor = NULL;
116     size_t size   = 0;
117
118     OC_UNUSED(ctx);
119     OC_UNUSED(data);
120
121     if (NULL == response->payload)
122     {
123         OIC_LOG(ERROR, TAG, "Receive NULL payload\n");
124         return OC_STACK_INVALID_PARAM;
125     }
126
127     result = OCConvertPayload(response->payload, &cbor, &size);
128     if (result != OC_STACK_OK)
129     {
130         OIC_LOG(ERROR, TAG, "Can't convert OCPayload to cbor");
131         goto exit;
132     }
133
134     OicSecAcl_t* acl = CBORPayloadToAcl2(cbor, size);
135     if (NULL == acl)
136     {
137         OIC_LOG(ERROR, TAG, "Can't parse CBOR payload");
138         goto exit;
139     }
140
141     result = InstallNewACL2(acl);
142     if (result != OC_STACK_OK)
143     {
144         OIC_LOG(ERROR, TAG, "Can't update ACL resource");
145     }
146
147 exit:
148     //can't delete acl because aces was added to gAcl
149     OICFree(cbor);
150     return result;
151 }
152
153 OCStackResult OCCloudAclIndividualGetInfo(void* ctx,
154                                           const char *aclId,
155                                           const OCDevAddr *endPoint,
156                                           OCCloudResponseCB callback)
157 {
158     char uri[MAX_URI_LENGTH]  = { 0 };
159
160     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
161
162     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
163             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
164
165     OCCallbackData cbData;
166     fillCallbackData(&cbData, ctx, callback, handleAclGetInfoResponse, NULL);
167
168     return OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL,
169                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
170 }
171
172 OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
173                                             const char *aclId,
174                                             const cloudAce_t *aces,
175                                             const OCDevAddr *endPoint,
176                                             OCCloudResponseCB callback)
177 {
178     size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
179     char uri[MAX_URI_LENGTH]  = { 0 };
180
181     int i = 0, j = 0;
182
183     OCRepPayload **helperPayload  = NULL;
184     OCRepPayload **helperPayload2 = NULL;
185
186     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
187     VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
188
189     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
190             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
191
192     OCRepPayload *payload = OCRepPayloadCreate();
193     if (!payload)
194     {
195         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
196         goto no_memory;
197     }
198
199     int acllist_count = 0;
200     if (aces)
201     {
202         cloudAce_t *ace = (cloudAce_t *)&aces[acllist_count++];
203         while (ace->next)
204         {
205             ace = ace->next;
206             acllist_count++;
207         }
208     }
209
210     helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
211     if (!helperPayload)
212     {
213         OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
214         goto no_memory;
215     }
216
217     for (int i = 0; i < acllist_count; i++)
218     {
219         OCRepPayload *payload = OCRepPayloadCreate();
220         if (!payload)
221         {
222             OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
223             goto no_memory;
224         }
225         helperPayload[i] = payload;
226
227         const cloudAce_t *ace = &aces[i];
228
229         OCRepPayloadSetPropString(payload, OC_RSRVD_ACE_ID, ace->aceId);
230         OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)ace->subjectuuid.id);
231         OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
232         OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
233
234         int reslist_count = 0;
235         if (ace->resources)
236         {
237             OicSecRsrc_t *res = &ace->resources[reslist_count++];
238             while (res->next)
239             {
240                 res = res->next;
241                 reslist_count++;
242             }
243         }
244
245         helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
246         if (!helperPayload2)
247         {
248             goto no_memory;
249         }
250
251         for (int j = 0; j < reslist_count; j++)
252         {
253             OCRepPayload *payload = OCRepPayloadCreate();
254             if (!payload)
255             {
256                 OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
257                 goto no_memory;
258             }
259             helperPayload2[j] = payload;
260
261             const OicSecRsrc_t *res = &ace->resources[j];
262
263             OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
264
265             dimensions[0] = res->typeLen;
266             OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
267                                        (const char **)res->types, dimensions);
268
269             dimensions[0] = res->interfaceLen;
270             OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
271                                        (const char **)res->interfaces, dimensions);
272         }
273         dimensions[0] = reslist_count;
274         OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
275                 (const OCRepPayload **)helperPayload2, dimensions);
276     }
277     dimensions[0] = acllist_count;
278     OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
279             (const OCRepPayload **)helperPayload, dimensions);
280
281     OCCallbackData cbData;
282     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
283
284     OIC_LOG(DEBUG, TAG, "Next payload created:");
285     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
286
287     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
288                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
289 no_memory:
290     if (helperPayload2)
291     {
292         for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
293         OICFree(helperPayload2);
294     }
295     if (helperPayload)
296     {
297         for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
298         OICFree(helperPayload);
299     }
300     OCRepPayloadDestroy(payload);
301     return OC_STACK_NO_MEMORY;
302 }
303
304 OCStackResult OCCloudAclIndividualDelete(void* ctx,
305                                          const char *aclId,
306                                          const OCDevAddr *endPoint,
307                                          OCCloudResponseCB callback)
308 {
309     char uri[MAX_URI_LENGTH]  = { 0 };
310
311     VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
312
313     snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
314             endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
315
316     OCCallbackData cbData;
317     fillCallbackData(&cbData, ctx, callback, NULL, NULL);
318
319     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
320                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
321 }