Added Cloud-connector API in base layer for account server 21/9121/17
authorJaewook Jung <jw0213.jung@samsung.com>
Thu, 16 Jun 2016 11:51:46 +0000 (20:51 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Thu, 21 Jul 2016 11:34:39 +0000 (11:34 +0000)
added APIs to support functions about account authorization
  : Sign-up, Sign-in, Sign-out, Refresh Access token
one existing build option is used to inlude APIs
  : WITH_CLOUD
and it is not supported on client mode for now
since device id is not generated on client mode (JIRA-1184)

Change-Id: Iefdf52545580efa4c533ff77137bce6c779bcaba
Signed-off-by: Jaewook Jung <jw0213.jung@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/9121
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: jihwan seo <jihwan.seo@samsung.com>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
16 files changed:
build_common/SConscript
examples/OICMiddle/SConscript
resource/csdk/stack/include/octypes.h
resource/examples/SConscript
resource/include/IClientWrapper.h
resource/include/InProcClientWrapper.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OutOfProcClientWrapper.h
resource/src/InProcClientWrapper.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp
resource/src/OCResource.cpp
resource/src/SConscript
resource/unittests/OCPlatformTest.cpp
resource/unittests/SConscript

index 3fab911..9756ca0 100644 (file)
@@ -88,7 +88,7 @@ help_vars.Add(BoolVariable('WITH_RA', 'Build with Remote Access module', False))
 help_vars.Add(BoolVariable('WITH_TCP', 'Build with TCP adapter', False))
 help_vars.Add(ListVariable('WITH_MQ', 'Build with MQ publisher/broker', 'OFF', ['OFF', 'SUB', 'PUB', 'BROKER']))
 help_vars.Add(EnumVariable('WITH_RD', 'Build including Resource Directory', '0', allowed_values=('0', '1')))
-help_vars.Add(BoolVariable('WITH_CLOUD', 'Build including Cloud client sample', False))
+help_vars.Add(BoolVariable('WITH_CLOUD', 'Build including Cloud Connector and Cloud Client sample', False))
 
 help_vars.Add(BoolVariable('SIMULATOR', 'Build with simulator module', False))
 
index 340dbe5..98a4d84 100644 (file)
@@ -69,6 +69,9 @@ if target_os == 'android':
 if target_os in ['darwin', 'ios']:
        examples_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
 
+if env.get('WITH_CLOUD'):
+       examples_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
index 4d45976..4b521b5 100644 (file)
@@ -338,6 +338,38 @@ extern "C" {
 /** To represent resource type with Publish RD.*/
 #define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdpub"
 
+/** Cloud Account */
+
+/** Account URI.*/
+#define OC_RSRVD_ACCOUNT_URI               "/.well-known/ocf/account"
+
+/** Account session URI.*/
+#define OC_RSRVD_ACCOUNT_SESSION_URI       "/.well-known/ocf/account/session"
+
+/** Account token refresh URI.*/
+#define OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI "/.well-known/ocf/account/tokenrefresh"
+
+/** Defines auth provider. */
+#define OC_RSRVD_AUTHPROVIDER              "authprovider"
+
+/** Defines auth code. */
+#define OC_RSRVD_AUTHCODE                  "authcode"
+
+/** Defines session. */
+#define OC_RSRVD_ACCESS_TOKEN              "accesstoken"
+
+/** Defines status. */
+#define OC_RSRVD_STATUS                    "status"
+
+/** Defines grant type. */
+#define OC_RSRVD_GRANT_TYPE                "granttype"
+
+/** Defines refresh token. */
+#define OC_RSRVD_REFRESH_TOKEN             "refreshtoken"
+
+/** To represent grant type with refresh token. */
+#define OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN  "refresh_token"
+
 /**
  * Mark a parameter as unused. Used to prevent unused variable compiler warnings.
  * Used in three cases:
index 895a2e5..c85806d 100644 (file)
@@ -73,12 +73,12 @@ if target_os in ['darwin', 'ios']:
 if examples_env.get('LOGGING'):
        examples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
+if examples_env.get('WITH_CLOUD'):
+       examples_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 if target_os in ['msys_nt', 'windows']:
        examples_env.AppendUnique(LIBS = ['Comctl32', 'Gdi32', 'User32'])
 
-if examples_env.get('LOGGING'):
-       examples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
-
 def make_single_file_cpp_program(program_name):
        return examples_env.Program(program_name, program_name + ".cpp")
 
index 0cbfa53..849be2d 100644 (file)
@@ -77,6 +77,7 @@ namespace OC
                         const std::string& uri,
                         const OCRepresentation& rep, const QueryParamsMap& queryParams,
                         const HeaderOptions& headerOptions,
+                        OCConnectivityType connectivityType,
                         PostCallback& callback, QualityOfService QoS) = 0;
 
         virtual OCStackResult DeleteResource(
index c13edb1..c4f0e59 100644 (file)
@@ -138,7 +138,8 @@ namespace OC
             const OCDevAddr& devAddr,
             const std::string& uri,
             const OCRepresentation& attributes, const QueryParamsMap& queryParams,
-            const HeaderOptions& headerOptions, PostCallback& callback, QualityOfService QoS);
+            const HeaderOptions& headerOptions, OCConnectivityType connectivityType,
+            PostCallback& callback, QualityOfService QoS);
 
         virtual OCStackResult DeleteResource(
             const OCDevAddr& devAddr,
index a5c50e2..a46bb75 100644 (file)
@@ -615,6 +615,82 @@ namespace OC
         OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
                                      const std::string& pinNumber,
                                      DirectPairingCallback resultCallback);
+#ifdef WITH_CLOUD
+        /**
+         * API for Account Registration to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param authProvider Provider name used for authentication.
+         * @param authCode The authorization code obtained by using an authorization server
+         *                 as an intermediary between the client and resource owner.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult signUp(const std::string& host,
+                             const std::string& authProvider,
+                             const std::string& authCode,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        /**
+         * API for Sign-In to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param accessToken Identifier of the resource obtained by account registration.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult signIn(const std::string& host,
+                             const std::string& accessToken,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        /**
+         * API for Sign-Out to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param accessToken Identifier of the resource obtained by account registration.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult signOut(const std::string& host,
+                              const std::string& accessToken,
+                              OCConnectivityType connectivityType,
+                              PostCallback cloudConnectHandler);
+
+        /**
+         * API for Refresh Access token to Account Server
+         * @note Not supported on client mode for now since device id is not generated yet on
+         *       client mode. So it should be server or both mode for API to work.
+         *
+         * @param host Host IP Address of a account server.
+         * @param refreshToken Refresh token used for access token refresh.
+         * @param connectivityType ::OCConnectivityType type of connectivity indicating the
+         *                           interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP.
+         * @param cloudConnectHandler Callback function that will get the result of the operation.
+         *
+         * @return Returns ::OC_STACK_OK if success
+         */
+        OCStackResult refreshAccessToken(const std::string& host,
+                                         const std::string& refreshToken,
+                                         OCConnectivityType connectivityType,
+                                         PostCallback cloudConnectHandler);
+#endif // WITH_CLOUD
     }
 }
 
index 51217f0..c9f85ac 100644 (file)
@@ -241,7 +241,34 @@ namespace OC
         OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel,
                                          const std::string& pinNumber,
                                          DirectPairingCallback resultCallback);
-
+#ifdef WITH_CLOUD
+        OCStackResult signUp(const std::string& host,
+                             const std::string& authProvider,
+                             const std::string& authCode,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        OCStackResult signIn(const std::string& host,
+                             const std::string& accessToken,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler);
+
+        OCStackResult signOut(const std::string& host,
+                              const std::string& accessToken,
+                              OCConnectivityType connectivityType,
+                              PostCallback cloudConnectHandler);
+
+        OCStackResult signInOut(const std::string& host,
+                                const std::string& accessToken,
+                                bool isSignIn,
+                                OCConnectivityType connectivityType,
+                                PostCallback cloudConnectHandler);
+
+        OCStackResult refreshAccessToken(const std::string& host,
+                                         const std::string& refreshToken,
+                                         OCConnectivityType connectivityType,
+                                         PostCallback cloudConnectHandler);
+#endif // WITH_CLOUD
     private:
         PlatformConfig m_cfg;
 
index 3719a63..4b2d24a 100644 (file)
@@ -84,6 +84,7 @@ namespace OC
             const OCRepresentation& /*attributes*/,
             const QueryParamsMap& /*queryParams*/,
             const HeaderOptions& /*headerOptions*/,
+            OCConnectivityType /*connectivityType*/,
             PostCallback& /*callback*/, QualityOfService /*QoS*/)
             {return OC_STACK_NOTIMPL;}
 
index 1d68a2f..db1178b 100644 (file)
@@ -576,6 +576,7 @@ namespace OC
         const std::string& uri,
         const OCRepresentation& rep,
         const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
+        OCConnectivityType connectivityType,
         PostCallback& callback, QualityOfService QoS)
     {
         if (!callback)
@@ -602,7 +603,7 @@ namespace OC
             result = OCDoResource(nullptr, OC_REST_POST,
                                   url.c_str(), &devAddr,
                                   assembleSetResourcePayload(rep),
-                                  CT_DEFAULT,
+                                  connectivityType,
                                   static_cast<OCQualityOfService>(QoS),
                                   &cbdata,
                                   assembleHeaderOptions(options, headerOptions),
index b722750..f959239 100644 (file)
@@ -290,7 +290,44 @@ namespace OC
             return OCPlatform_impl::Instance().doDirectPairing(peer, pmSel,
                                              pinNumber, resultCallback);
         }
+#ifdef WITH_CLOUD
+        OCStackResult signUp(const std::string& host,
+                             const std::string& authProvider,
+                             const std::string& authCode,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().signUp(host, authProvider, authCode,
+                                                      connectivityType, cloudConnectHandler);
+        }
+
+        OCStackResult signIn(const std::string& host,
+                             const std::string& accessToken,
+                             OCConnectivityType connectivityType,
+                             PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().signIn(host, accessToken,
+                                                      connectivityType, cloudConnectHandler);
+        }
 
+        OCStackResult signOut(const std::string& host,
+                              const std::string& accessToken,
+                              OCConnectivityType connectivityType,
+                              PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().signOut(host, accessToken,
+                                                       connectivityType, cloudConnectHandler);
+        }
+
+        OCStackResult refreshAccessToken(const std::string& host,
+                                         const std::string& refreshToken,
+                                         OCConnectivityType connectivityType,
+                                         PostCallback cloudConnectHandler)
+        {
+            return OCPlatform_impl::Instance().refreshAccessToken(host, refreshToken,
+                                                       connectivityType, cloudConnectHandler);
+        }
+#endif // WITH_CLOUD
     } // namespace OCPlatform
 } //namespace OC
 
index 3862862..da48020 100644 (file)
@@ -417,6 +417,120 @@ namespace OC
         return checked_guard(m_client, &IClientWrapper::DoDirectPairing,
                              peer, pmSel, pinNumber, resultCallback);
     }
+#ifdef WITH_CLOUD
+    OCStackResult OCPlatform_impl::signUp(const std::string& host,
+                                          const std::string& authProvider,
+                                          const std::string& authCode,
+                                          OCConnectivityType connectivityType,
+                                          PostCallback cloudConnectHandler)
+    {
+        const char* di = OCGetServerInstanceIDString();
+        if (!di)
+        {
+            oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
+            return result_guard(OC_STACK_ERROR);
+        }
+        std::string deviceId(di);
+
+        OCRepresentation rep;
+        rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
+        rep.setValue(OC_RSRVD_AUTHPROVIDER, authProvider);
+        rep.setValue(OC_RSRVD_AUTHCODE, authCode);
+
+        std::string uri = host + OC_RSRVD_ACCOUNT_URI;
+
+        OCDevAddr devAddr;
+        QueryParamsMap queryParams;
+        HeaderOptions headerOptions;
 
+        QualityOfService defaultQos = OC::QualityOfService::NaQos;
+        checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
+
+        return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
+                             devAddr, uri, rep, queryParams, headerOptions,
+                             connectivityType, cloudConnectHandler, defaultQos);
+    }
+
+    OCStackResult OCPlatform_impl::signIn(const std::string& host,
+                                          const std::string& accessToken,
+                                          OCConnectivityType connectivityType,
+                                          PostCallback cloudConnectHandler)
+    {
+        return signInOut(host, accessToken, true, connectivityType, cloudConnectHandler);
+    }
+
+    OCStackResult OCPlatform_impl::signOut(const std::string& host,
+                                           const std::string& accessToken,
+                                           OCConnectivityType connectivityType,
+                                           PostCallback cloudConnectHandler)
+    {
+        return signInOut(host, accessToken, false, connectivityType, cloudConnectHandler);
+    }
+
+    OCStackResult OCPlatform_impl::signInOut(const std::string& host,
+                                             const std::string& accessToken,
+                                             bool isSignIn,
+                                             OCConnectivityType connectivityType,
+                                             PostCallback cloudConnectHandler)
+    {
+        const char* di = OCGetServerInstanceIDString();
+        if (!di)
+        {
+            oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
+            return result_guard(OC_STACK_ERROR);
+        }
+        std::string deviceId(di);
+
+        OCRepresentation rep;
+        rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
+        rep.setValue(OC_RSRVD_ACCESS_TOKEN, accessToken);
+        rep.setValue(OC_RSRVD_STATUS, isSignIn);
+
+        std::string uri = host + OC_RSRVD_ACCOUNT_SESSION_URI;
+
+        OCDevAddr devAddr;
+        QueryParamsMap queryParams;
+        HeaderOptions headerOptions;
+
+        QualityOfService defaultQos = OC::QualityOfService::NaQos;
+        checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
+
+        return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
+                             devAddr, uri, rep, queryParams, headerOptions,
+                             connectivityType, cloudConnectHandler, defaultQos);
+    }
+
+    OCStackResult OCPlatform_impl::refreshAccessToken(const std::string& host,
+                                                      const std::string& refreshToken,
+                                                      OCConnectivityType connectivityType,
+                                                      PostCallback cloudConnectHandler)
+    {
+        const char* di = OCGetServerInstanceIDString();
+        if (!di)
+        {
+            oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
+            return result_guard(OC_STACK_ERROR);
+        }
+        std::string deviceId(di);
+
+        OCRepresentation rep;
+        rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
+        rep.setValue(OC_RSRVD_REFRESH_TOKEN, refreshToken);
+        rep.setValue(OC_RSRVD_GRANT_TYPE, OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN);
+
+        std::string uri = host + OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI;
+
+        OCDevAddr devAddr;
+        QueryParamsMap queryParams;
+        HeaderOptions headerOptions;
+
+        QualityOfService defaultQos = OC::QualityOfService::NaQos;
+        checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
+
+        return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
+                             devAddr, uri, rep, queryParams, headerOptions,
+                             connectivityType, cloudConnectHandler, defaultQos);
+    }
+#endif // WITH_CLOUD
 } //namespace OC
 
index 43fdeab..7d680ca 100644 (file)
@@ -376,7 +376,7 @@ OCStackResult OCResource::post(const OCRepresentation& rep,
 {
     return checked_guard(m_clientWrapper.lock(), &IClientWrapper::PostResourceRepresentation,
                          m_devAddr, m_uri, rep, queryParametersMap,
-                         m_headerOptions, attributeHandler, QoS);
+                         m_headerOptions, CT_DEFAULT, attributeHandler, QoS);
 }
 
 OCStackResult OCResource::post(const OCRepresentation& rep,
index 0f31035..32ff64b 100644 (file)
@@ -77,6 +77,9 @@ if target_os in ['msys_nt', 'windows']:
        if secured == '1':
                oclib_env.AppendUnique(LIBS=['tinydtls'])
 
+if oclib_env.get('WITH_CLOUD'):
+       oclib_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
index d5aad2e..481e453 100644 (file)
@@ -69,7 +69,12 @@ namespace OCPlatformTest
     void pairedHandler(const PairedDevices& /*list*/)
     {
     }
-
+#ifdef WITH_CLOUD
+    void accountHandler(const HeaderOptions& /*headerOptions*/, const OCRepresentation& /*rep*/,
+            const int /*eCode*/)
+    {
+    }
+#endif
     //Helper methods
     void DeleteStringLL(OCStringLL* ll)
     {
@@ -869,4 +874,70 @@ namespace OCPlatformTest
         std::shared_ptr<OCDirectPairing> s_dp(new OCDirectPairing(&peer));
         EXPECT_ANY_THROW(OCPlatform::doDirectPairing(nullptr, pmSel, pin, nullptr));
     }
+#ifdef WITH_CLOUD
+    //SignUp Test
+    TEST(SignUpTest, DISABLED_SignUpWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string authProvider("AnyAuthProvider");
+        std::string authCode("AnyAuthCode");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::signUp(host, authProvider, authCode,
+                                                  CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(SignUpTest, SignUpWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string authProvider("AnyAuthProvider");
+        std::string authCode("AnyAuthCode");
+        EXPECT_ANY_THROW(OCPlatform::signUp(host, authProvider, authCode, CT_DEFAULT, nullptr));
+    }
+
+    //SignIn Test
+    TEST(SignInTest, DISABLED_SignInWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::signIn(host, accessToken, CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(SignInTest, SignInWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_ANY_THROW(OCPlatform::signIn(host, accessToken, CT_DEFAULT, nullptr));
+    }
+
+    //SignOut Test
+    TEST(SignOutTest, DISABLED_SignOutWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::signOut(host, accessToken,
+                                                   CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(SignOutTest, SignOutWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string accessToken("AnyAccessToken");
+        EXPECT_ANY_THROW(OCPlatform::signOut(host, accessToken, CT_DEFAULT, nullptr));
+    }
+
+    //RefreshAccessToken Test
+    TEST(RefreshAccessTokenTest, DISABLED_RefreshAccessTokenWithValidParameters)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string refreshToken("AnyRefreshToken");
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::refreshAccessToken(host, refreshToken,
+                                                              CT_DEFAULT, &accountHandler));
+    }
+
+    TEST(RefreshAccessTokenTest, RefreshAccessTokenWithNullCallback)
+    {
+        std::string host("coap+tcp://192.168.1.2:5000");
+        std::string refreshToken("AnyRefreshToken");
+        EXPECT_ANY_THROW(OCPlatform::refreshAccessToken(host, refreshToken, CT_DEFAULT, nullptr));
+    }
+#endif // WITH_CLOUD
 }
index 8d1249d..a3a78cd 100644 (file)
@@ -60,6 +60,9 @@ if unittests_env.get('SECURED') == '1':
 if unittests_env.get('LOGGING'):
        unittests_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
+if unittests_env.get('WITH_CLOUD'):
+       unittests_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
+
 ######################################################################
 # Source files and Targets
 ######################################################################