From: Jongmin Choi Date: Wed, 5 Oct 2016 11:47:38 +0000 (+0900) Subject: Cloud ACL Modifications X-Git-Tag: 1.2.0+RC4~86 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6c08489dfc353cb854f2d04c4648108c04d114b6;p=platform%2Fupstream%2Fiotivity.git Cloud ACL Modifications 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 Change-Id: I6b3b4c68f06c43ce002df36a741ea4eb8549ba44 Signed-off-by: Jongmin Choi Reviewed-on: https://gerrit.iotivity.org/gerrit/12739 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh --- diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java index c7c9757..1adb63a 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/Acl.java @@ -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> aclDbList = (List>) hashmap .get(Constants.REQ_ACL_LIST); + + for(HashMap ace : aclist) { + ace.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString()); + } + List> newAcList = new ArrayList>( aclist); @@ -166,6 +173,55 @@ public class Acl { notifyToSubscriber(getResponsePayload(true)); } + public void updateACE(String aceid, HashMap ace) { + + HashMap hashmap = AccountDBManager.getInstance() + .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + + List> aclDbList = (List>) hashmap.get(Constants.REQ_ACL_LIST); + + ace.put(Constants.REQ_ACE_ID, aceid); + + ListIterator> iterator = aclDbList.listIterator(); + while (iterator.hasNext()) { + HashMap 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 hashmap = AccountDBManager.getInstance() + .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + + List> aclDbList = (List>) hashmap + .get(Constants.REQ_ACL_LIST); + + + ListIterator> iterator = aclDbList.listIterator(); + while (iterator.hasNext()) { + HashMap 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); diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java index 701ca80..f974aaf 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclManager.java @@ -91,7 +91,14 @@ public class AclManager { getAcl(aclid).addACE(aclist); } - public void deleteAclACE(String aclid) { + public void updateACE(String aclid, String aceid, HashMap 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(); } diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java index dd2a920..c9f9c51 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/id/AclResource.java @@ -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 ace = (HashMap) 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); diff --git a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java index 3682b7a..87cb960 100644 --- a/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java +++ b/cloud/account/src/main/java/org/iotivity/cloud/accountserver/resources/acl/verify/AclVerifyResource.java @@ -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 diff --git a/resource/csdk/security/provisioning/include/cloud/occloudprovisioning.h b/resource/csdk/security/provisioning/include/cloud/occloudprovisioning.h index 4f8ccfd..6e2da24 100644 --- a/resource/csdk/security/provisioning/include/cloud/occloudprovisioning.h +++ b/resource/csdk/security/provisioning/include/cloud/occloudprovisioning.h @@ -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 diff --git a/resource/csdk/security/provisioning/sample/cloud/cloudCommon.c b/resource/csdk/security/provisioning/sample/cloud/cloudCommon.c index 6add1c0..360ba42 100644 --- a/resource/csdk/security/provisioning/sample/cloud/cloudCommon.c +++ b/resource/csdk/security/provisioning/sample/cloud/cloudCommon.c @@ -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; diff --git a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c index 5031a52..fbb6d8b 100644 --- a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c +++ b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c @@ -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 }; diff --git a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h index 26613be..62ba04b 100644 --- a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h +++ b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h @@ -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 diff --git a/resource/csdk/security/provisioning/src/cloud/aclid.c b/resource/csdk/security/provisioning/src/cloud/aclid.c index 58b0ddc..d1fd141 100644 --- a/resource/csdk/security/provisioning/src/cloud/aclid.c +++ b/resource/csdk/security/provisioning/src/cloud/aclid.c @@ -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); +} +