Added new function in EntityHandler to parse and validate query string.
authorMoumita Ray <moumita.ray@intel.com>
Tue, 28 Apr 2015 21:14:54 +0000 (14:14 -0700)
committerErich Keane <erich.keane@intel.com>
Tue, 5 May 2015 18:07:49 +0000 (18:07 +0000)
IOT-491: When client creates a resource and calls GET  with different
resource type name and interface,GET should fail but it is successful.
Analysis: Since APP creates resource, it should know the
resource/interface types and it should check for resourceTypeName
and ResourceInterface to identify a known resource prior to handle
entity Request.

Change-Id: I9159b465bf708a4cb5835f4b3adf0aea3a2c87bb
Signed-off-by: Moumita Ray <moumita.ray@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/860
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Erich Keane <erich.keane@intel.com>
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.h
resource/examples/simpleserver.cpp

index 1040fc3..f133925 100644 (file)
@@ -80,6 +80,11 @@ const char *platformVersion = "myPlatformVersion";
 const char *supportUrl = "mySupportUrl";
 const char *version = "myVersion";
 
+// Entity handler should check for resourceTypeName and ResourceInterface in order to GET
+// the existence of a known resource
+const char *resourceTypeName = "core.light";
+const char *resourceInterface = "oc.mi.def";
+
 OCDeviceInfo deviceInfo;
 
 //This function takes the request as an input and returns the response
@@ -169,10 +174,53 @@ bool checkIfQueryForPowerPassed(char * query)
     return true;
 }
 
+/* This method check the validity of resourceTypeName and resource interfaces
+ * Entity Handler has to parse the query string in order to process it
+ */
+
+OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest)
+{
+    bool resourceList = true;
+    uint8_t resourceIndex = 0;
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OC_LOG (ERROR, TAG, "Invalid request pointer");
+        return ehResult;
+    }
+    //Added check for resource type & interface in server entity handle
+
+    while(resourceList)
+    {
+        const char* typeName = OCGetResourceTypeName(entityHandlerRequest->resource,
+                                                      resourceIndex);
+        const char* interfaceName = OCGetResourceInterfaceName(entityHandlerRequest->resource,
+                                                                resourceIndex);
+        if(typeName && interfaceName)
+        {
+            if(strcmp(typeName,resourceTypeName) == 0 &&
+               strcmp(interfaceName,resourceInterface) == 0)
+            {
+                ehResult = OC_EH_OK;
+                break;
+            }
+            resourceIndex++;
+        }
+        else
+        {
+            resourceList = false;
+        }
+    }
+    return ehResult;
+}
+
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
         char *payload, uint16_t maxPayloadSize)
 {
     OCEntityHandlerResult ehResult;
+    char *getResp = constructJsonResponse(ehRequest);
 
     bool queryPassed = checkIfQueryForPowerPassed(ehRequest->query);
 
@@ -462,7 +510,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
 {
     OC_LOG_V (INFO, TAG, "Inside device default entity handler - flags: 0x%x, uri: %s", flag, uri);
 
-    OCEntityHandlerResult ehResult = OC_EH_OK;
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
     OCEntityHandlerResponse response;
     char payload[MAX_RESPONSE_LENGTH] = {0};
 
@@ -472,13 +520,17 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         OC_LOG (ERROR, TAG, "Invalid request pointer");
         return OC_EH_ERROR;
     }
-
     // Initialize certain response fields
     response.numSendVendorSpecificHeaderOptions = 0;
     memset(response.sendVendorSpecificHeaderOptions, 0,
             sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
 
+    // Entity handler to check the validity of resourceTypeName and resource interfaces
+    // It is Entity handler's responsibility to keep track of the list of resources prior to call
+    // Requested method
+    ehResult = ValidateQueryParams(entityHandlerRequest);
+
     if (flag & OC_INIT_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
@@ -486,34 +538,43 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
     if (flag & OC_REQUEST_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
-        if (entityHandlerRequest->resource == NULL)
+        // Entity handler to check the validity of resourceType and resource interface
+        if( ehResult == OC_EH_OK )
         {
-            OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
-            ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest,
-                    payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_GET == entityHandlerRequest->method)
-        {
-            OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_PUT == entityHandlerRequest->method)
-        {
-            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-            ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_DELETE == entityHandlerRequest->method)
-        {
-            OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
-            ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            if (entityHandlerRequest->resource == NULL)
+            {
+                OC_LOG (INFO, TAG, "Received request from client to a non-existing resource");
+                ehResult = ProcessNonExistingResourceRequest(entityHandlerRequest,
+                               payload, sizeof(payload) - 1);
+            }
+            else if (OC_REST_GET == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+                ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else if (OC_REST_PUT == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+                ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else if (OC_REST_DELETE == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
+                ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else
+            {
+                OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+                          entityHandlerRequest->method);
+                ehResult = OC_EH_ERROR;
+            }
         }
         else
         {
-            OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
-                    entityHandlerRequest->method);
-            ehResult = OC_EH_ERROR;
+            OC_LOG_V (INFO, TAG,
+                      "Invalid ResourceInterface Type & Name received from client for method: %d ",
+                      entityHandlerRequest->method);
         }
-
         // If the result isn't an error or forbidden, send response
         if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
         {
@@ -582,6 +643,12 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
             0, sizeof response.sendVendorSpecificHeaderOptions);
     memset(response.resourceUri, 0, sizeof response.resourceUri);
 
+    // Entity handler to check the validity of resourceTypeName and resource interfaces
+    // It is Entity handler's responsibility to keep track of the list of resources prior to call
+    // Requested method
+
+    ehResult = ValidateQueryParams(entityHandlerRequest);
+
     if (flag & OC_INIT_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_INIT_FLAG");
@@ -589,33 +656,44 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
     if (flag & OC_REQUEST_FLAG)
     {
         OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
-        if (OC_REST_GET == entityHandlerRequest->method)
-        {
-            OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
-            ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_PUT == entityHandlerRequest->method)
-        {
-            OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
-            ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_POST == entityHandlerRequest->method)
-        {
-            OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
-            ehResult = ProcessPostRequest (entityHandlerRequest,
-                    &response, payload, sizeof(payload) - 1);
-        }
-        else if (OC_REST_DELETE == entityHandlerRequest->method)
+
+        // Entity handler to check the validity of resourceType and resource interface
+        // Entity handler to check the validity of resourceType and resource interface
+        if(ehResult == OC_EH_OK)
         {
-            OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
-            ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            if (OC_REST_GET == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+                ehResult = ProcessGetRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else if (OC_REST_PUT == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+                ehResult = ProcessPutRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else if (OC_REST_POST == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, payload, sizeof(payload) - 1);
+            }
+            else if (OC_REST_DELETE == entityHandlerRequest->method)
+            {
+                OC_LOG (INFO, TAG, "Received OC_REST_DELETE from client");
+                ehResult = ProcessDeleteRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else
+            {
+                OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+                          entityHandlerRequest->method);
+                ehResult = OC_EH_ERROR;
+            }
         }
         else
         {
-            OC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
-                    entityHandlerRequest->method);
+            OC_LOG_V (INFO, TAG,
+                      "Invalid ResourceInterface Type & Name received from client for method: %d ",
+                      entityHandlerRequest->method);
         }
-
         // If the result isn't an error or forbidden, send response
         if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
         {
@@ -791,7 +869,7 @@ void *presenceNotificationGenerator(void *param)
             sleep(1);
             res = OCCreateResource(&presenceNotificationHandles[i],
                     presenceNotificationResources.at(i).c_str(),
-                    "oc.mi.def",
+                    resourceInterface,
                     presenceNotificationUris.at(i).c_str(),
                     OCNOPEntityHandlerCb,
                     OC_DISCOVERABLE|OC_OBSERVABLE);
@@ -962,8 +1040,8 @@ int createLightResource (char *uri, LightResource *lightResource)
     lightResource->state = false;
     lightResource->power= 0;
     OCStackResult res = OCCreateResource(&(lightResource->handle),
-            "core.light",
-            "oc.mi.def",
+            resourceTypeName,
+            resourceInterface,
             uri,
             OCEntityHandlerCb,
             OC_DISCOVERABLE|OC_OBSERVABLE);
index ea6ca50..e6d123e 100644 (file)
@@ -70,6 +70,11 @@ char* constructJsonResponse (OCEntityHandlerRequest *ehRequest);
  */
 void *ChangeLightRepresentation (void *param);
 
+/* This method check the validity of resourceTypeName and resource interfaces
+ * Entity Handler has to parse the query string in order to process it
+ */
+OCEntityHandlerResult ValidateQueryParams (OCEntityHandlerRequest *entityHandlerRequest);
+
 /* Following methods process the PUT, GET, POST, Delete,
  * & Observe requests */
 OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
index f1a1e28..4b04f3a 100644 (file)
@@ -53,6 +53,11 @@ bool isSecure = false;
 /// Specifies whether Entity handler is going to do slow response or not
 bool isSlowResponse = false;
 
+// Entity handler should check for resourceTypeName and ResourceInterface in order to GET
+// the existence of a known resource
+const std::string resourceTypeLight = "core.light";
+const std::string resourceInterfaceDefault = DEFAULT_INTERFACE;
+
 // Forward declaring the entityHandler
 
 /// This class represents a single resource named 'lightResource'. This resource has
@@ -90,9 +95,12 @@ public:
     /// This function internally calls registerResource API.
     void createResource()
     {
-        std::string resourceURI = m_lightUri; //URI of the resource
-        std::string resourceTypeName = "core.light"; //resource type name. In this case, it is light
-        std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+        //URI of the resource
+        std::string resourceURI = m_lightUri;
+        //resource type name. In this case, it is light
+        std::string resourceTypeName = resourceTypeLight;
+        // resource interface.
+        std::string resourceInterface = resourceInterfaceDefault;
 
         // OCResourceProperty is defined ocstack.h
         uint8_t resourceProperty;
@@ -119,9 +127,12 @@ public:
 
     OCStackResult createResource1()
     {
-        std::string resourceURI = "/a/light1"; // URI of the resource
-        std::string resourceTypeName = "core.light"; // resource type name. In this case, it is light
-        std::string resourceInterface = DEFAULT_INTERFACE; // resource interface.
+        // URI of the resource
+        std::string resourceURI = "/a/light1";
+        // resource type name. In this case, it is light
+        std::string resourceTypeName = resourceTypeLight;
+        // resource interface.
+        std::string resourceInterface = resourceInterfaceDefault;
 
         // OCResourceProperty is defined ocstack.h
         uint8_t resourceProperty;
@@ -259,7 +270,6 @@ OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
         if(requestFlag & RequestHandlerFlag::InitFlag)
         {
             cout << "\t\trequestFlag : Init\n";
-
             // entity handler to perform resource initialization operations
         }
         if(requestFlag & RequestHandlerFlag::RequestFlag)
@@ -269,8 +279,43 @@ OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
             pResponse->setRequestHandle(request->getRequestHandle());
             pResponse->setResourceHandle(request->getResourceHandle());
 
+            // Check for query params (if any)
+            QueryParamsMap queryParamsMap = request->getQueryParameters();
+
+            // Entity handler to check the validity of resourceTypeName and resource interfaces
+            // It is Entity handler's responsibility to keep track of the list of resources prior to call
+            // Requested method
+
+            std::string interfaceName;
+            std::string typeName;
+
+            cout << "\t\t\tquery params: \n";
+
+            for(auto it : queryParamsMap)
+            {
+                cout << "\t\t\t\t" << it.first << ":" << it.second << endl;
+                std::string firstQuery = it.first;
+                if(firstQuery.find_first_of("if") == 0)
+                {
+                    interfaceName = it.second;
+                }
+                else if(firstQuery.find_first_of("rt") == 0 )
+                {
+                    typeName = it.second;
+                }
+            }
+            if(typeName.compare(resourceTypeLight) == 0 &&
+                interfaceName.compare(resourceInterfaceDefault) == 0)
+            {
+                ehResult = OC_EH_OK;
+            }
+            else
+            {
+                cout<< "\t\t Invalid ResourceInterface Type & Name received from Client"<<endl;
+            }
+
             // If the request type is GET
-            if(requestType == "GET")
+            if(requestType == "GET" && ehResult == OC_EH_OK)
             {
                 cout << "\t\t\trequestType : GET\n";
                 if(isSlowResponse) // Slow response case
@@ -295,7 +340,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
                     }
                 }
             }
-            else if(requestType == "PUT")
+            else if(requestType == "PUT" && ehResult == OC_EH_OK)
             {
                 cout << "\t\t\trequestType : PUT\n";
                 OCRepresentation rep = request->getResourceRepresentation();
@@ -311,7 +356,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
                     ehResult = OC_EH_OK;
                 }
             }
-            else if(requestType == "POST")
+            else if(requestType == "POST" && ehResult == OC_EH_OK)
             {
                 cout << "\t\t\trequestType : POST\n";
 
@@ -336,7 +381,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
                     ehResult = OC_EH_OK;
                 }
             }
-            else if(requestType == "DELETE")
+            else if(requestType == "DELETE" && ehResult == OC_EH_OK)
             {
                 // DELETE request operations
             }
@@ -551,4 +596,3 @@ int main(int argc, char* argv[])
 
     return 0;
 }
-