+static bool UpdatePersistentStorage(const OicSecAcl_t *acl)
+{
+ // Convert ACL data into JSON for update to persistent storage
+ char *jsonStr = BinToAclJSON(acl);
+ if (jsonStr)
+ {
+ cJSON *jsonAcl = cJSON_Parse(jsonStr);
+ OICFree(jsonStr);
+
+ if ((jsonAcl) && (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl)))
+ {
+ return true;
+ }
+ cJSON_Delete(jsonAcl);
+ }
+ return false;
+}
+
+/*
+ * This method removes ACE for the subject and resource from the ACL
+ *
+ * @param subject - subject of the ACE
+ * @param resource - resource of the ACE
+ *
+ * @return
+ * OC_STACK_RESOURCE_DELETED on success
+ * OC_STACK_NO_RESOURC on failure to find the appropriate ACE
+ * OC_STACK_INVALID_PARAM on invalid parameter
+ */
+static OCStackResult RemoveACE(const OicUuid_t * subject,
+ const char * resource)
+{
+ OC_LOG(DEBUG, TAG, "IN RemoveACE");
+
+ OicSecAcl_t *acl = NULL;
+ OicSecAcl_t *tempAcl = NULL;
+ bool deleteFlag = false;
+ OCStackResult ret = OC_STACK_NO_RESOURCE;
+
+ if(memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
+ {
+ OC_LOG_V (ERROR, TAG, "%s received invalid parameter", __func__ );
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ //If resource is NULL then delete all the ACE for the subject.
+ if(NULL == resource || resource[0] == '\0')
+ {
+ LL_FOREACH_SAFE(gAcl, acl, tempAcl)
+ {
+ if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
+ {
+ LL_DELETE(gAcl, acl);
+ FreeACE(acl);
+ deleteFlag = true;
+ }
+ }
+ }
+ else
+ {
+ //Looping through ACL to find the right ACE to delete. If the required resource is the only
+ //resource in the ACE for the subject then delete the whole ACE. If there are more resources
+ //than the required resource in the ACE, for the subject then just delete the resource from
+ //the resource array
+ LL_FOREACH_SAFE(gAcl, acl, tempAcl)
+ {
+ if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
+ {
+ if(1 == acl->resourcesLen && strcmp(acl->resources[0], resource) == 0)
+ {
+ LL_DELETE(gAcl, acl);
+ FreeACE(acl);
+ deleteFlag = true;
+ break;
+ }
+ else
+ {
+ int resPos = -1;
+ size_t i;
+ for(i = 0; i < acl->resourcesLen; i++)
+ {
+ if(strcmp(acl->resources[i], resource) == 0)
+ {
+ resPos = i;
+ break;
+ }
+ }
+ if((0 <= resPos))
+ {
+ OICFree(acl->resources[resPos]);
+ acl->resources[resPos] = NULL;
+ acl->resourcesLen -= 1;
+ for(i = resPos; i < acl->resourcesLen; i++)
+ {
+ acl->resources[i] = acl->resources[i+1];
+ }
+ deleteFlag = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if(deleteFlag)
+ {
+ if(UpdatePersistentStorage(gAcl))
+ {
+ ret = OC_STACK_RESOURCE_DELETED;
+ }
+ }
+ return ret;
+}
+
+/*
+ * This method parses the query string received for REST requests and
+ * retrieves the 'subject' field.
+ *
+ * @param query querystring passed in REST request
+ * @param subject subject UUID parsed from query string
+ *
+ * @return true if query parsed successfully and found 'subject', else false.
+ */
+static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
+{
+ OicParseQueryIter_t parseIter = {.attrPos=NULL};
+
+ ParseQueryIterInit((unsigned char *)query, &parseIter);
+
+
+ while(GetNextQuery(&parseIter))
+ {
+ if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, parseIter.attrLen) == 0)
+ {
+ VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
+ unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+ uint32_t outLen = 0;
+ B64Result b64Ret = B64_OK;
+ b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen, base64Buff,
+ sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, (B64_OK == b64Ret && outLen <= sizeof(subject->id)), ERROR);
+ memcpy(subject->id, base64Buff, outLen);
+
+ return true;
+ }
+ }
+
+exit:
+ return false;
+}
+
+/*
+ * This method parses the query string received for REST requests and
+ * retrieves the 'resource' field.
+ *
+ * @param query querystring passed in REST request
+ * @param resource resource parsed from query string
+ * @param resourceSize size of the memory pointed to resource
+ *
+ * @return true if query parsed successfully and found 'resource', else false.
+ */
+static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
+{
+ OicParseQueryIter_t parseIter = {.attrPos=NULL};
+
+ ParseQueryIterInit((unsigned char *)query, &parseIter);
+
+ while(GetNextQuery(&parseIter))
+ {
+ if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen) == 0)
+ {
+ VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
+ OICStrcpy(resource, resourceSize, (char *)parseIter.valPos);
+
+ return true;
+ }
+ }
+
+exit:
+ return false;
+}
+
+
+