From 1a2e71f9c470c7cc17157f83deb4488ee83050a4 Mon Sep 17 00:00:00 2001 From: Jongmin Choi Date: Thu, 20 Oct 2016 11:03:41 +0900 Subject: [PATCH] Cloud ACE update - APIs added to update Cloud ACE using aclid and acid - aceid input removed from device side update API Patch #1: initial upload Patch #2: update ACE fix Patch #4: Issue fixed related to update ACE and individual ACE update. Also Acl modification Patch #5: Rebased to latest 1.2-rel Patch #7: isValidACE method added and other issue fix Patch #8-9: delete logic fix, getAclACE added, unnecessary code deleted Change-Id: I8b15fe4556536b4af4d597564ccab4cf66c55e44 Signed-off-by: Jongmin Choi Signed-off-by: Sunil Kumar K R Signed-off-by: Jongmin Choi Signed-off-by: Sunil Kumar K R Signed-off-by: Jongmin Choi Reviewed-on: https://gerrit.iotivity.org/gerrit/13049 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh --- .../cloud/accountserver/resources/acl/id/Acl.java | 84 ++++++++++++++++++---- .../accountserver/resources/acl/id/AclManager.java | 26 +++++-- .../resources/acl/id/AclResource.java | 66 +++++++++-------- .../resources/acl/verify/AclVerifyResource.java | 9 +-- .../provisioning/sample/cloud/cloudWrapper.c | 1 - .../provisioning/sample/cloud/cloudWrapper.h | 10 +++ .../csdk/security/provisioning/src/cloud/aclid.c | 25 ++++--- 7 files changed, 153 insertions(+), 68 deletions(-) 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 1adb63a..62dfc3e 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 @@ -148,32 +148,84 @@ public class Acl { @SuppressWarnings("unchecked") - public void addACE(List> aclist) { + public List> addACE(List> aclist) { + Log.v("IN addACE"); + HashMap hashmap = AccountDBManager.getInstance() + .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + if (hashmap == null) { + throw new BadRequestException("aclid is invalid"); + } + List> aclDbList = (List>) hashmap + .get(Constants.REQ_ACL_LIST); + + + ListIterator> iterator = aclist.listIterator(); + while (iterator.hasNext()) { + HashMap aceMap = iterator.next(); + if (aceMap.get(Constants.KEYFIELD_ACE_SUBJECT_ID) + .equals(hashmap.get(Constants.REQ_OWNER_ID))) { + // remove current iterator + iterator.remove(); + continue; + } + aceMap.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString()); + } + + List> newAcList = new ArrayList>( + aclist); + if (aclDbList != null) { + newAcList.addAll(aclDbList); + } + hashmap.put(Constants.REQ_ACL_LIST, newAcList); + AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, + hashmap); + notifyToSubscriber(getResponsePayload(true)); + Log.v("OUT addACE"); + return aclist; + } + + public HashMap getACE(String aceid) { HashMap hashmap = AccountDBManager.getInstance() .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + if (hashmap == null) { + throw new BadRequestException("aclid is invalid"); + } List> aclDbList = (List>) hashmap .get(Constants.REQ_ACL_LIST); - - - for(HashMap ace : aclist) { - ace.put(Constants.REQ_ACE_ID, UUID.randomUUID().toString()); + ListIterator> iterator = aclDbList + .listIterator(); + while (iterator.hasNext()) { + HashMap aceMap = iterator.next(); + if (aceMap.get(Constants.REQ_ACE_ID).equals(aceid)) { + // Return the current element from the iterator + return aceMap; + } + } + throw new BadRequestException("aceid is invalid"); + } + public boolean isValidAceId(String aceid) { + HashMap hashmap = AccountDBManager.getInstance() + .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); + if (hashmap == null) { + return false; } - List> newAcList = new ArrayList>( - aclist); - - if (aclDbList != null) { - newAcList.addAll(aclDbList); + 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)) { + return true; + } } - hashmap.put(Constants.REQ_ACL_LIST, newAcList); - AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, - hashmap); - notifyToSubscriber(getResponsePayload(true)); + return false; } - public void updateACE(String aceid, HashMap ace) { + Log.v("IN updateACE"); HashMap hashmap = AccountDBManager.getInstance() .selectRecord(Constants.ACL_TABLE, getCondition()).get(0); @@ -195,6 +247,8 @@ public class Acl { hashmap.put(Constants.REQ_ACL_LIST, aclDbList); AccountDBManager.getInstance().updateRecord(Constants.ACL_TABLE, hashmap); notifyToSubscriber(getResponsePayload(true)); + Log.v("OUT updateACE"); + } public void deleteACE(String aceid) { 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 f974aaf..081315f 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 @@ -87,16 +87,34 @@ public class AclManager { mAcls.remove(aclid); } - public void addAclACE(String aclid, List> aclist) { - getAcl(aclid).addACE(aclist); + public List> addAclACE(String aclid, List> aclist) { + return getAcl(aclid).addACE(aclist); + } + + public HashMap getAclACE(String aclid, String aceid) { + return getAcl(aclid).getACE(aceid); } public void updateACE(String aclid, String aceid, HashMap ace) { - getAcl(aclid).updateACE(aceid, ace); + if(getAcl(aclid).isValidAceId(aceid)) + { + getAcl(aclid).updateACE(aceid, ace); + } + else + { + throw new BadRequestException("Invalid parameters"); + } } public void deleteAclACE(String aclid, String aceid) { - getAcl(aclid).deleteACE(aceid); + if(getAcl(aclid).isValidAceId(aceid)) + { + getAcl(aclid).deleteACE(aceid); + } + else + { + throw new BadRequestException("Invalid parameters"); + } } 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 c741468..7ad3516 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 @@ -86,40 +86,37 @@ public class AclResource extends Resource { } private IResponse handlePostRequest(IRequest request) - throws ServerException { + throws ServerException { - HashMap payloadData = mCbor + HashMap payloadData = mCbor .parsePayloadFromCbor(request.getPayload(), HashMap.class); - if (!getUriPathSegments().containsAll(request.getUriPathSegments())) { - String aclid = request.getUriPathSegments() - .get(getUriPathSegments().size()); - - List> aclist = null; - - checkPayloadException(Constants.REQ_ACL_LIST, payloadData); - - aclist = (List>) payloadData + if (null !=request.getUriQueryMap()) { + String aclid = request.getUriPathSegments().get(getUriPathSegments().size()); + String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID).get(0); + List> aclist = (List>) payloadData .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 + mAclManager.updateACE(aclid, aceid, aclist.get(0)); + return MessageBuilder.createResponse(request, ResponseStatus.CHANGED); + } + else if (!getUriPathSegments().containsAll(request.getUriPathSegments())) { + String aclid = request.getUriPathSegments().get(getUriPathSegments().size()); + + List> aclist = null; + if (!payloadData.containsKey(Constants.REQ_ACL_LIST)) { + throw new BadRequestException("aclist not included in payload"); + } + aclist = (List>) payloadData .get(Constants.REQ_ACL_LIST); - mAclManager.updateACE(aclid, aceid, ace); - return MessageBuilder.createResponse(request, - ResponseStatus.CHANGED); + aclist= mAclManager.addAclACE(aclid, aclist); + payloadData.put(Constants.REQ_ACL_LIST, aclist); + return MessageBuilder.createResponse(request, ResponseStatus.CHANGED, + ContentFormat.APPLICATION_CBOR, + mCbor.encodingPayloadToCbor(payloadData)); + } + throw new BadRequestException("uriPath is invalid"); } - throw new BadRequestException("uriPath is invalid"); - - } @SuppressWarnings("unchecked") @@ -181,13 +178,20 @@ public class AclResource extends Resource { } else { aclid = request.getUriPathSegments() .get(getUriPathSegments().size()); - String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID) - .get(0); - if (aceid == null) { + + if (request.getUriQueryMap() == null) + { mAclManager.deleteAclAclist(aclid); - } else { + } + else if (request.getUriQueryMap() + .containsKey(Constants.REQ_ACE_ID)) { + String aceid = request.getUriQueryMap().get(Constants.REQ_ACE_ID) + .get(0); mAclManager.deleteAclACE(aclid, aceid); } + else { + throw new BadRequestException("uriPath is invalid"); + } } 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 87cb960..0ad3011 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 @@ -72,7 +72,7 @@ public class AclVerifyResource extends Resource { private boolean checkResourceUri(List aceResources, String uri) throws ServerException { for (AceResource aceResource : aceResources) { - if (aceResource.getHref().equals(uri)) { + if (aceResource.getHref().trim().equals("*") || aceResource.getHref().equals(uri)) { return true; } } @@ -97,12 +97,13 @@ public class AclVerifyResource extends Resource { for (HashMap eachAclMap : aclResult) { AclTable aclTable = Acl.convertMaptoAclObject(eachAclMap); - if (aclTable.getAclist() == null) { - return false; - } if (aclTable.getOid().equals(sid)) { return true; } + if (aclTable.getAclist() == null) { + return false; + } + for (Ace ace : aclTable.getAclist()) { if (ace.getSubjectuuid().equals(sid)) { // check permission matches diff --git a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c index fbb6d8b..4c1b565 100644 --- a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c +++ b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c @@ -430,7 +430,6 @@ OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloud int stype = 0; int permission = 0; - readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE); do { readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE); diff --git a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h index 62ba04b..1df22cb 100644 --- a/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h +++ b/resource/csdk/security/provisioning/sample/cloud/cloudWrapper.h @@ -95,6 +95,16 @@ OCStackResult OCWrapperAclIndividualGetInfo(const OCDevAddr *endPoint, OCCloudRe OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback); /** + * ACL individual update. Replaces an existing ACE with a new one + * + * @param[in] endPoint cloud host and port + * @param[in] callback result callback + * @return OCStackResult application result + */ + +OCStackResult OCWrapperAclIndividualUpdate(const OCDevAddr *endPoint, OCCloudResponseCB callback); + +/** * ACL individual delete * * @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 d1fd141..6c0fa4c 100644 --- a/resource/csdk/security/provisioning/src/cloud/aclid.c +++ b/resource/csdk/security/provisioning/src/cloud/aclid.c @@ -271,7 +271,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); @@ -352,7 +351,7 @@ no_memory: OCStackResult OCCloudAclIndividualUpdate(void* ctx, const char *aclId, const char *aceId, - const cloudAce_t *ace, + const cloudAce_t *aces, const OCDevAddr *endPoint, OCCloudResponseCB callback) { @@ -366,10 +365,11 @@ OCStackResult OCCloudAclIndividualUpdate(void* ctx, 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); + VERIFY_NON_NULL_RET(aces, 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); + 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) @@ -388,9 +388,9 @@ OCStackResult OCCloudAclIndividualUpdate(void* ctx, } i = 0; - cloudAce_t *tempAce = NULL; + cloudAce_t *ace = NULL; - LL_FOREACH((cloudAce_t*)ace, tempAce) + LL_FOREACH((cloudAce_t*)aces, ace) { OCRepPayload *payload = OCRepPayloadCreate(); if (!payload) @@ -401,22 +401,21 @@ OCStackResult OCCloudAclIndividualUpdate(void* ctx, helperPayload[i++] = payload; char *uuid = NULL; - if (OC_STACK_OK != ConvertUuidToStr(&tempAce->subjectuuid, &uuid)) + if (OC_STACK_OK != ConvertUuidToStr(&ace->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); + 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 = tempAce->resources; + OicSecRsrc_t *res = ace->resources; while (res) { res = res->next; @@ -433,7 +432,7 @@ OCStackResult OCCloudAclIndividualUpdate(void* ctx, j = 0; OicSecRsrc_t *res = NULL; - LL_FOREACH(tempAce->resources, res) + LL_FOREACH(ace->resources, res) { OCRepPayload *payload = OCRepPayloadCreate(); if (!payload) -- 2.7.4