Fix the problem of browser launch when webapp can't access remote url by WARP
authorYunchan Cho <yunchan.cho@samsung.com>
Wed, 13 Feb 2013 08:48:41 +0000 (17:48 +0900)
committerYunchan Cho <yunchan.cho@samsung.com>
Thu, 21 Feb 2013 14:35:50 +0000 (23:35 +0900)
[Issue#] DCM-494
[Problem] Browser is not launched in case that access to remote url is not permitted by WARP/ACE check
[Cause] Result from WARP/ACE check was not handled by WRT
[Solution] WARP/ACE check point is moved to proper point, and checking logic between UI and Web process is changed

Change-Id: Ib75211567d9beafc28791efa5ef1309f7e8547a8

src/api_new/ewk_context_manager.cpp
src/view/webkit/bundles/bundle_uri_handling.cpp
src/view/webkit/bundles/bundle_uri_handling.h
src/view/webkit/bundles/wrt-wk2-bundle.cpp
src/view/webkit/view_logic.cpp
src/view/webkit/view_logic.h

index a5fbdba..d2264fb 100644 (file)
@@ -194,9 +194,7 @@ void EwkContextManager::messageFromInjectedBundleCallback(
     LogDebug("did recive message: " << name);
 
     EwkContextManager* This = static_cast<EwkContextManager*>(clientInfo);
-    if (!returnData) {
-        This->m_view->checkSyncMessageFromBundle(name, body, returnData);
-    }
+    This->m_view->checkSyncMessageFromBundle(name, body, returnData);
 }
 
 void EwkContextManager::didStartDownloadCallback(const char* downloadUrl, void* data)
index 656cd89..9595dcf 100644 (file)
@@ -49,8 +49,6 @@ char const * const ACE_IGNORED_SCHEMA[] = { "file://", "widget://", "data:",
                                             "tel:", "sms:", "mmsto:", "mailto:",
                                             0 };
 
-WKStringRef block_message = WKStringCreateWithUTF8CString("uri_block_msg");
-
 bool checkWARP(const char *url, const DPL::String& tizenId)
 {
     // ignore WARP in test mode
@@ -151,33 +149,23 @@ bool filterURIBySecurity(DPL::OptionalString &op_uri,
 } // namespace (anonymous)
 
 namespace BundleURIHandling {
-DPL::Optional<DPL::String> processURI(const DPL::String& inputURI,
-                                      bool is_xhr,
-                                      const DPL::String& tizenId,
-                                      WKBundleRef bundle)
+bool processURI(const DPL::String& inputURI,
+                bool is_xhr,
+                const DPL::String& tizenId,
+                WKBundleRef bundle)
 {
-    DPL::Optional<DPL::String> uri = localizeURI(inputURI, tizenId);
-
+    DPL::Optional<DPL::String> uri(inputURI);
     if (uri.IsNull()) {
         LogDebug("uri is empty");
-        return uri;
+        return true;
     }
 
     // check ACE, WARP
     if (!filterURIBySecurity(uri, is_xhr, tizenId)) {
-        WKStringRef urlStr = WKStringCreateWithUTF8CString(
-                DPL::ToUTF8String(*uri).c_str());
-        WKTypeRef retVal = NULL;
-        // Send information about blocked URI to view_logic
-        LogInfo("Sent blocked uri to open browser later : " << uri);
-        WKBundlePostSynchronousMessage(bundle, block_message,
-                                       urlStr, &retVal);
-        WKRelease(urlStr);
-        WKRelease(retVal);
-        return DPL::Optional<DPL::String>::Null;
+        return false;
     }
 
-    return uri;
+    return true;
 }
 
 DPL::OptionalString localizeURI(const DPL::String& inputURI,
index 28634fa..78b74cd 100644 (file)
 #include <WKBundle.h>
 
 namespace BundleURIHandling {
-DPL::Optional<DPL::String> processURI(const DPL::String& inputURI,
-                                      bool is_xhr,
-                                      const DPL::String& tizenId,
-                                      WKBundleRef bundle);
+bool processURI(const DPL::String& inputURI,
+                bool is_xhr,
+                const DPL::String& tizenId,
+                WKBundleRef bundle);
 DPL::OptionalString localizeURI(const DPL::String& inputURI,
                                 const DPL::String& tizenId);
 }
index de28673..1734762 100644 (file)
@@ -73,6 +73,7 @@
 
 namespace {
 const char * const uriChangedMessageName = "uri_changed_msg";
+const char * const uriBlockedMessageName = "uri_blocked_msg";
 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
 const char * const URICHANGE_PLUGIN_NO_CHANGE = "plugin_no_change";
@@ -469,28 +470,6 @@ void Bundle::didFinishLoadForResourceCallback(
     const void* clientInfo)
 {
     LogDebug("didFinishLoadForResourceCallback called");
-    Bundle* This = static_cast<Bundle*>(const_cast<void*>(clientInfo));
-
-    WKURLRef url = WKBundleFrameCopyURL(frame);
-    WKTypeRef retVal = NULL;
-
-    // If url is NULL, this url has been already blocked by willsend
-    // So current page should be moved to previous page
-    if (url == NULL) {
-        if (WKBundleFrameIsMainFrame(frame)) {
-            LogInfo("url is NULL. Go back to previous view");
-            WKStringRef blockedURL =
-                WKStringCreateWithUTF8CString(URICHANGE_BLOCKED_URL);
-            WKBundlePostSynchronousMessage(This->m_bundle,
-                                           This->m_uriChangedMessage,
-                                           blockedURL,
-                                           &retVal);
-        } else {
-            LogInfo("Blocked uri in IFrame.");
-        }
-        return;
-    }
-    WKRelease(url);
 }
 
 void Bundle::didCommitLoadForFrameCallback(
@@ -624,78 +603,74 @@ WKURLRequestRef Bundle::willSendRequestForFrame(WKURLRequestRef request)
     bool is_xhr = true; // Webkit should inform if it's XHR
     DPL::String dplurl = DPL::FromUTF8String(toString(urlStr));
     WKRelease(urlStr);
-    DPL::Optional<DPL::String> newurl = BundleURIHandling::processURI(
-            dplurl,
+
+    DPL::Optional<DPL::String> localizedUrl = 
+        BundleURIHandling::localizeURI(dplurl, m_widgetTizenId);
+    bool ret = BundleURIHandling::processURI(
+            *localizedUrl,
             is_xhr,
             m_widgetTizenId,
             m_bundle);
 
-    if (newurl.IsNull()) {
-        LogDebug("URI is blocked");
-        WKRelease(url);
+    if (!ret) {
+        LogDebug("Not permitted resource: " << *localizedUrl);
         return NULL;
-    } else {
-        LogDebug("URI processing result: " << *newurl);
-        std::string tmpUrlStr = DPL::ToUTF8String(*newurl);
-        if (tmpUrlStr.empty()) {
-            LogDebug("uri is blocked");
-            WKRelease(url);
-            return NULL;
-        }
+    }
 
-        WKURLRef tmpUrl = WKURLCreateWithUTF8CString(tmpUrlStr.c_str());
-        std::string scheme = toString(WKURLCopyScheme(url));
-        WKRelease(url);
-        // Return value must contain details information of input
-        // WKURLRequestRef. Current webkit2 doesn't support api that
-        // copy WKURLRequestRef or change url only. Before webkit2
-        // support api, callback return original WKURLRequestRef in the
-        // case of external scheme
-
-        // external scheme also need to send message to UI process for
-        // checking roaming and security
-        if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS) {
-            LogDebug("external scheme return original WKURLRequestRef");
-            WKRelease(tmpUrl);
-            WKRetain(request);
-            return request;
-        } else {
-            std::string checkUrl = toString(tmpUrl);
-            int getFileSize;
-
-            if (m_encrypted) {
-                if (isEncryptedResource(checkUrl, getFileSize)) {
-                    std::string decryptString = DecryptResource(checkUrl,
-                                                                getFileSize);
-                    if (!decryptString.empty()) {
-                        std::string destString = DATA_STRING;
-
-                        std::string mimeString =
-                            DPL::ToUTF8String(
-                                MimeTypeUtils::identifyFileMimeType(
-                                    DPL::FromUTF8String(checkUrl)));
-
-                        destString += mimeString;
-                        destString += BASE64_STRING;
-
-                        decryptString.insert(0, destString);
-
-                        WKURLRef destUrl =
-                            WKURLCreateWithUTF8CString(decryptString.c_str());
-
-                        WKURLRequestRef req = WKURLRequestCreateWithWKURL(
-                                destUrl);
-                        WKRelease(destUrl);
-                        LogDebug("return value " << decryptString << "]]");
-                        return req;
-                    }
+    LogDebug("URI processing result: " << *localizedUrl);
+    std::string tmpUrlStr = DPL::ToUTF8String(*localizedUrl);
+    WKURLRef tmpUrl = WKURLCreateWithUTF8CString(tmpUrlStr.c_str());
+    std::string scheme = toString(WKURLCopyScheme(url));
+    WKRelease(url);
+    // Return value must contain details information of input
+    // WKURLRequestRef. Current webkit2 doesn't support api that
+    // copy WKURLRequestRef or change url only. Before webkit2
+    // support api, callback return original WKURLRequestRef in the
+    // case of external scheme
+
+    // external scheme also need to send message to UI process for
+    // checking roaming and security
+    if (scheme == SCHEME_HTTP || scheme == SCHEME_HTTPS) {
+        LogDebug("external scheme return original WKURLRequestRef");
+        WKRelease(tmpUrl);
+        WKRetain(request);
+        return request;
+    } else {
+        std::string checkUrl = toString(tmpUrl);
+        int getFileSize;
+
+        if (m_encrypted) {
+            if (isEncryptedResource(checkUrl, getFileSize)) {
+                std::string decryptString = DecryptResource(checkUrl,
+                                                            getFileSize);
+                if (!decryptString.empty()) {
+                    std::string destString = DATA_STRING;
+
+                    std::string mimeString =
+                        DPL::ToUTF8String(
+                            MimeTypeUtils::identifyFileMimeType(
+                                DPL::FromUTF8String(checkUrl)));
+
+                    destString += mimeString;
+                    destString += BASE64_STRING;
+
+                    decryptString.insert(0, destString);
+
+                    WKURLRef destUrl =
+                        WKURLCreateWithUTF8CString(decryptString.c_str());
+
+                    WKURLRequestRef req = WKURLRequestCreateWithWKURL(
+                            destUrl);
+                    WKRelease(destUrl);
+                    LogDebug("return value " << decryptString << "]]");
+                    return req;
                 }
             }
-            WKURLRequestRef req = WKURLRequestCreateWithWKURL(tmpUrl);
-            WKRelease(tmpUrl);
-            LogDebug("return value " << toString(req).c_str());
-            return req;
         }
+        WKURLRequestRef req = WKURLRequestCreateWithWKURL(tmpUrl);
+        WKRelease(tmpUrl);
+        LogDebug("return value " << toString(req).c_str());
+        return req;
     }
 }
 
@@ -720,6 +695,26 @@ WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationAction(
         return WKBundlePagePolicyActionUse;
     }
 
+    // WARP & ACE Check
+    DPL::String dplUrl = DPL::FromUTF8String(request_uri);
+    DPL::Optional<DPL::String> localizedUrl = 
+        BundleURIHandling::localizeURI(dplUrl, m_widgetTizenId);
+    bool ret = BundleURIHandling::processURI(
+            *localizedUrl, true, m_widgetTizenId, m_bundle);
+    if (!ret) {
+        std::string blockedUrl = DPL::ToUTF8String(*localizedUrl);
+        LogDebug("URI is blocked: " << blockedUrl);
+
+        // Send information about blocked URI to UIProcess
+        WKStringRef urlStr = WKStringCreateWithUTF8CString(blockedUrl.c_str());
+        WKTypeRef retVal = NULL;
+        WKStringRef blockMessage = WKStringCreateWithUTF8CString(uriBlockedMessageName);
+        WKBundlePostSynchronousMessage(m_bundle, blockMessage, urlStr, &retVal);
+        WKRelease(urlStr);
+        WKRelease(retVal);
+        WKRelease(blockMessage);
+    }
+
     // get scheme string
     std::string request_scheme = getScheme(request_uri);
 
@@ -758,11 +753,11 @@ WKBundlePagePolicyAction Bundle::pageDecidePolicyForNavigationAction(
 
     LogDebug("Uri action: " << action);
 
-    if (action == URI_ACTION_WRT) {
-        return WKBundlePagePolicyActionUse;
+    if (action != URI_ACTION_WRT) {
+        return WKBundlePagePolicyActionPassThrough;
     }
 
-    return WKBundlePagePolicyActionPassThrough;
+    return WKBundlePagePolicyActionUse;
 }
 
 std::string Bundle::toString(WKStringRef str)
index 093fd8e..0baefef 100644 (file)
@@ -74,7 +74,7 @@
 
 namespace {
 const char * const bundlePath = "/usr/lib/wrt-wk2-bundles/libwrt-wk2-bundle.so";
-const char * const uriBlockedMessageName = "uri_block_msg";
+const char * const uriBlockedMessageName = "uri_blocked_msg";
 const char * const uriChangedMessageName = "uri_changed_msg";
 const char * const URICHANGE_PLUGIN_STOP_ONLY = "plugin_stop_only";
 const char * const URICHANGE_PLUGIN_RESTART = "plugin_restart";
@@ -447,19 +447,20 @@ void ViewLogic::checkSyncMessageFromBundle(
         *returnData = NULL;
         return;
     }
+
+    LogDebug("received : " << name);
+    std::string result;
     if (!strcmp(name, uriBlockedMessageName)) {
-        LogDebug("received : " << uriBlockedMessageName);
         // Currently WebProcess informs obly about blocked
         // URI - URI localization and security chekcs are
         // done by WebProcess itself (see: wrt-wk2-bundle.cpp
         // and bundle_uri_handling.cpp)
-        rememberBlockedURI(DPL::FromUTF8String(body));
-        *returnData = NULL;
+        result = requestUrlBlocked(std::string(body));
     } else if (!strcmp(name, uriChangedMessageName)) {
-        LogDebug("received : " << uriChangedMessageName);
-        std::string ret = requestUriChanged(DPL::FromUTF8String(body));
-        *returnData = strdup(ret.c_str());
+        result = requestUrlChanged(std::string(body));
     }
+
+    *returnData = strdup(result.c_str());
 }
 
 void ViewLogic::downloadData(const char* url)
@@ -796,22 +797,39 @@ void ViewLogic::loadFinishedCallback(
     const char* url = ewk_view_url_get(This->m_currentEwkView);
     if (NULL == url || strlen(url) == 0) {
         LogError("url is empty");
-    } else {
-        DPL::OptionalString jsOptionalString =
-            ViewModule::PasswordSupport::jsForAutoFillData(url);
-        if (jsOptionalString.IsNull()) {
-            LogError("Fail to get JS String");
+        return;
+    }
+
+    // check if this loading is for blocked url
+    if (This->m_blockedUri == url) {
+        if (ewk_view_back_possible(This->m_currentEwkView)) {
+            // go back to previous page
+            LogDebug("go to previous page");
+            ewk_view_back(This->m_currentEwkView);
         } else {
-            std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
-
-            if (EINA_FALSE == ewk_view_script_execute(
-                    This->m_currentEwkView,
-                    jsStr.c_str(),
-                    didRunJavaScriptCallback,
-                    This))
-            {
-                LogError("JS for auto fill data failed.");
-            }
+            // stop current page
+            LogDebug("remove current page");
+            ewk_view_stop(This->m_currentEwkView);
+            ecore_idler_add(windowCloseIdlerCallback, This);
+        }
+        This->m_blockedUri = std::string();
+        return;
+    }
+
+    DPL::OptionalString jsOptionalString =
+        ViewModule::PasswordSupport::jsForAutoFillData(url);
+    if (jsOptionalString.IsNull()) {
+        LogError("Fail to get JS String");
+    } else {
+        std::string jsStr = DPL::ToUTF8String(*jsOptionalString).c_str();
+
+        if (EINA_FALSE == ewk_view_script_execute(
+                This->m_currentEwkView,
+                jsStr.c_str(),
+                didRunJavaScriptCallback,
+                This))
+        {
+            LogError("JS for auto fill data failed.");
         }
     }
 
@@ -1897,64 +1915,44 @@ bool ViewLogic::askUserForCertificateConfirm()
                CERTIFICATE_CONFIRM_REQUEST_ASK_BODY);
 }
 
-void ViewLogic::rememberBlockedURI(const DPL::String& inputURI)
+std::string ViewLogic::requestUrlBlocked(const std::string& blockedUrl)
 {
-    m_blockedUri = DPL::ToUTF8String(inputURI);
-    LogInfo("set blocked uri to open browser later : " << m_blockedUri);
-    return;
-}
+    LogInfo("enter");
 
-std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
-{
-    using namespace ViewModule::SecuritySupport;
+    if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
+        // block this page and open it in browser
+        LogDebug("Request was blocked by WARP: " << blockedUrl);
+        LogDebug("open browser : " << blockedUrl);
+        bundle* bundleData = bundle_create();
+        appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
+        appsvc_set_uri(bundleData, blockedUrl.c_str());
+        CONTROLLER_POST_EVENT(
+            ApplicationLauncher,
+            ApplicationLauncherEvents::LaunchApplicationByAppService(
+                bundleData,
+                NULL,
+                NULL));
+    }
 
-    std::string url = DPL::ToUTF8String(changedURL);
-    LogInfo("URL = [" << url << "]");
+    // set block url. This is used on load finished callback
+    m_blockedUri = blockedUrl;
 
-    // check WARP
-    // If url is same to URICHANGE_BLOCKED_URL,
-    // this url has been already blocked by willsend.
-    // So current page should be moved to previous page
-    if (url == URICHANGE_BLOCKED_URL) {
-        if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
-            // block this page and open it in browser
-            LogDebug("Request was blocked by WARP: " << url.c_str());
-            if (!m_blockedUri.empty()) {
-                LogDebug("open browser : " << m_blockedUri);
-                bundle* bundleData = bundle_create();
-                appsvc_set_operation(bundleData, APPSVC_OPERATION_VIEW);
-                appsvc_set_uri(bundleData, m_blockedUri.c_str());
-                CONTROLLER_POST_EVENT(
-                    ApplicationLauncher,
-                    ApplicationLauncherEvents::LaunchApplicationByAppService(
-                        bundleData,
-                        NULL,
-                        NULL));
-                m_blockedUri = std::string();
-            }
-        }
-        if (ewk_view_back_possible(m_currentEwkView)) {
-            // go back to previous page
-            ewk_view_back(m_currentEwkView);
-        } else {
-            // stop current page
-            ewk_view_stop(m_currentEwkView);
-            ecore_idler_add(windowCloseIdlerCallback, this);
-        }
+    // This is used in case of returning previous page
+    return URICHANGE_PLUGIN_NO_CHANGE;
+}
 
-        // This is used in case of returning previous page
-        m_currentUri = url;
-        return URICHANGE_PLUGIN_NO_CHANGE;
-    }
+std::string ViewLogic::requestUrlChanged(const std::string& changedUrl)
+{
+    using namespace ViewModule::SecuritySupport;
 
-    m_currentUri = url;
+    LogInfo("changed url: " << changedUrl);
 
     // Check if this url with 'http' or 'https' is included in whitelist,
     // which has lists of accessible external documents and
     // used for ONLY Tizen app
     std::string matchedScheme;
     std::string matchedUri;
-    pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(url.c_str(),
+    pcrecpp::RE(PATTERN_URI_CHANGE).PartialMatch(changedUrl.c_str(),
                                                  &matchedUri,
                                                  &matchedScheme);
     ViewModule::Scheme scheme(matchedScheme);
@@ -1962,7 +1960,7 @@ std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
         scheme.GetType() == ViewModule::Scheme::HTTPS)
     {
         if (m_model->Type.Get().appType == WrtDB::APP_TYPE_TIZENWEBAPP) {
-            if (!checkWhitelist(url.c_str())) {
+            if (!checkWhitelist(changedUrl.c_str())) {
                 LogInfo("This uri is not included in white document list");
                 return URICHANGE_PLUGIN_STOP_ONLY;
             }
@@ -1974,8 +1972,7 @@ std::string ViewLogic::requestUriChanged(const DPL::String& changedURL)
         }
     }
 
-    // register javascript object for plugins to be used
-    LogInfo("Register Plugin Objects");
+    m_currentUri = changedUrl;
     return URICHANGE_PLUGIN_RESTART;
 }
 
index 03a8615..6c14862 100644 (file)
@@ -257,8 +257,8 @@ class ViewLogic : public ViewModule::IViewModule
     static Eina_Bool windowCloseIdlerCallback(void *data);
 
     // security
-    void rememberBlockedURI(const DPL::String& str);
-    std::string requestUriChanged(const DPL::String& changedURL);
+    std::string requestUrlBlocked(const std::string& blockedUrl);
+    std::string requestUrlChanged(const std::string& changedUrl);
 
     // window
     void windowClose(void);