Add "accessToken" and "acceessTokenType" property in cloudserver resource.
authorJihun Ha <jihun.ha@samsung.com>
Wed, 14 Dec 2016 08:27:51 +0000 (17:27 +0900)
committerUze Choi <uzchoi@samsung.com>
Thu, 15 Dec 2016 02:47:00 +0000 (02:47 +0000)
Rather than authCode, some of IoT Cloud servers may use an access token for
enrollee to do sign-up. For example, after a mediator got issued
an auth code from account server, it can send a request to change it
to its corresponding access token which is going to deliver to Enrollee.
Additionally, AccessTokenType property is added, which indicates ,for example,
an given access token is "bearer" type token.

Change-Id: I6feb2b4f1582b5c9ee9b104b3592267247f97f99
Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/15657
Reviewed-by: Heewon Park <h_w.park@samsung.com>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
service/easy-setup/enrollee/inc/ESEnrolleeCommon.h
service/easy-setup/enrollee/src/resourcehandler.c
service/easy-setup/enrollee/src/resourcehandler.h
service/easy-setup/inc/escommon.h
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/CloudProp.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/ESConstants.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/OAUTH_TOKENTYPE.java [new file with mode: 0755]
service/easy-setup/mediator/richsdk/inc/ESRichCommon.h
service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp
service/easy-setup/sampleapp/enrollee/linux/enrolleewifi.c
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp

index 41f1902..99cce50 100755 (executable)
@@ -58,6 +58,8 @@ typedef struct
 typedef struct
 {
     char authCode[OIC_STRING_MAX_VALUE];        /**< Auth code issued by OAuth2.0-compatible account server **/
+    char accessToken[OIC_STRING_MAX_VALUE];     /**< Access token resolved with an auth code **/
+    OAUTH_TOKENTYPE accessTokenType;            /**< Access token type **/
     char authProvider[OIC_STRING_MAX_VALUE];    /**< Auth provider ID **/
     char ciServer[OIC_STRING_MAX_VALUE];        /**< Cloud interface server URL which an Enrollee is going to registered **/
     void *userdata;                             /**< Vender-specific data**/
index 450e626..e45bcb2 100755 (executable)
@@ -225,6 +225,8 @@ OCStackResult initCloudServerResource(bool isSecured)
     OCStackResult res = OC_STACK_ERROR;
 
     OICStrcpy(gCloudResource.authCode, sizeof(gCloudResource.authCode), "");
+    OICStrcpy(gCloudResource.accessToken, sizeof(gCloudResource.accessToken), "");
+    gCloudResource.accessTokenType = NONE_OAUTH_TOKENTYPE;
     OICStrcpy(gCloudResource.authProvider, sizeof(gCloudResource.authProvider), "");
     OICStrcpy(gCloudResource.ciServer, sizeof(gCloudResource.ciServer), "");
 
@@ -379,6 +381,8 @@ void updateCloudResource(OCRepPayload* input)
     }
 
     memset(cloudData->authCode, 0, OIC_STRING_MAX_VALUE);
+    memset(cloudData->accessToken, 0, OIC_STRING_MAX_VALUE);
+    gCloudResource.accessTokenType = NONE_OAUTH_TOKENTYPE;
     memset(cloudData->authProvider, 0, OIC_STRING_MAX_VALUE);
     memset(cloudData->ciServer, 0, OIC_STRING_MAX_VALUE);
     cloudData->userdata = NULL;
@@ -391,6 +395,22 @@ void updateCloudResource(OCRepPayload* input)
         OIC_LOG_V(INFO, ES_RH_TAG, "gCloudResource.authCode %s", gCloudResource.authCode);
     }
 
+    char *accessToken = NULL;
+    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_ACCESSTOKEN, &accessToken))
+    {
+        OICStrcpy(gCloudResource.accessToken, sizeof(gCloudResource.accessToken), accessToken);
+        OICStrcpy(cloudData->accessToken, sizeof(cloudData->accessToken), accessToken);
+        OIC_LOG_V(INFO, ES_RH_TAG, "gCloudResource.accessToken %s", gCloudResource.accessToken);
+    }
+
+    int64_t accessTokenType = -1;
+    if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_ACCESSTOKEN_TYPE, &accessTokenType))
+    {
+        gCloudResource.accessTokenType = accessTokenType;
+        cloudData->accessTokenType = gCloudResource.accessTokenType;
+        OIC_LOG_V(INFO, ES_RH_TAG, "gCloudResource.accessTokenType %d", gCloudResource.accessTokenType);
+    }
+
     char *authProvider = NULL;
     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHPROVIDER, &authProvider))
     {
@@ -412,7 +432,7 @@ void updateCloudResource(OCRepPayload* input)
         gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER, &cloudData->userdata);
     }
 
-    if(authCode || authProvider || ciServer)
+    if(authCode || accessToken || authProvider || ciServer)
     {
         OIC_LOG(INFO, ES_RH_TAG, "Send CloudRsrc Callback To ES");
 
@@ -633,6 +653,8 @@ OCRepPayload* constructResponseOfCloud(char *interface)
     }
 
     OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHCODE, gCloudResource.authCode);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_ACCESSTOKEN, gCloudResource.accessToken);
+    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_ACCESSTOKEN_TYPE, (int)gCloudResource.accessTokenType);
     OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHPROVIDER, gCloudResource.authProvider);
     OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CISERVER, gCloudResource.ciServer);
 
index 03a6a05..a957717 100755 (executable)
@@ -65,6 +65,8 @@ typedef struct
 {
     OCResourceHandle handle;
     char authCode[OIC_STRING_MAX_VALUE];
+    char accessToken[OIC_STRING_MAX_VALUE];
+    OAUTH_TOKENTYPE accessTokenType;
     char authProvider[OIC_STRING_MAX_VALUE];
     char ciServer[OIC_STRING_MAX_VALUE];
 } CloudResource;
index 51928b9..ecd31bb 100755 (executable)
@@ -53,6 +53,8 @@ extern "C"
 #define OC_RSRVD_ES_AUTHTYPE               "wat"
 #define OC_RSRVD_ES_ENCTYPE                "wet"
 #define OC_RSRVD_ES_AUTHCODE               "ac"
+#define OC_RSRVD_ES_ACCESSTOKEN            "at"
+#define OC_RSRVD_ES_ACCESSTOKEN_TYPE       "att"
 #define OC_RSRVD_ES_AUTHPROVIDER           "apn"
 #define OC_RSRVD_ES_CISERVER               "cis"
 #define OC_RSRVD_ES_SERVERID               "sid"
@@ -126,6 +128,16 @@ typedef enum
 } WIFI_ENCTYPE;
 
 /**
+ * @brief OAuth Access Token Types. "bearer" and "mac" types are supported.
+ */
+typedef enum
+{
+    NONE_OAUTH_TOKENTYPE = 0,
+    OAUTH_TOKENTYPE_BEARER,
+    OAUTH_TOKENTYPE_MAC
+} OAUTH_TOKENTYPE;
+
+/**
  * @brief A result of Easy Setup
  */
 typedef enum
index 008828c..22a2acb 100755 (executable)
@@ -22,6 +22,8 @@ package org.iotivity.service.easysetup.mediator;
 
 import android.util.Log;
 
+import org.iotivity.service.easysetup.mediator.enums.OAUTH_TOKENTYPE;
+
 import org.iotivity.base.OcException;
 import org.iotivity.base.OcRepresentation;
 
@@ -65,6 +67,31 @@ public class CloudProp {
         }
     }
 
+    public void setCloudPropWithAccessToken(String accessToken, OAUTH_TOKENTYPE tokenType,
+                                        String authProvider, String ciServer)
+    {
+        if(accessToken == null)
+        {
+            accessToken = "";
+        }
+        if(authProvider == null)
+        {
+            authProvider = "";
+        }
+        if(ciServer == null)
+        {
+            ciServer = "";
+        }
+        try {
+            mRep.setValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN, accessToken);
+            mRep.setValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN_TYPE, tokenType.getValue());
+            mRep.setValue(ESConstants.OC_RSRVD_ES_AUTHPROVIDER, authProvider);
+            mRep.setValue(ESConstants.OC_RSRVD_ES_CISERVER, ciServer);
+        } catch (OcException e) {
+            Log.e(TAG, "setCloudPropWithAccessToken is failed.");
+        }
+    }
+
     public void setCloudID(String cloudID)
     {
         mCloudID = cloudID;
@@ -161,6 +188,52 @@ public class CloudProp {
         return mCredID;
     }
 
+    /**
+     * This method returns an accessToken used for the first registration to IoTivity cloud
+     * @return accessToken for sign-up to IoTivity cloud
+     */
+    public String getAccessToken()
+    {
+        if(mRep == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            if (mRep.hasAttribute(ESConstants.OC_RSRVD_ES_ACCESSTOKEN))
+                return mRep.getValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN);
+        }
+        catch (OcException e)
+        {
+            Log.e(TAG, "getAccessToken is failed.");
+        }
+        return null;
+    }
+
+    /**
+     * This method returns an access token type
+     * @return tokenType of access token
+     */
+    public OAUTH_TOKENTYPE getAccessTokenType()
+    {
+        if(mRep == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            if (mRep.hasAttribute(ESConstants.OC_RSRVD_ES_ACCESSTOKEN_TYPE))
+                return OAUTH_TOKENTYPE.fromInt((int)mRep.getValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN_TYPE));
+        }
+        catch (OcException e)
+        {
+            Log.e(TAG, "getAccessTokenType is failed.");
+        }
+        return OAUTH_TOKENTYPE.NONE_OAUTH_TOKENTYPE;
+    }
+
     public OcRepresentation toOCRepresentation()
     {
         return mRep;
index b023d6c..a694df2 100755 (executable)
@@ -34,6 +34,8 @@ public class ESConstants {
     public static final String OC_RSRVD_ES_AUTHTYPE = "wat";
     public static final String OC_RSRVD_ES_ENCTYPE = "wet";
     public static final String OC_RSRVD_ES_AUTHCODE = "ac";
+    public static final String OC_RSRVD_ES_ACCESSTOKEN = "at";
+    public static final String OC_RSRVD_ES_ACCESSTOKEN_TYPE = "att";
     public static final String OC_RSRVD_ES_AUTHPROVIDER = "apn";
     public static final String OC_RSRVD_ES_CISERVER = "cis";
     public static final String OC_RSRVD_ES_SERVERID = "sid";
diff --git a/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/OAUTH_TOKENTYPE.java b/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/OAUTH_TOKENTYPE.java
new file mode 100755 (executable)
index 0000000..70dc519
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * ***************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ****************************************************************
+ */
+
+package org.iotivity.service.easysetup.mediator.enums;
+
+/**
+ * This enum class indicates an OAuth Token type like "bearer" and "mac"\r
+ */
+public enum OAUTH_TOKENTYPE\r
+{
+    NONE_OAUTH_TOKENTYPE(0),\r
+    OAUTH_TOKENTYPE_BEARER(1),\r
+    OAUTH_TOKENTYPE_MAC(2);\r
+\r
+    private int value;
+
+    private OAUTH_TOKENTYPE(int value)\r
+    {
+        this.value = value;
+    }
+
+    /**
+     * Get OAuth Token type as an integer value\r
+     *
+     * @return int OAuth Token type as an integer value\r
+     */
+    public int getValue()
+    {
+        return value;
+    }
+
+    /**
+     * Get OAuth Token type as OAUTH_TOKENTYPE type value\r
+     *
+     * @return OAuth Token type enum value corresponding to its integer value\r
+     */
+    public static OAUTH_TOKENTYPE fromInt(int i)\r
+    {
+        for (OAUTH_TOKENTYPE b : OAUTH_TOKENTYPE.values())\r
+        {
+            if (b.getValue() == i)
+                return b;
+        }
+        return null;
+    }
+}
+\r
index 0dac2fb..17eedbe 100755 (executable)
@@ -170,6 +170,26 @@ namespace OIC
             }
 
             /**
+             * Set CloudServer resource properties with Access token to be delivered to Enrollee
+             *
+             * @param accessToken  Access token which is given in a return of auth code issued by
+             *                     OAuth2.0-compatible account server
+             * @param tokenType Access token type, i.e. "bearer"
+             * @param authProvider Auth provider ID
+             * @param ciServer Cloud interface server URL which an Enrollee is going to registered
+             *
+             * @see OAUTH_TOKENTYPE
+             */
+            void setCloudPropWithAccessToken(string accessToken, OAUTH_TOKENTYPE tokenType,
+                                                string authProvider, string ciServer)
+            {
+                m_rep.setValue(OC_RSRVD_ES_ACCESSTOKEN, accessToken);
+                m_rep.setValue(OC_RSRVD_ES_ACCESSTOKEN_TYPE, tokenType);
+                m_rep.setValue(OC_RSRVD_ES_AUTHPROVIDER, authProvider);
+                m_rep.setValue(OC_RSRVD_ES_CISERVER, ciServer);
+            }
+
+            /**
              * Set CloudServer's UUID
              *
              * @param cloudID Cloud Interface server's UUID
@@ -252,6 +272,36 @@ namespace OIC
             }
 
             /**
+             * Get an access token to be delivered.
+             *
+             * @return an access token to be delivered.
+             */
+            std::string getAccessToken() const
+            {
+                if(m_rep.hasAttribute(OC_RSRVD_ES_ACCESSTOKEN))
+                {
+                    return m_rep.getValue<std::string>(OC_RSRVD_ES_ACCESSTOKEN);
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get an access token type to be delivered.
+             *
+             * @return an access token type to be delivered.
+             */
+            OAUTH_TOKENTYPE getAccessTokenType() const
+            {
+
+                if(m_rep.hasAttribute(OC_RSRVD_ES_ACCESSTOKEN_TYPE))
+                {
+                    return static_cast<OAUTH_TOKENTYPE>(
+                                m_rep.getValue<int>(OC_RSRVD_ES_ACCESSTOKEN_TYPE));
+                }
+                return NONE_OAUTH_TOKENTYPE;
+            }
+
+            /**
              * Get OCRepresentation object
              *
              * @return OCRepresentation object
index c78ed96..f059aab 100755 (executable)
@@ -434,6 +434,13 @@ namespace OIC
 
             m_cloudPropProvStatusCb = callback;
 
+            if((cloudProp.getAuthCode().empty() && cloudProp.getAccessToken().empty()) ||
+                cloudProp.getAuthProvider().empty() ||
+                cloudProp.getCiServer().empty())
+            {
+                throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
+            }
+
             try
             {
                 initCloudResource();
index a3126c0..555deba 100755 (executable)
@@ -113,6 +113,8 @@ void CloudDataProvCbInApp(ESCloudProvData *eventData)
     }
 
     printf("AuthCode : %s\n", eventData->authCode);
+    printf("AcessToken : %s\n", eventData->accessToken);
+    printf("AcessTokenType : %d\n", eventData->accessTokenType);
     printf("AuthProvider : %s\n", eventData->authProvider);
     printf("CI Server : %s\n", eventData->ciServer);
 
index 1c7cc1b..41f0a78 100755 (executable)
@@ -276,7 +276,7 @@ void provisionCloudProperty()
     }
 
     CloudProp cloudProp;
-    cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
+    cloudProp.setCloudPropWithAccessToken("accessToken", OAUTH_TOKENTYPE_BEARER, "authProvider", "ciServer");
     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
     cloudProp.setCredID(1);