diff --git a/lib/capybara/driver/webkit/browser.rb b/lib/capybara/driver/webkit/browser.rb index 9d7bbd5..c010993 100644 --- a/lib/capybara/driver/webkit/browser.rb +++ b/lib/capybara/driver/webkit/browser.rb @@ -6,6 +6,10 @@ class Capybara::Driver::Webkit @connection = connection end + def authenticate(username, password) + command("Authenticate", username, password) + end + def visit(url) command "Visit", url end diff --git a/spec/driver_spec.rb b/spec/driver_spec.rb index 451cca4..1dfa916 100644 --- a/spec/driver_spec.rb +++ b/spec/driver_spec.rb @@ -1,5 +1,6 @@ require 'spec_helper' require 'capybara/driver/webkit' +require 'base64' describe Capybara::Driver::Webkit do subject { Capybara::Driver::Webkit.new(@app, :browser => $webkit_browser) } @@ -1711,4 +1712,30 @@ describe Capybara::Driver::Webkit do end.to raise_error(Capybara::Driver::Webkit::WebkitInvalidResponseError) end end + + describe "basic auth" do + before(:all) do + @app = lambda do |env| + if env["REQUEST_PATH"] == "/hello/world" + [200, {"Content-Type" => "text/html", "Content-Length" => "0"}, [""]] + else + if env["HTTP_AUTHORIZATION"] + header = env["HTTP_AUTHORIZATION"] + [200, {"Content-Type" => "text/html", "Content-Length" => header.length.to_s}, [header]] + else + html = "401 Unauthorized." + [401, + {"Content-Type" => "text/html", "Content-Length" => html.length.to_s, "WWW-Authenticate" => 'Basic realm="Secure Area"'}, + [html]] + end + end + end + end + + it "can authenticate a request" do + subject.browser.authenticate('user', 'password') + subject.visit("/") + subject.body.should include("Basic "+Base64.encode64("user:password").strip) + end + end end diff --git a/src/Authenticate.cpp b/src/Authenticate.cpp new file mode 100644 index 0000000..add3e1f --- /dev/null +++ b/src/Authenticate.cpp @@ -0,0 +1,18 @@ +#include "Authenticate.h" +#include "WebPage.h" +#include "NetworkAccessManager.h" + +Authenticate::Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent) : Command(manager, arguments, parent) { +} + +void Authenticate::start() { + QString username = arguments()[0]; + QString password = arguments()[1]; + + NetworkAccessManager* networkAccessManager = qobject_cast(page()->networkAccessManager()); + networkAccessManager->setUserName(username); + networkAccessManager->setPassword(password); + + emit finished(new Response(true)); +} + diff --git a/src/Authenticate.h b/src/Authenticate.h new file mode 100644 index 0000000..b78972e --- /dev/null +++ b/src/Authenticate.h @@ -0,0 +1,12 @@ +#include "Command.h" + +class WebPage; + +class Authenticate : public Command { + Q_OBJECT + + public: + Authenticate(WebPageManager *manager, QStringList &arguments, QObject *parent = 0); + virtual void start(); +}; + diff --git a/src/CommandFactory.cpp b/src/CommandFactory.cpp index 524ecc3..3d1d921 100644 --- a/src/CommandFactory.cpp +++ b/src/CommandFactory.cpp @@ -29,6 +29,7 @@ #include "GetWindowHandles.h" #include "GetWindowHandle.h" #include "WebPageManager.h" +#include "Authenticate.h" CommandFactory::CommandFactory(WebPageManager *manager, QObject *parent) : QObject(parent) { m_manager = manager; diff --git a/src/NetworkAccessManager.cpp b/src/NetworkAccessManager.cpp index c7249bc..6a0301c 100644 --- a/src/NetworkAccessManager.cpp +++ b/src/NetworkAccessManager.cpp @@ -1,9 +1,11 @@ #include "NetworkAccessManager.h" #include "WebPage.h" #include +#include NetworkAccessManager::NetworkAccessManager(QObject *parent):QNetworkAccessManager(parent) { + connect(this, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*))); } QNetworkReply* NetworkAccessManager::createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice * outgoingData = 0) { @@ -27,3 +29,17 @@ void NetworkAccessManager::resetHeaders() { m_headers.clear(); }; +void NetworkAccessManager::setUserName(const QString &userName) { + m_userName = userName; +} + +void NetworkAccessManager::setPassword(const QString &password) { + m_password = password; +} + + +void NetworkAccessManager::provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator) { + Q_UNUSED(reply); + authenticator->setUser(m_userName); + authenticator->setPassword(m_password); +} diff --git a/src/NetworkAccessManager.h b/src/NetworkAccessManager.h index c2364c6..a7fb279 100644 --- a/src/NetworkAccessManager.h +++ b/src/NetworkAccessManager.h @@ -10,10 +10,17 @@ class NetworkAccessManager : public QNetworkAccessManager { NetworkAccessManager(QObject *parent = 0); void addHeader(QString key, QString value); void resetHeaders(); + void setUserName(const QString &userName); + void setPassword(const QString &password); protected: QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &req, QIODevice * outgoingData); + QString m_userName; + QString m_password; private: QHash m_headers; + + private slots: + void provideAuthentication(QNetworkReply *reply, QAuthenticator *authenticator); }; diff --git a/src/find_command.h b/src/find_command.h index 9cc7ddf..3806f23 100644 --- a/src/find_command.h +++ b/src/find_command.h @@ -30,3 +30,4 @@ CHECK_COMMAND(SetSkipImageLoading) CHECK_COMMAND(WindowFocus) CHECK_COMMAND(GetWindowHandles) CHECK_COMMAND(GetWindowHandle) +CHECK_COMMAND(Authenticate) diff --git a/src/webkit_server.pro b/src/webkit_server.pro index 2cb4704..608c415 100644 --- a/src/webkit_server.pro +++ b/src/webkit_server.pro @@ -2,6 +2,7 @@ TEMPLATE = app TARGET = webkit_server DESTDIR = . HEADERS = \ + Authenticate.h \ IgnoreSslErrors.h \ ResizeWindow.h \ CurrentUrl.h \ @@ -45,6 +46,7 @@ HEADERS = \ GetWindowHandle.h \ SOURCES = \ + Authenticate.cpp \ IgnoreSslErrors.cpp \ ResizeWindow.cpp \ CurrentUrl.cpp \