Commit e7781287 authored by Andrii Shtompel's avatar Andrii Shtompel Committed by Randeep

[IOT-2465] Fix DELETE request impl for cred

Verified using CTT 1.5.11 test CT1.7.9.3
DELETE delete all credentials return PASSED

Change-Id: Ie52c6af9fb9205a650b766acf0084e0ac2dcdcf1
Signed-off-by: default avatarAndrii Shtompel <a.shtompel@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/21403Reviewed-by: Aleksey's avatarAleksey Volkov <a.volkov@samsung.com>
Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Nathan Heldt-Sheller's avatarNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Reviewed-by: default avatarOleksii Beketov <ol.beketov@samsung.com>
Reviewed-by: Randeep's avatarRandeep Singh <randeep.s@samsung.com>
parent 4fc4eb48
......@@ -100,6 +100,29 @@ typedef enum CredCompareResult{
CRED_CMP_ERROR = 2
}CredCompareResult_t;
typedef struct CredIdList CredIdList_t;
struct CredIdList
{
uint16_t credId;
CredIdList_t *next;
};
static void DeleteCredIdList(CredIdList_t** list)
{
if (list)
{
CredIdList_t *head = *list;
while (head)
{
CredIdList_t *tmp = head->next;
OICFree(head);
head = tmp;
}
}
}
static bool ValueWithinBounds(uint64_t value, uint64_t maxValue)
{
if (value > maxValue)
......@@ -1838,7 +1861,7 @@ exit:
OCStackResult RemoveCredential(const OicUuid_t *subject)
{
OCStackResult ret = OC_STACK_RESOURCE_DELETED;
OCStackResult ret = OC_STACK_ERROR;
OicSecCred_t *cred = NULL;
OicSecCred_t *tempCred = NULL;
bool deleteFlag = false;
......@@ -1855,13 +1878,12 @@ OCStackResult RemoveCredential(const OicUuid_t *subject)
if (deleteFlag)
{
if (!UpdatePersistentStorage(gCred))
if (UpdatePersistentStorage(gCred))
{
ret = OC_STACK_ERROR;
ret = OC_STACK_RESOURCE_DELETED;
}
}
return ret;
}
OCStackResult RemoveCredentialByCredId(uint16_t credId)
......@@ -1901,7 +1923,115 @@ OCStackResult RemoveCredentialByCredId(uint16_t credId)
OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredId");
return ret;
}
/**
* This method removes cred's corresponding to given list of credid's from the Cred
*
* @param credid's of the Cred
*
* @return
* ::OC_STACK_RESOURCE_DELETED on success
* ::OC_STACK_NO_RESOURCE on failure to find the appropriate Cred
* ::OC_STACK_INVALID_PARAM on invalid parameter
*/
static OCStackResult RemoveCredentialByCredIds(CredIdList_t *credIdList)
{
OCStackResult ret = OC_STACK_ERROR;
OicSecCred_t *cred = NULL;
OicSecCred_t *tempCred = NULL;
CredIdList_t *credIdElem = NULL;
bool deleteFlag = false;
OIC_LOG(INFO, TAG, "IN RemoveCredentialByCredIds");
LL_FOREACH(credIdList, credIdElem)
{
LL_FOREACH_SAFE(gCred, cred, tempCred)
{
if (cred->credId == credIdElem->credId)
{
OIC_LOG_V(DEBUG, TAG, "Credential(ID=%d) will be removed.", cred->credId);
LL_DELETE(gCred, cred);
FreeCred(cred);
deleteFlag = true;
//TODO: add break when cred's will have unique credid (during IOT-2464 fix)
}
}
}
if (deleteFlag)
{
if (UpdatePersistentStorage(gCred))
{
ret = OC_STACK_RESOURCE_DELETED;
}
}
OIC_LOG(INFO, TAG, "OUT RemoveCredentialByCredIds");
return ret;
}
/**
* This method parses the query string received for REST requests and
* retrieves the 'credid' field.
*
* @param query querystring passed in REST request
* @param credid cred id parsed from query string
*
* @return true if query parsed successfully and found 'credid', else false.
*/
static bool GetCredIdsFromQueryString(const char *query, CredIdList_t **credid)
{
bool found = false;
OicParseQueryIter_t parseIter = { .attrPos = NULL };
ParseQueryIterInit((unsigned char *) query, &parseIter);
while (GetNextQuery (&parseIter))
{
if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_CREDID_NAME, parseIter.attrLen) == 0)
{
VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
//parse credid array value in format "1,2,3"
unsigned char *str = parseIter.valPos;
//remember last symbol (may be '\0' or '&')
unsigned char tmp = str[parseIter.valLen];
//set last symbol to '\0' to use strtok_r
str[parseIter.valLen] = '\0';
char *saveptr = NULL;
for (; ; str = NULL)
{
char *token = strtok_r((char *)str, ",", &saveptr);
if (NULL == token)
{
break;
}
CredIdList_t *newCredIdElem = (CredIdList_t *) OICCalloc(1, sizeof(CredIdList_t));
if (NULL == newCredIdElem)
{
OIC_LOG(ERROR, TAG, "Failed to allocate CredIdList_t element");
break;
}
newCredIdElem->credId = (uint16_t)atoi(token);
LL_PREPEND(*credid, newCredIdElem);
found = true;
}
//restore last symbol
parseIter.valPos[parseIter.valLen] = tmp;
}
}
exit:
return found;
}
/**
......@@ -1911,7 +2041,7 @@ OCStackResult RemoveCredentialByCredId(uint16_t credId)
* OC_STACK_OK - no errors
* OC_STACK_ERROR - stack process error
*/
OCStackResult RemoveAllCredentials(void)
static OCStackResult RemoveAllCredentials()
{
DeleteCredList(gCred);
gCred = GetCredDefault();
......@@ -1923,6 +2053,41 @@ OCStackResult RemoveAllCredentials(void)
return OC_STACK_OK;
}
/**
* This method parses the query string received for REST requests and
* retrieves the 'subjectuuid' 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_SUBJECTID_NAME, parseIter.attrLen) == 0)
{
VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
//temporary set '\0' symbol instead of copy string
char tmp = parseIter.valPos[parseIter.valLen];
parseIter.valPos[parseIter.valLen] = '\0';
OCStackResult res = ConvertStrToUuid((const char*)parseIter.valPos, subject);
parseIter.valPos[parseIter.valLen] = tmp;
VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
return true;
}
}
exit:
return false;
}
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
/**
* Internal function to fill private data of owner PSK.
......@@ -2401,35 +2566,40 @@ static OCEntityHandlerResult HandleDeleteRequest(const OCEntityHandlerRequest *e
OIC_LOG(DEBUG, TAG, "Processing CredDeleteRequest");
OCEntityHandlerResult ehRet = OC_EH_ERROR;
CredIdList_t *credIdList = NULL;
OicUuid_t subject = { .id= { 0 } };
if (NULL == ehRequest->query)
{
return ehRet;
}
OicParseQueryIter_t parseIter = { .attrPos=NULL };
OicUuid_t subject = {.id={0}};
//Parsing REST query to get the subject
ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
while (GetNextQuery(&parseIter))
if (GetCredIdsFromQueryString(ehRequest->query, &credIdList))
{
if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
parseIter.attrLen) == 0)
if (OC_STACK_RESOURCE_DELETED == RemoveCredentialByCredIds(credIdList))
{
OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
ehRet = OC_EH_RESOURCE_DELETED;
}
DeleteCredIdList(&credIdList);
}
if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
else if (GetSubjectFromQueryString(ehRequest->query, &subject))
{
ehRet = OC_EH_RESOURCE_DELETED;
if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
{
ehRet = OC_EH_RESOURCE_DELETED;
}
}
else
{
if (OC_STACK_OK == RemoveAllCredentials())
{
ehRet = OC_EH_RESOURCE_DELETED;
}
}
//Send response to request originator
ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
OC_EH_OK : OC_EH_ERROR;
exit:
return ehRet;
}
......@@ -2451,7 +2621,7 @@ OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
switch (ehRequest->method)
{
case OC_REST_GET:
ret = HandleGetRequest(ehRequest);;
ret = HandleGetRequest(ehRequest);
break;
case OC_REST_PUT:
case OC_REST_POST:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment