Cloud ACL Modifications
authorJongmin Choi <jminl.choi@samsung.com>
Wed, 5 Oct 2016 11:47:38 +0000 (20:47 +0900)
committerRandeep Singh <randeep.s@samsung.com>
Fri, 7 Oct 2016 13:53:21 +0000 (13:53 +0000)
Modifications to Cloud ACL

Patch #1: ACE Id changed to UUID format
Patch #2: Changes modified DeleteACE & UpdateACE changes added
Patch #3: Oid check included in verifyAcl
Patch #4-5: OCCloudAclIndividualDeleteAce() added
Patch #6: Minor bug fixes
Patch #7: OCCloudAclIndividualUpdate() added

Signed-off-by: Sunil Kumar K R <sunil.k14@samsung.com>
Change-Id: I6b3b4c68f06c43ce002df36a741ea4eb8549ba44
Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/12739
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Randeep Singh <randeep.s@samsung.com>
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java
cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java
resource/csdk/security/provisioning/include/cloud/occloudprovisioning.h
resource/csdk/security/provisioning/sample/cloud/cloudCommon.c
resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c
resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h
resource/csdk/security/provisioning/src/cloud/aclid.c

index c7c9757..1adb63a 100644 (file)
@@ -28,6 +28,8 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.UUID;
+import java.util.ListIterator;
 
 import org.iotivity.cloud.accountserver.Constants;
 import org.iotivity.cloud.accountserver.db.AccountDBManager;
@@ -154,6 +156,11 @@ public class Acl {
         List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
             .get(Constants.REQ_ACL_LIST);
 
+
+        for(HashMap<String, Object> ace : aclist) {
+            ace.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString());
+        }
+
         List<HashMap<String, Object>> newAcList = new ArrayList<HashMap<String, Object>>(
                 aclist);
 
@@ -166,6 +173,55 @@ public class Acl {
         notifyToSubscriber(getResponsePayload(true));
     }
 
+    public void updateACE(String aceid, HashMap<String, Object> ace) {
+
+        HashMap<String, Object> hashmap = AccountDBManager.getInstance()
+            .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+
+        List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap.get(Constants.REQ_ACL_LIST);
+
+        ace.put(Constants.REQ_ACE_ID, aceid);
+
+        ListIterator<HashMap<String, Object>> iterator = aclDbList.listIterator();
+        while (iterator.hasNext()) {
+            HashMap<String, Object> aceMap = iterator.next();
+            if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
+                // replace current iterator with new element
+                iterator.set(ace);
+                break;
+            }
+        }
+
+        hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
+        AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, hashmap);
+        notifyToSubscriber(getResponsePayload(true));
+    }
+
+    public void deleteACE(String aceid) {
+
+        HashMap<String, Object> hashmap = AccountDBManager.getInstance()
+            .selectRecord(Constants.ACL_TABLE, getCondition()).get(0);
+
+        List<HashMap<String, Object>> aclDbList = (List<HashMap<String, Object>>) hashmap
+            .get(Constants.REQ_ACL_LIST);
+
+
+        ListIterator<HashMap<String, Object>> iterator = aclDbList.listIterator();
+        while (iterator.hasNext()) {
+            HashMap<String, Object> aceMap = iterator.next();
+            if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) {
+                // Remove the current element from the iterator
+                iterator.remove();
+                break;
+            }
+        }
+
+        hashmap.put(Constants.REQ_ACL_LIST, aclDbList);
+        AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE,
+                hashmap);
+        notifyToSubscriber(getResponsePayload(true));
+    }
+
     public void deleteAclist() {
         AclTable aclTable = getAclTable();
         aclTable.setAclist(null);
index 701ca80..f974aaf 100644 (file)
@@ -91,7 +91,14 @@ public class AclManager {
         getAcl(aclid).addACE(aclist);
     }
 
-    public void deleteAclACE(String aclid) {
+    public void updateACE(String aclid, String aceid, HashMap<String, Object> ace) {
+        getAcl(aclid).updateACE(aceid, ace);
+    }
+
+    public void deleteAclACE(String aclid, String aceid) {
+        getAcl(aclid).deleteACE(aceid);
+    }
+    public void deleteAclAclist(String aclid) {
         getAcl(aclid).deleteAclist();
     }
 
index dd2a920..c9f9c51 100644 (file)
@@ -100,6 +100,12 @@ public class AclResource extends Resource {
                         .get(Constants.REQ_ACL_LIST);
             mAclManager.addAclACE(aclid, aclist);
             return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
+        }else if (getUriPathSegments().containsAll(request.getUriPathSegments())) {
+            String aclid = request.getUriPathSegments().get(getUriPathSegments().size());
+            String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID).get(0);
+            HashMap<String, Object> ace = (HashMap<String, Object>) payloadData.get(Constants.REQ_ACL_LIST);
+            mAclManager.updateACE(aclid, aceid, ace);
+            return MessageBuilder.createResponse(request, ResponseStatus.CHANGED);
         }
 
         throw new BadRequestException("uriPath is invalid");
@@ -163,7 +169,12 @@ public class AclResource extends Resource {
             mAclManager.deleteAcl(aclid);
         } else {
             aclid = request.getUriPathSegments().get(getUriPathSegments().size());
-            mAclManager.deleteAclACE(aclid);
+            String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID).get(0);
+            if (aceid == null) {
+                mAclManager.deleteAclAclist(aclid);
+            } else {
+                mAclManager.deleteAclACE(aclid, aceid);
+            }
         }
 
         return MessageBuilder.createResponse(request, ResponseStatus.DELETED);
index 3682b7a..87cb960 100644 (file)
@@ -100,6 +100,9 @@ public class AclVerifyResource extends Resource {
                 if (aclTable.getAclist() == null) {
                     return false;
                 }
+                if (aclTable.getOid().equals(sid)) {
+                    return true;
+                }
                 for (Ace ace : aclTable.getAclist()) {
                     if (ace.getSubjectuuid().equals(sid)) {
                         // check permission matches
index 4f8ccfd..6e2da24 100644 (file)
@@ -175,7 +175,25 @@ OCStackResult OCCloudAclIndividualUpdateAce(void* ctx,
                                             OCCloudResponseCB callback);
 
 /**
- * ACL individual delete
+ * ACL individual update
+ *
+ * @param[in] ctx               user-defined context
+ * @param[in] aclId             mandatory parameter acl id
+ * @param[in] aceId             mandatory parameter target ace id
+ * @param[in] aces              mandatory parameter aces
+ * @param[in] endPoint          cloud host and port
+ * @param[in] callback          optional result callback, can be NULL if not required
+ * @return  OCStackResult application result
+ */
+OCStackResult OCCloudAclIndividualUpdate(void* ctx,
+                                            const char *aclId,
+                                            const char *aceId,
+                                            const cloudAce_t *aces,
+                                            const OCDevAddr *endPoint,
+                                            OCCloudResponseCB callback);
+
+/**
+ * ACL individual delete - replaces ACE with given aceid with provided ACE
  *
  * @param[in] ctx               user-defined context
  * @param[in] aclId             mandatory parameter acl id
@@ -189,6 +207,22 @@ OCStackResult OCCloudAclIndividualDelete(void* ctx,
                                          OCCloudResponseCB callback);
 
 /**
+ * ACL individual delete ACE
+ *
+ * @param[in] ctx               user-defined context
+ * @param[in] aclId             mandatory parameter acl id
+ * @param[in] aceId             target ace id
+ * @param[in] endPoint          cloud host and port
+ * @param[in] callback          optional result callback, can be NULL if not required
+ * @return  OCStackResult application result
+ */
+OCStackResult OCCloudAclIndividualDeleteAce(void* ctx,
+                                         const char *aclId,
+                                         const char *aceId,
+                                         const OCDevAddr *endPoint,
+                                         OCCloudResponseCB callback);
+
+/**
  * ACL post group request function
  *
  * @param[in] ctx               user-defined context
index 6add1c0..360ba42 100644 (file)
@@ -97,7 +97,9 @@ typedef enum {
 
     ACL_INDIVIDUAL_GET_INFO = 40,
     ACL_INDIVIDUAL_UPDATE_ACE = 41,
-    ACL_INDIVIDUAL_DELETE = 42,
+    ACL_INDIVIDUAL_UPDATE = 42,
+    ACL_INDIVIDUAL_DELETE = 43,
+    ACL_INDIVIDUAL_DELETE_ACE = 44,
 
     ACL_GROUP_CREATE = 50,
     ACL_GROUP_FIND   = 51,
@@ -167,7 +169,9 @@ static void printMenu(OCMode mode)
     printf("** ACL INDIVIDUAL\n");
     printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
     printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
+    printf("** %d - ACL individual update Request\n", ACL_INDIVIDUAL_UPDATE);
     printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
+    printf("** %d - ACL individual delete ACE Request\n", ACL_INDIVIDUAL_DELETE_ACE);
 
     printf("** ACL GROUP MANAGER\n");
     printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
@@ -485,9 +489,15 @@ static void userRequests(void *data)
         case ACL_INDIVIDUAL_UPDATE_ACE:
             res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
             break;
+        case ACL_INDIVIDUAL_UPDATE:
+            res = OCWrapperAclIndividualUpdate(&endPoint, handleCB);
+            break;
         case ACL_INDIVIDUAL_DELETE:
             res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
             break;
+        case ACL_INDIVIDUAL_DELETE_ACE:
+            res = OCWrapperAclIndividualDeleteAce(&endPoint, handleCB);
+            break;
         case CSR_SIGN:
             res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
             break;
index 5031a52..fbb6d8b 100644 (file)
@@ -479,6 +479,72 @@ exit:
     return result;
 }
 
+OCStackResult OCWrapperAclIndividualUpdate(const OCDevAddr *endPoint, OCCloudResponseCB callback)
+{
+    OCStackResult result = OC_STACK_NO_MEMORY;
+
+    char aclid[MAX_ID_LENGTH] = { 0 };
+    readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
+
+    cloudAce_t *ace = OICCalloc(1, sizeof(cloudAce_t));
+    if (!ace)
+    {
+        OIC_LOG(ERROR, TAG, "Can't allocate memory for ace");
+        goto exit;
+    }
+
+    char aceid[MAX_ID_LENGTH] = { 0 };
+    char subjectuuid[MAX_ID_LENGTH] = { 0 };
+    int stype = 0;
+    int permission = 0;
+
+    readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
+    do
+    {
+        readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
+    } while (OC_STACK_OK != ConvertStrToUuid(subjectuuid, &ace->subjectuuid));
+
+    readInteger(&stype, "subject type", "0 – Device, 1 – User, 2 - Group");
+    readInteger(&permission, "permission", "6");
+
+    ace->stype = stype;
+    ace->permission = permission;
+
+    int reslist_count = 0;
+    readInteger(&reslist_count, "resources list count", "1");
+
+    for (int i = 0; i < reslist_count; i++)
+    {
+        OicSecRsrc_t *res = OICCalloc(1, sizeof(OicSecRsrc_t));
+        if (!res)
+        {
+            OIC_LOG(ERROR, TAG, "Can't allocate memory for res");
+            goto exit;
+        }
+        LL_APPEND(ace->resources, res);
+
+        char href[32] = { 0 };
+        readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE);
+
+        stringArray_t rt = {0, 0};
+        readStringArray(&rt, MAX_ID_LENGTH, "resource type", RESOURCE_TYPE_EXAMPLE);
+
+        stringArray_t _if = {0, 0};
+        readStringArray(&_if, MAX_ID_LENGTH, "interface", INTERFACE_EXAMPLE);
+
+        res->href = OICStrdup(href);
+        res->types = rt.array;
+        res->typeLen = rt.length;
+        res->interfaces = _if.array;
+        res->interfaceLen = _if.length;
+    }
+
+
+    result = OCCloudAclIndividualUpdate(NULL, aclid,aceid, ace, endPoint, callback);
+exit:
+    return result;
+}
+
 OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
 {
     char aclid[MAX_ID_LENGTH] = { 0 };
@@ -488,6 +554,17 @@ OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudRes
     return OCCloudAclIndividualDelete(NULL, aclid, endPoint, callback);
 }
 
+OCStackResult OCWrapperAclIndividualDeleteAce(const OCDevAddr *endPoint, OCCloudResponseCB callback)
+{
+    char aclid[MAX_ID_LENGTH] = { 0 };
+    char aceid[MAX_ID_LENGTH] = { 0 };
+
+    readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
+    readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
+
+    return OCCloudAclIndividualDeleteAce(NULL, aclid, aceid, endPoint, callback);
+}
+
 OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
 {
     char gtype[16] = { 0 };
index 26613be..62ba04b 100644 (file)
@@ -104,6 +104,15 @@ OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloud
 OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback);
 
 /**
+ * ACL individual delete ACE
+ *
+ * @param[in] endPoint          cloud host and port
+ * @param[in] callback          result callback
+ * @return  OCStackResult application result
+ */
+OCStackResult OCWrapperAclIndividualDeleteAce(const OCDevAddr *endPoint, OCCloudResponseCB callback);
+
+/**
  * ACL post group request function
  *
  * @param[in] endPoint          cloud host and port
index 58b0ddc..d1fd141 100644 (file)
@@ -349,6 +349,143 @@ no_memory:
     return OC_STACK_NO_MEMORY;
 }
 
+OCStackResult OCCloudAclIndividualUpdate(void* ctx,
+                                            const char *aclId,
+                                            const char *aceId,
+                                            const cloudAce_t *ace,
+                                            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(ace, TAG, "NULL input param", OC_STACK_INVALID_PARAM);
+
+    snprintf(uri, MAX_URI_LENGTH, "%s%s:%d%s/%s", DEFAULT_PREFIX,
+            endPoint->addr, endPoint->port, OC_RSRVD_ACL_ID_URL, aclId);
+
+    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 *tempAce = NULL;
+
+    LL_FOREACH((cloudAce_t*)ace, tempAce)
+    {
+        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(&tempAce->subjectuuid, &uuid))
+        {
+            OIC_LOG(ERROR, TAG, "Can't convert subjectuuid to string");
+        }
+
+        OCRepPayloadSetPropString(payload, OC_RSRVD_ACE_ID, tempAce->aceId);
+        OCRepPayloadSetPropString(payload, OC_RSRVD_SUBJECT_UUID, (const char *)uuid);
+        OCRepPayloadSetPropInt(payload, OC_RSRVD_SUBJECT_TYPE, tempAce->stype);
+        OCRepPayloadSetPropInt(payload, OC_RSRVD_PERMISSION_MASK, tempAce->permission);
+
+        OICFree(uuid);
+
+        int reslist_count = 0;
+        //code below duplicates LL_COUNT, implemented in newer version of utlist.h
+        {
+            OicSecRsrc_t *res = tempAce->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(tempAce->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 +505,26 @@ 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);
+}
+