Add support for getting service definitions from the MFA platform

Added GetServiceDetails function to MPinSDK.

Closes: MAASMOB-431
diff --git a/src/mpin_sdk.cpp b/src/mpin_sdk.cpp
index cf37779..d55ddae 100644
--- a/src/mpin_sdk.cpp
+++ b/src/mpin_sdk.cpp
@@ -371,6 +371,11 @@
     m_mpinStatus.SetErrorMessage(String().Format("HTTP request to '%s' failed. Error: '%s'", m_requestUrl.c_str(), error.c_str()));
 }
 
+void MPinSDK::HttpResponse::SetResponseJsonParseError(const String& jsonParseError)
+{
+    SetResponseJsonParseError(String(m_rawData).Trim(), jsonParseError);
+}
+
 void MPinSDK::HttpResponse::SetResponseJsonParseError(const String& responseJson, const String& jsonParseError)
 {
     m_httpStatus = NON_HTTP_ERROR;
@@ -425,6 +430,7 @@
 {
     switch(context)
     {
+    case GET_SERVICE_DETAILS:
     case GET_CLIENT_SETTINGS:
     case AUTHENTICATE_PASS1:
     case AUTHENTICATE_PASS2:
@@ -648,6 +654,36 @@
     return Status(Status::OK);
 }
 
+Status MPinSDK::GetServiceDetails(const String& url, OUT ServiceDetails& serviceDetails)
+{
+    HttpResponse response = MakeGetRequest(String().Format("%s/service", String(url).TrimRight("/").c_str()));
+    if (response.GetStatus() != HttpResponse::HTTP_OK)
+    {
+        return response.TranslateToMPinStatus(HttpResponse::GET_SERVICE_DETAILS);
+    }
+
+    try
+    {
+        const util::JsonObject& data = response.GetJsonData();
+        serviceDetails.name = ((const json::String&) data["name"]).Value();
+        serviceDetails.backendUrl = ((const json::String&) data["url"]).Value();
+        serviceDetails.rpsPrefix = ((const json::String&) data["rps_prefix"]).Value();
+        serviceDetails.logoUrl = ((const json::String&) data["logo_url"]).Value();
+        String type = ((const json::String&) data["type"]).Value();
+        if (type != "online")
+        {
+            throw json::Exception(String().Format("Unexpected service details type: '%s'. Must be 'online'", type.c_str()));
+        }
+
+        return Status::OK;
+    }
+    catch (json::Exception& e)
+    {
+        response.SetResponseJsonParseError(e.what());
+        return response.TranslateToMPinStatus(HttpResponse::GET_SERVICE_DETAILS);
+    }
+}
+
 Status MPinSDK::Init(const StringMap& config, IContext* ctx)
 {
     return Init(config, ctx, StringMap());
diff --git a/src/mpin_sdk.h b/src/mpin_sdk.h
index 5d29199..23792d5 100644
--- a/src/mpin_sdk.h
+++ b/src/mpin_sdk.h
@@ -237,8 +237,20 @@
         String appIconUrl;
     };
 
+    class ServiceDetails
+    {
+    public:
+        String name;
+        String backendUrl;
+        String rpsPrefix;
+        String logoUrl;
+    };
+
     MPinSDK();
     ~MPinSDK();
+
+    Status GetServiceDetails(const String& url, OUT ServiceDetails& serviceDetails);
+
     Status Init(const StringMap& config, IN IContext* ctx);
     Status Init(const StringMap& config, IN IContext* ctx, const StringMap& customHeaders);
     void SetClientId(const String& clientId);
@@ -294,6 +306,7 @@
 
         enum Context
         {
+            GET_SERVICE_DETAILS,
             GET_CLIENT_SETTINGS,
             REGISTER,
             GET_CLIENT_SECRET1,
@@ -322,6 +335,7 @@
         const StringMap& GetHeaders() const;
         void SetNetworkError(const String& error);
         void SetHttpError(int httpStatus);
+        void SetResponseJsonParseError(const String& jsonParseError);
         Status TranslateToMPinStatus(Context context);
 
     private: