1/* 2 * Copyright (C) 2012 Intel Corporation. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27 28#include "UnitTestUtils/EWK2UnitTestBase.h" 29#include "UnitTestUtils/EWK2UnitTestServer.h" 30 31using namespace EWK2UnitTest; 32 33extern EWK2UnitTestEnvironment* environment; 34 35static const char testUsername[] = "username"; 36static const char testPassword[] = "password"; 37static const char expectedSuccessTitle[] = "EFLWebKit2 Authentication test"; 38static const char expectedAuthorization[] = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="; // Base64 encoding of "username:password". 39static const char indexHTMLString[] = 40 "<html>" 41 "<head><title>EFLWebKit2 Authentication test</title></head>" 42 "<body></body></html>"; 43 44class EWK2AuthRequestTest : public EWK2UnitTestBase { 45public: 46 static void serverCallback(SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, void*) 47 { 48 if (message->method != SOUP_METHOD_GET) { 49 soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); 50 return; 51 } 52 53 if (!strcmp(path, "/index.html")) { 54 const char* authorization = soup_message_headers_get_one(message->request_headers, "Authorization"); 55 // Require authentication 56 if (authorization && !strcmp(authorization, expectedAuthorization)) { 57 // Successful authentication. 58 soup_message_set_status(message, SOUP_STATUS_OK); 59 soup_message_body_append(message->response_body, SOUP_MEMORY_COPY, indexHTMLString, strlen(indexHTMLString)); 60 } else { 61 // No (valid) authorization header provided by the client, request authentication. 62 soup_message_set_status(message, SOUP_STATUS_UNAUTHORIZED); 63 soup_message_headers_append(message->response_headers, "WWW-Authenticate", "Basic realm=\"my realm\""); 64 } 65 } else 66 soup_message_set_status(message, SOUP_STATUS_NOT_FOUND); 67 68 soup_message_body_complete(message->response_body); 69 } 70 71 static void onAuthenticationRequest(void* userData, Evas_Object*, void* eventInfo) 72 { 73 Ewk_Auth_Request** returnRequest = static_cast<Ewk_Auth_Request**>(userData); 74 ASSERT_TRUE(returnRequest); 75 76 Ewk_Auth_Request* request = static_cast<Ewk_Auth_Request*>(eventInfo); 77 ASSERT_TRUE(request); 78 79 *returnRequest = ewk_object_ref(request); 80 } 81 82 static void onLoadFinished(void* userData, Evas_Object*, void*) 83 { 84 bool* isFinished = static_cast<bool*>(userData); 85 ASSERT_TRUE(isFinished); 86 87 *isFinished = true; 88 } 89}; 90 91TEST_F(EWK2AuthRequestTest, ewk_auth_request_success) 92{ 93 std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>(); 94 httpServer->run(serverCallback); 95 96 Ewk_Auth_Request* authenticationRequest = 0; 97 evas_object_smart_callback_add(webView(), "authentication,request", onAuthenticationRequest, &authenticationRequest); 98 99 ewk_view_url_set(webView(), httpServer->getURLForPath("/index.html").data()); 100 101 while (!authenticationRequest) 102 ecore_main_loop_iterate(); 103 104 ASSERT_TRUE(authenticationRequest); 105 evas_object_smart_callback_del(webView(), "authentication,request", onAuthenticationRequest); 106 107 EXPECT_STREQ("my realm", ewk_auth_request_realm_get(authenticationRequest)); 108 EXPECT_STREQ("127.0.0.1", ewk_auth_request_host_get(authenticationRequest)); 109 EXPECT_FALSE(ewk_auth_request_retrying_get(authenticationRequest)); 110 111 ASSERT_TRUE(ewk_auth_request_authenticate(authenticationRequest, testUsername, testPassword)); 112 113 ewk_object_unref(authenticationRequest); 114 115 ASSERT_TRUE(waitUntilTitleChangedTo(expectedSuccessTitle)); 116} 117 118TEST_F(EWK2AuthRequestTest, ewk_auth_request_failure_then_success) 119{ 120 std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>(); 121 httpServer->run(serverCallback); 122 123 Ewk_Auth_Request* authenticationRequest = 0; 124 evas_object_smart_callback_add(webView(), "authentication,request", onAuthenticationRequest, &authenticationRequest); 125 126 ewk_view_url_set(webView(), httpServer->getURLForPath("/index.html").data()); 127 128 while (!authenticationRequest) 129 ecore_main_loop_iterate(); 130 131 ASSERT_TRUE(authenticationRequest); 132 133 EXPECT_STREQ("my realm", ewk_auth_request_realm_get(authenticationRequest)); 134 EXPECT_STREQ("127.0.0.1", ewk_auth_request_host_get(authenticationRequest)); 135 EXPECT_FALSE(ewk_auth_request_retrying_get(authenticationRequest)); 136 137 ASSERT_TRUE(ewk_auth_request_authenticate(authenticationRequest, testUsername, "wrongpassword")); 138 139 ewk_object_unref(authenticationRequest); 140 authenticationRequest = 0; 141 142 // We expect a second authentication request since the first one failed. 143 while (!authenticationRequest) 144 ecore_main_loop_iterate(); 145 evas_object_smart_callback_del(webView(), "authentication,request", onAuthenticationRequest); 146 147 EXPECT_STREQ("my realm", ewk_auth_request_realm_get(authenticationRequest)); 148 EXPECT_STREQ("127.0.0.1", ewk_auth_request_host_get(authenticationRequest)); 149 EXPECT_TRUE(ewk_auth_request_retrying_get(authenticationRequest)); 150 151 // Now provide the right password. 152 ASSERT_TRUE(ewk_auth_request_authenticate(authenticationRequest, testUsername, testPassword)); 153 154 ewk_object_unref(authenticationRequest); 155 156 ASSERT_TRUE(waitUntilTitleChangedTo(expectedSuccessTitle)); 157} 158 159TEST_F(EWK2AuthRequestTest, ewk_auth_request_cancel) 160{ 161 std::unique_ptr<EWK2UnitTestServer> httpServer = std::make_unique<EWK2UnitTestServer>(); 162 httpServer->run(serverCallback); 163 164 Ewk_Auth_Request* authenticationRequest = 0; 165 evas_object_smart_callback_add(webView(), "authentication,request", onAuthenticationRequest, &authenticationRequest); 166 167 ewk_view_url_set(webView(), httpServer->getURLForPath("/index.html").data()); 168 169 while (!authenticationRequest) 170 ecore_main_loop_iterate(); 171 172 ASSERT_TRUE(authenticationRequest); 173 evas_object_smart_callback_del(webView(), "authentication,request", onAuthenticationRequest); 174 175 EXPECT_STREQ("my realm", ewk_auth_request_realm_get(authenticationRequest)); 176 EXPECT_STREQ("127.0.0.1", ewk_auth_request_host_get(authenticationRequest)); 177 EXPECT_FALSE(ewk_auth_request_retrying_get(authenticationRequest)); 178 179 bool isFinished = false; 180 evas_object_smart_callback_add(webView(), "load,finished", onLoadFinished, &isFinished); 181 182 // Will attempt to continue without authentication by default. 183 ewk_object_unref(authenticationRequest); 184 185 waitUntilTrue(isFinished); 186 187 ASSERT_STRNE(expectedSuccessTitle, ewk_view_title_get(webView())); 188 189 evas_object_smart_callback_del(webView(), "load,finished", onLoadFinished); 190} 191