replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / src / cloud / aclid.c
index c85c478..20da886 100644 (file)
@@ -1,3 +1,22 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
 #include "utils.h"
 
 #include "oic_malloc.h"
 #include "ocstack.h"
 #include "ocpayload.h"
 #include "pmutility.h"
-#include "srmutility.h"
 #include "cacommonutil.h"
 #include "aclresource.h"
 #include "ocpayloadcbor.h"
 #include "payload_logging.h"
 #include "utlist.h"
+#include "securevirtualresourcetypes.h"
+
+#define TAG "OIC_CLOUD_ACL_ID"
 
-#define TAG "CLOUD-ACL-ID"
+/* Although this is already implemented in srmutility.h, we can't include the header file,
+ * because of "redefined VERIFY_NON_NULL"
+ */
+OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid);
 
 /**
  * ACL Id parse from received response
@@ -174,14 +198,14 @@ static OCStackResult handleAclGetInfoResponse(void *ctx, void **data, OCClientRe
 
     printACL(acl);
 
-    result = InstallNewACL2(acl);
+    result = InstallACL(acl);
     if (result != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "Can't update ACL resource");
     }
 
+    *data = acl;
 exit:
-    //can't delete acl because aces was added to gAcl
     OICFree(cbor);
     return result;
 }
@@ -271,7 +295,6 @@ OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
             OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
         }
 
-        OCRepPayloadSetPropString(payload, OC_RSRVD_ACE_ID, ace->aceId);
         OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
         OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
         OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
@@ -349,6 +372,143 @@ no_memory:
     return OC_STACK_NO_MEMORY;
 }
 
+OCStackResult OCCloudAclIndividualUpdate(void* ctx,
+                                            const char *aclId,
+                                            const char *aceId,
+                                            const cloudAce_t *aces,
+                                            const OCDevAddr *endPoint,
+                                            OCCloudResponseCB callback)
+{
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+    char uri[MAX_URI_LENGTH]  = { 0 };
+
+    int i = 0, j = 0;
+
+    OCRepPayload **helperPayload  = NULL;
+    OCRepPayload **helperPayload2 = NULL;
+
+    VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(aces, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
+
+    snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s?%s=%s", DEFAULT_PREFIX,
+            endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId,
+            OC_RSRVD_ACE_ID, aceId);
+
+    OCRepPayload *payload = OCRepPayloadCreate();
+    if (!payload)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for payload");
+        goto no_memory;
+    }
+
+    int acllist_count = 1;
+
+    helperPayload = OICCalloc(acllist_count, sizeof(OCRepPayload *));
+    if (!helperPayload)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload");
+        goto no_memory;
+    }
+
+    i = 0;
+    cloudAce_t *ace = NULL;
+
+    LL_FOREACH((cloudAce_t*)aces, ace)
+    {
+        OCRepPayload *payload = OCRepPayloadCreate();
+        if (!payload)
+        {
+            OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload[i]");
+            goto no_memory;
+        }
+        helperPayload[i++] = payload;
+
+        char *uuid = NULL;
+        if (OC_STACK_OK != ConvertUuidToStr(&ace->subjectuuid, &uuid))
+        {
+            OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
+        }
+
+        OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
+        OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, ace->stype);
+        OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, ace->permission);
+
+        OICFree(uuid);
+
+        int reslist_count = 0;
+        //code below duplicates LL_COUNT, implemented in newer version of utlist.h
+        {
+            OicSecRsrc_t *res = ace->resources;
+            while (res)
+            {
+                res = res->next;
+                reslist_count++;
+            }
+        }
+
+        helperPayload2 = OICCalloc(reslist_count, sizeof(OCRepPayload *));
+        if (!helperPayload2)
+        {
+            goto no_memory;
+        }
+
+        j = 0;
+        OicSecRsrc_t *res = NULL;
+
+        LL_FOREACH(ace->resources, res)
+        {
+            OCRepPayload *payload = OCRepPayloadCreate();
+            if (!payload)
+            {
+                OIC_LOG_V(DEBUG, TAG, "Can't allocate memory for helperPayload2[j]");
+                goto no_memory;
+            }
+            helperPayload2[j++] = payload;
+
+            OCRepPayloadSetPropString(payload, OC_RSRVD_HREF, res->href);
+
+            dimensions[0] = res->typeLen;
+            OCRepPayloadSetStringArray(payload, OC_RSRVD_RESOURCE_TYPE,
+                                       (const char **)res->types, dimensions);
+
+            dimensions[0] = res->interfaceLen;
+            OCRepPayloadSetStringArray(payload, OC_RSRVD_INTERFACE,
+                                       (const char **)res->interfaces, dimensions);
+        }
+        dimensions[0] = reslist_count;
+        OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_RESOURCES,
+                (const OCRepPayload **)helperPayload2, dimensions);
+    }
+    dimensions[0] = acllist_count;
+    OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ACCESS_CONTROL_LIST,
+            (const OCRepPayload **)helperPayload, dimensions);
+
+    OCCallbackData cbData;
+    fillCallbackData(&cbData, ctx, callback, NULL, NULL);
+
+    OIC_LOG(DEBUG, TAG, "Next payload created:");
+    OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)payload);
+
+    return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+no_memory:
+    if (helperPayload2)
+    {
+        for (int k = 0; k < j; k++) OCRepPayloadDestroy(helperPayload2[k]);
+        OICFree(helperPayload2);
+    }
+    if (helperPayload)
+    {
+        for (int k = 0; k < i; k++) OCRepPayloadDestroy(helperPayload[k]);
+        OICFree(helperPayload);
+    }
+    OCRepPayloadDestroy(payload);
+    return OC_STACK_NO_MEMORY;
+}
+
+
+
 OCStackResult OCCloudAclIndividualDelete(void* ctx,
                                          const char *aclId,
                                          const OCDevAddr *endPoint,
@@ -368,3 +528,56 @@ OCStackResult OCCloudAclIndividualDelete(void* ctx,
     return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
 }
+
+OCStackResult OCCloudAclIndividualDeleteAce(void* ctx,
+                                         const char *aclId,
+                                         const char *aceId,
+                                         const OCDevAddr *endPoint,
+                                         OCCloudResponseCB callback)
+{
+    char uri[MAX_URI_LENGTH]  = { 0 };
+
+    VERIFY_NON_NULL_RET(endPoint, TAG, "NULL endpoint", OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(aclId, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
+
+    snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s?%s=%s", DEFAULT_PREFIX,
+            endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId,
+            OC_RSRVD_ACE_ID, aceId);
+
+    OCCallbackData cbData;
+    fillCallbackData(&cbData, ctx, callback, NULL, NULL);
+
+    return OCDoResource(NULL, OC_REST_DELETE, uri, NULL, NULL,
+                        CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+}
+
+OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid)
+{
+    if (NULL == uuid || NULL == strUuid || NULL != *strUuid)
+    {
+        OIC_LOG(ERROR, TAG, "ConvertUuidToStr : Invalid param");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    size_t uuidIdx = 0;
+    size_t urnIdx = 0;
+    const size_t urnBufSize = (UUID_LENGTH * 2) + 4 + 1;
+    char *convertedUrn = (char*)OICCalloc(urnBufSize, sizeof(char));
+    VERIFY_NON_NULL(convertedUrn, TAG, "OICCalloc() is failed(convertedUrn)");
+
+    for (uuidIdx = 0, urnIdx = 0; uuidIdx < UUID_LENGTH && urnIdx < urnBufSize;
+            uuidIdx++, urnIdx += 2)
+    {
+        // canonical format for UUID has '8-4-4-4-12'
+        if (4 == uuidIdx || 6 == uuidIdx || 8 == uuidIdx || 10 == uuidIdx)
+        {
+            snprintf(convertedUrn + urnIdx, 2, "%c", '-');
+            urnIdx++;
+        }
+        snprintf(convertedUrn + urnIdx, 3, "%02x", (uint8_t)(uuid->id[uuidIdx]));
+    }
+    convertedUrn[urnBufSize - 1] = '\0';
+
+    *strUuid = convertedUrn;
+    return OC_STACK_OK;
+}