Merge lp:~mardy/webbrowser-app/add-onlineaccount-support-for-container2 into lp:webbrowser-app
- add-onlineaccount-support-for-container2
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 556 |
Proposed branch: | lp:~mardy/webbrowser-app/add-onlineaccount-support-for-container2 |
Merge into: | lp:webbrowser-app |
Diff against target: |
1573 lines (+935/-256) 21 files modified
debian/control (+4/-1) src/app/browserapplication.cpp (+6/-0) src/app/browserapplication.h (+2/-0) src/app/webcontainer/AccountsPage.qml (+73/-0) src/app/webcontainer/CMakeLists.txt (+5/-1) src/app/webcontainer/chrome-cookie-store.cpp (+218/-0) src/app/webcontainer/chrome-cookie-store.h (+53/-0) src/app/webcontainer/cookie-store.cpp (+30/-24) src/app/webcontainer/cookie-store.h (+16/-28) src/app/webcontainer/online-accounts-cookie-store.cpp (+8/-12) src/app/webcontainer/online-accounts-cookie-store.h (+6/-6) src/app/webcontainer/sqlitecookiestore.cpp (+0/-99) src/app/webcontainer/sqlitecookiestore.h (+0/-58) src/app/webcontainer/webapp-container.cpp (+24/-1) src/app/webcontainer/webapp-container.h (+4/-0) src/app/webcontainer/webapp-container.qml (+114/-26) src/app/webcontainer/webkit-cookie-store.cpp (+120/-0) src/app/webcontainer/webkit-cookie-store.h (+51/-0) tests/unittests/CMakeLists.txt (+1/-0) tests/unittests/cookie-store/CMakeLists.txt (+11/-0) tests/unittests/cookie-store/tst_CookieStore.cpp (+189/-0) |
To merge this branch: | bzr merge lp:~mardy/webbrowser-app/add-onlineaccount-support-for-container2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Olivier Tilloy | Approve | ||
David Barth (community) | Approve | ||
Review via email: mp+211701@code.launchpad.net |
Commit message
Add online account support in the webapp container.
A new "accountProvider" command line parameter has been added to allow one to specify an account provider for the specific webapp launch. When used, one can specify a given provider, e.g. "facebook", to pull existing accounts (if any) from the specified provider
from Online Accounts.
When the provider does not have any existing account, an option to delegate the creation of such an account to OA is provided. It is also possible to skip the step and go straight to the target url.
Description of the change
Add online account support in the webapp container.
A new "accountProvider" command line parameter has been added to allow one to specify an account provider for the specific webapp launch. When used, one can specify a given provider, e.g. "facebook", to pull existing accounts (if any) from the specified provider
from Online Accounts.
When the provider does not have any existing account, an option to delegate the creation of such an account to OA is provided. It is also possible to skip the step and go straight to the target url.
In order to use it, one can use a command line such as:
APP_ID=cookie-test ./webapp-container --webapp --accountProvid
(provided a proper .application file has been installed with the proper name in /usr/share/
PS Jenkins bot (ps-jenkins) wrote : | # |
David Barth (dbarth) : | # |
Olivier Tilloy (osomon) wrote : | # |
60 +// system
61 +#include <string.h>
62 +#include <unistd.h>
Those changes seem useless, can they be reverted?
Olivier Tilloy (osomon) wrote : | # |
287 + bool registerCookieQ
What’s the point of this method returning a boolean value (the return value seems unused)?
Olivier Tilloy (osomon) wrote : | # |
223 + qmlRegisterType
224 + qmlRegisterType
225 + qmlRegisterType
For consistency with what’s already done in webbrowser-app.cpp (see line 90), and to make it fully explicit that those are not public API exposed through a plugin, could you change the import to "private.
Olivier Tilloy (osomon) wrote : | # |
235 - out << "Usage: " << command << " [-h|--help] [--fullscreen] [--maximized] [--inspector] [--app-id=APP_ID] [--homepage=URL] [--webapp[=name]] [--webappModelS
This was split in several lines for readability (thanks for this!), but it’s missing the new [--accountProvi
Olivier Tilloy (osomon) wrote : | # |
358 + return i18n.tr("Ubuntu Web Application")
Since some strings were updated, the translation template needs to be re-generated. To do that, run:
cmake . && make webbrowser-app.pot
and then commit the changes to the branch.
Olivier Tilloy (osomon) wrote : | # |
(apparently, when the initial version of this branch was reverted in trunk, the new C++ files were not removed)
421 + dbPath: ".local/share/" + applicationName + "/.QtWebKit/
Apparently this dbPath property is relative to the user’s home directory. This is not how local files to the applications should be accessed. Instead, use the "dataLocation" global context property being exported by the Ubuntu.
Olivier Tilloy (osomon) wrote : | # |
206 + m_window-
In Qt 5.2, the Qt.application global QML object has a 'name' property, which will make this additional property superfluous.
Olivier Tilloy (osomon) wrote : | # |
Olivier Tilloy (osomon) wrote : | # |
=== modified file 'tests/
Changes to this file are unrelated, please revert.
Olivier Tilloy (osomon) wrote : | # |
456 +
457 +
Can those two superfluous blank lines be removed?
Olivier Tilloy (osomon) wrote : | # |
Looks good overall, but I made a bunch of comments for minor changes, so marking needs fixing to ensure they get addressed before landing. Thanks!
- 471. By Alberto Mardegan
-
Address review comments
- 472. By Alberto Mardegan
-
remove added empty line
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:471
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
The inclusion of <QStandardPaths> in src/app/
- 473. By Alberto Mardegan
-
Removed unused header inclusion
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:472
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:473
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 474. By Alberto Mardegan
-
Don't load the webview as soon as a webapp starts
The code in webapp-
container. qml initially checks the value of its
"accountProvider" property and loads the webview if that's empty.
If this property is set after the component has been built, this will cause the
webview to be (accidentally) loaded for a fraction of a second, which in turn
will cause the WebProcess to be spawned. The WebProcess will read the
cookies.db file, and the same WebProcess instance will likely be reused for the
webapp, once we really want to use it. This has the unfortunate side-effect
that it will not re-read the cookies which we might have copied over from
Online Accounts in the meantime.So, with this change we make sure that all properties (including
"accountProvider") will be set on the Window before the component is completed.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:474
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 475. By Alberto Mardegan
-
Fix build
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:475
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
I understand the logic in revision 474 (and the need for it), but I’m not very fond of the way it’s implemented. Do we really need an optional CreationMode parameter? Can’t we just make BeginCreation the (non overridable) default?
I.e., what do we gain from keeping webbrowser-app being initialized in CompleteCreation mode?
Alberto Mardegan (mardy) wrote : | # |
I agree with you Olivier, I simply wanted to avoid changing webbrowser-app at all. If you don't mind me adding a completeCreate() call in WebbrowserApp:
Olivier Tilloy (osomon) wrote : | # |
> I agree with you Olivier, I simply wanted to avoid changing webbrowser-app at
> all. If you don't mind me adding a completeCreate() call in
> WebbrowserApp:
Yes, please do. Thanks!
- 476. By Alberto Mardegan
-
Always use 2-step creation of the component
Olivier Tilloy (osomon) wrote : | # |
I haven’t tested again, but the changes look good to me. Please ensure the changes are thoroughly tested before landing.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:476
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 477. By Alberto Mardegan
-
Merge from trunk, partial fixes
[ Ubuntu daily release ]
* New rebuild forced
[ Alexandre Abreu ]
* Fix the network dialog reload (LP: #1309138)
* Oxide (and Chromium) does not inform of non user driven navigations
(or more specifically redirects that would be part of an
popup/webview load (after its been granted). Quite a few sites (e.g.
Youtube), create popups when clicking on links (or following a
window.open()) with proper youtube.com address but w/ redirection
params, e.g.:
http://www.youtube. com/redirect? q=http% 3A%2F%2Fgodzill amovie. com%2F&
redir_token=b8WPI1pq9 FHXeHm2bN3KVLAJ Sfp8MTM5NzI2NDg 3NEAxMzk3MTc4ND c0
In this instance the popup & navigation is granted, but then a
redirect happens inside the popup to the real target url (here
http://godzillamovie. com) which is not trapped by a navigation
requested and therefore not filtered. The only way to do it atm is
to listen to url changes in popups & also filter there. (LP:
#1294279)
[ CI bot ]
* Resync trunk
[ Olivier Tilloy ]
* Handle new view requests in the browser. (LP: #1307735)
[ Olivier Tilloy ]
* Force the page title to be reset to an empty string when the
activity view is being hidden. (LP: #1307420)
[ Michael Sheldon ]
* Add support for file upload via content-hub
[ Ugo Riboni ]
* Add support for file upload via content-hub
[ Alexandre Abreu ]
* Make sure that we dont load unecessary libs (oxide or qtwebkit)
correspnding to the webengine that we dont use. (LP: #1306037)
* Add a basic set of integration tests for the webapp container
[ Ubuntu daily release ]
* New rebuild forced
[ Olivier Tilloy ]
* Enable UA overrides for all form factors, each in a separate file.
Add an override for google calendar on desktop. Clean up the
construction of the default UA string for easier reading and
maintenance.
[ Bill Filler ]
* Add support for file upload via content-hub
[ David Barth ]
* To prevent https://bugs.launchpad .net/ubuntu/ +source/ ubuntu- ui-
toolkit/+bug/1305834 caused by a recent UI toolkit change, we are
returning an empty title for now. (LP: #1305834)
[ Alexandre Abreu ]
* Add support for Oxide's onNavigationRequested in the container (LP:
#1302769)
* Webapps: maintain the session cookies for the user session Instruct
Oxide to store/load the session cookies on disk in a per-webapp
directory under XDG_RUNTIME_DIR. The first time in a user session
that the webapp is launched, the session cookies (leftover from
previous sessions) are not loaded, but only stored (this is the
chrome's "persistent" sessionCookieMode). The next times, session
cookies are both loaded and stored (chrome's "restored"
sessionCookieMode).
[ Alberto Mardegan ]
* Webapps: maintain the session cookies for the user session Instruct
Oxide to store/load the session cookies on disk in a per-webapp
directory under XDG_RUNTIME_DIR. The first time in a user session
that the webapp is launched, the session cookies (leftover from
previous sessions) are not loaded, but only stored (this is the
chrome's "persistent" sessionCookieMode). The next times, session
cookies are both loaded and stored (chrome's "restored"
sessionCookieMode).
[ Ubuntu daily release ]
* New rebuild forced
[ Olivier Tilloy ]
* Update to oxide 1.0.
[ Olivier Tilloy ]
* Re-enable javascript dialogs, now that they are available in oxide.
[ CI bot ]
* Resync trunk
[ Alexandre Abreu ]
* Small update to the --webapp flag documentation
[ Olivier Tilloy ]
* Null-check to fix a segmentation fault when --help is passed to the
executable.
[ Olivier Tilloy ]
* Land the master Oxide support branch. See individual revisions for
details. (LP: #1271756)
[ Alexandre Abreu ]
* There are 2 ways for the webapp-container to receive a list of
patterns to filter url browsing in a webapp container: through the
manifest.json file that comes with a given (named) webapp, or
through the command line. At the moment, the 2 mechanisms are
exclusive in the sense that from the webapp-container's perspective
it only considers one or another when filtering navigation (the
webapp manifest one being preferred) but they are NOT semantically
equivalent. The list of url patterns in the manifest.json file is
use as a mean to filter the urls that are being browsed to, but ALSO
in the chromium & FF browsers to know if a webapp is to be
installed/enabled when browsing in a given url. For example, for
Gmail, the hostname mail.google.com is used as a trigger to ask the
user for an installation/enablement of a webapp in the browser. It
is also implicitely used as a filter for browser once in the
container. The issue is that for applications like google services,
the authentication mechanism is common. So when launched in the
container, the user will be redirected to e.g.
https://accounts. google. com or https:/ /accounts. google. ca, etc. So,
the manifest.json cannot be modified to account for those, since we
dont want to install a webapp from those URLs but we need a way to
add extra navigation url patterns to allow google service webapps to
be redirected to e.g. https://accounts. google. * etc. We provide here
2 things: an way for the url patterns passed down from the command
line to be also considered in the navigation filtering,. a way to
simplify url patterns for google apps (LP: #1288982)
[ Olivier Tilloy ]
* Use the renderer only once when rendering a thumbnail. This seems to
fix the crash that was happening at destruction time. (LP: #1294219) - 478. By Alberto Mardegan
-
WIP
- 479. By Alberto Mardegan
-
From trunk
[ Olivier Tilloy ]
* Fix FTBFS with Qt 5.3. (LP: #1321440)
[ Ubuntu daily release ]
* New rebuild forced
[ Olivier Tilloy ]
* Remove an extraneous whitespace in the default UA on mobile.
[ Michael Sheldon ]
* Add support for downloading images via download manager and content-
hub on non-desktop platforms.
[ Tim Peeters ]
* Push the initial Page on the PageStack.
[ Ubuntu daily release ]
* New rebuild forced
[ Alexandre Abreu ]
* Add --local-webapp- manifest webapp container cli option to simplify
the command line in the case of a local manifest.json file
definition. This is to become a bit more important now that the
manifest support thing like ua overrides that would be beneficial to
webapp on touch.
[ Ubuntu daily release ]
* New rebuild forced
[ Alexandre Abreu ]
* Add capability for single webapps to have specific UA overrides for
the website that they serve (LP: #1245465)
[ Olivier Tilloy ]
* Enable cross compilation for an ARM target on an X86 host.
* Port autopilot tests to Python 3.
[ Michael Sheldon ]
* Resolve image URLs beginning with a double slash correctly for
context menu items (LP: #1311626)
[ Adnane Belmadiaf ]
* Enabled passwordEchoEnabled (LP: #1314251)
[ Alberto Mardegan ]
* Split UbuntuWebContext into two different components:
UbuntuWebContext, which is a WebContext derivative with the UA
overrides for Ubuntu. UbuntuSharedWebContext, which is a singleton
for UbuntuWebContext .
[ Olivier Tilloy ]
* Build the models in a separate static lib, and link the unit tests
against it. This speeds up build time by avoiding having to
recompile the models’ source for each unit test.
* Handle javascript console messages.
* Escape literal dots in UA override matching regular expressions.
* Enable localStorage by default in the browser. (LP: #1309673)
* Ensure that the URL actually changes so that the address bar is
updated in case the user has entered a new address that redirects to
where she previously was. (LP: #1306615)
* Update bzr ignore rules.
[ Olivier Tilloy ]
* Work around a recent regression by forcing the OSK to show up when
the address bar is being focused. (LP: #1316057)
[ CI bot ]
* Resync trunk
[ Alberto Mardegan ]
* Webapps: let SAML requests through SAML requests are used for
instance by Google Apps for your domain; they are implemented as a
HTTP redirect to a URL containing the query parameter called
"SAMLRequest". Besides letting the request through, we must also add
the SAML domain to the list of the allowed hosts. (LP: #1302780)
[ Ubuntu daily release ]
* New rebuild forced - 480. By Alberto Mardegan
-
Fix cookies stores, add tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:480
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
614 + bool setCookies(
Shouldn’t the argument be a "const Cookies&" ? (this applies to other methods that take a Cookies as argument)
Olivier Tilloy (osomon) wrote : | # |
In CookieStore:
Olivier Tilloy (osomon) wrote : | # |
440 + QString dbPath() const;
1310 + QString dbPath() const;
Can those return a "const QString&" ?
Olivier Tilloy (osomon) wrote : | # |
1108 + WebkitCookieStore {
1109 + id: webkitCookieStore
1110 + dbPath: dataLocation + "/.QtWebKit/
1111 + }
1112 +
1113 + ChromeCookieStore {
1114 + id: chromeCookieStore
1115 + dbPath: dataLocation + "/cookies.sqlite"
1116 + }
The two implementations of CookieStore are instantiated at all times, even though only one (or possibly none) of them is used. Can only one of them be instantiated dynamically in loadLoginView() instead?
Olivier Tilloy (osomon) wrote : | # |
1344 +set(TEST tst_CookieStore)
Can this be renamed to "tst_CookieStor
Olivier Tilloy (osomon) wrote : | # |
1436 + makeCleanDir(
1437 + makeCleanDir(
Please use QTemporaryDir instead to create truly unique and temporary directories.
Olivier Tilloy (osomon) wrote : | # |
1442 + QCOMPARE(
1462 + QCOMPARE(
Those tests are useless, as you just instantiated the signal spy, so you are guaranteed that the count is 0.
- 481. By Alberto Mardegan
-
Fix the webapp container
- 482. By Alberto Mardegan
-
Merge from trunk
[ Ubuntu daily release ]
* New rebuild forced
[ Olivier Tilloy ]
* Ensure the main page that contains the webviews fills the main view.
(LP: #1321462)
[ Olivier Tilloy ]
* Ensure the current webview is hidden while the activity view is
visible, and work around a bug in oxide that prevented new empty
tabs from rendering.
[ Ubuntu daily release ]
* New rebuild forced
[ Olivier Tilloy ]
* Various optimizations to the activity view. (LP: #1260980)
* Do not override the default height of the TextField that serves as
the address bar. (LP: #1317866) - 483. By Alberto Mardegan
-
Revert changes to pot file
- 484. By Alberto Mardegan
-
Address review comments
Alberto Mardegan (mardy) wrote : | # |
On 05/29/2014 11:27 AM, Olivier Tilloy wrote:
> 614 + bool setCookies(
>
> Shouldn’t the argument be a "const Cookies&" ? (this applies to other methods that take a Cookies as argument)
Fixed.
> In CookieStore:
Done.
> 440 + QString dbPath() const;
> 1310 + QString dbPath() const;
>
> Can those return a "const QString&" ?
They could indeed, but I prefer not to return a reference, because that
exposes an implementation detail (the fact that we store the path as a
member variable in the class). I generally never return by reference,
unless I have a very good reason to; but if you feel strongly about
this, I can change it.
> The two implementations of CookieStore are instantiated at all times, even though only one (or possibly none) of them is used. Can only one of them be instantiated dynamically in loadLoginView() instead?
Done.
> 1344 +set(TEST tst_CookieStore)
>
> Can this be renamed to "tst_CookieStor
Done.
> 1436 + makeCleanDir(
> 1437 + makeCleanDir(
>
> Please use QTemporaryDir instead to create truly unique and temporary directories.
Done.
> 1442 + QCOMPARE(
> 1462 + QCOMPARE(
>
> Those tests are useless, as you just instantiated the signal spy, so you are guaranteed that the count is 0.
No idea what I was thinking :-) I've now removed them.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:484
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Olivier Tilloy (osomon) wrote : | # |
> 1344 +set(TEST tst_CookieStore)
>
> Can this be renamed to "tst_CookieStor
> will match the generated binary and xml output?
Almost there :)
You renamed it to "tst_CookieStor
Olivier Tilloy (osomon) : | # |
- 485. By Alberto Mardegan
-
Rename test executable
Alberto Mardegan (mardy) wrote : | # |
I changed the test name, and replied to your comment about the SQL connection name.
- 486. By Alberto Mardegan
-
Remove support for relative file paths
Olivier Tilloy (osomon) wrote : | # |
Looks good to me now.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:485
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:486
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/control' | |||
2 | --- debian/control 2014-05-02 05:45:21 +0000 | |||
3 | +++ debian/control 2014-06-02 11:59:43 +0000 | |||
4 | @@ -51,9 +51,12 @@ | |||
5 | 51 | Multi-Arch: foreign | 51 | Multi-Arch: foreign |
6 | 52 | Depends: ${misc:Depends}, | 52 | Depends: ${misc:Depends}, |
7 | 53 | ${shlibs:Depends}, | 53 | ${shlibs:Depends}, |
8 | 54 | libqt5webkit5-qmlwebkitplugin, | ||
9 | 55 | qtdeclarative5-accounts-plugin, | ||
10 | 56 | qtdeclarative5-qtquick2-plugin (>= 5.2), | ||
11 | 54 | unity-webapps-qml, | 57 | unity-webapps-qml, |
12 | 55 | libqt5webkit5-qmlwebkitplugin, | ||
13 | 56 | webbrowser-app (= ${binary:Version}), | 58 | webbrowser-app (= ${binary:Version}), |
14 | 59 | Suggests: qtdeclarative5-online-accounts-client0.1 (>= 0.3), | ||
15 | 57 | Description: Ubuntu web applications container | 60 | Description: Ubuntu web applications container |
16 | 58 | A lightweight webapps container tailored for Ubuntu, based on the Webkit | 61 | A lightweight webapps container tailored for Ubuntu, based on the Webkit |
17 | 59 | rendering engine and using the Ubuntu UI components. | 62 | rendering engine and using the Ubuntu UI components. |
18 | 60 | 63 | ||
19 | === modified file 'src/app/browserapplication.cpp' | |||
20 | --- src/app/browserapplication.cpp 2014-05-21 08:01:42 +0000 | |||
21 | +++ src/app/browserapplication.cpp 2014-06-02 11:59:43 +0000 | |||
22 | @@ -122,6 +122,9 @@ | |||
23 | 122 | if (!isRunningInstalled()) { | 122 | if (!isRunningInstalled()) { |
24 | 123 | m_engine->addImportPath(UbuntuBrowserImportsDirectory()); | 123 | m_engine->addImportPath(UbuntuBrowserImportsDirectory()); |
25 | 124 | } | 124 | } |
26 | 125 | |||
27 | 126 | qmlEngineCreated(m_engine); | ||
28 | 127 | |||
29 | 125 | QQmlContext* context = m_engine->rootContext(); | 128 | QQmlContext* context = m_engine->rootContext(); |
30 | 126 | m_component = new QQmlComponent(m_engine); | 129 | m_component = new QQmlComponent(m_engine); |
31 | 127 | m_component->loadUrl(QUrl::fromLocalFile(UbuntuBrowserDirectory() + "/" + qmlFileSubPath)); | 130 | m_component->loadUrl(QUrl::fromLocalFile(UbuntuBrowserDirectory() + "/" + qmlFileSubPath)); |
32 | @@ -141,6 +144,9 @@ | |||
33 | 141 | return true; | 144 | return true; |
34 | 142 | } | 145 | } |
35 | 143 | 146 | ||
36 | 147 | void BrowserApplication::qmlEngineCreated(QQmlEngine*) | ||
37 | 148 | {} | ||
38 | 149 | |||
39 | 144 | int BrowserApplication::run() | 150 | int BrowserApplication::run() |
40 | 145 | { | 151 | { |
41 | 146 | Q_ASSERT(m_window != 0); | 152 | Q_ASSERT(m_window != 0); |
42 | 147 | 153 | ||
43 | === modified file 'src/app/browserapplication.h' | |||
44 | --- src/app/browserapplication.h 2014-04-10 14:47:53 +0000 | |||
45 | +++ src/app/browserapplication.h 2014-06-02 11:59:43 +0000 | |||
46 | @@ -49,6 +49,8 @@ | |||
47 | 49 | virtual void printUsage() const = 0; | 49 | virtual void printUsage() const = 0; |
48 | 50 | QList<QUrl> urls() const; | 50 | QList<QUrl> urls() const; |
49 | 51 | 51 | ||
50 | 52 | virtual void qmlEngineCreated(QQmlEngine*); | ||
51 | 53 | |||
52 | 52 | QStringList m_arguments; | 54 | QStringList m_arguments; |
53 | 53 | QQmlEngine* m_engine; | 55 | QQmlEngine* m_engine; |
54 | 54 | QQuickWindow* m_window; | 56 | QQuickWindow* m_window; |
55 | 55 | 57 | ||
56 | === added file 'src/app/webcontainer/AccountsPage.qml' | |||
57 | --- src/app/webcontainer/AccountsPage.qml 1970-01-01 00:00:00 +0000 | |||
58 | +++ src/app/webcontainer/AccountsPage.qml 2014-06-02 11:59:43 +0000 | |||
59 | @@ -0,0 +1,73 @@ | |||
60 | 1 | /* | ||
61 | 2 | * Copyright 2013-2014 Canonical Ltd. | ||
62 | 3 | * | ||
63 | 4 | * This file is part of webbrowser-app. | ||
64 | 5 | * | ||
65 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
66 | 7 | * it under the terms of the GNU General Public License as published by | ||
67 | 8 | * the Free Software Foundation; version 3. | ||
68 | 9 | * | ||
69 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
70 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
71 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
72 | 13 | * GNU General Public License for more details. | ||
73 | 14 | * | ||
74 | 15 | * You should have received a copy of the GNU General Public License | ||
75 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
76 | 17 | */ | ||
77 | 18 | |||
78 | 19 | import QtQuick 2.0 | ||
79 | 20 | import Ubuntu.Components 0.1 | ||
80 | 21 | import webcontainer.private 0.1 | ||
81 | 22 | |||
82 | 23 | Page { | ||
83 | 24 | id: accountsPage | ||
84 | 25 | |||
85 | 26 | property alias accountProvider: accountsLogin.accountProvider | ||
86 | 27 | property alias applicationName: accountsLogin.applicationName | ||
87 | 28 | property var webappCookieStore: null | ||
88 | 29 | |||
89 | 30 | signal done() | ||
90 | 31 | |||
91 | 32 | visible: false | ||
92 | 33 | anchors.fill: parent | ||
93 | 34 | |||
94 | 35 | AccountsLoginPage { | ||
95 | 36 | id: accountsLogin | ||
96 | 37 | |||
97 | 38 | anchors.fill: parent | ||
98 | 39 | |||
99 | 40 | QtObject { | ||
100 | 41 | id: internal | ||
101 | 42 | function onMoved(result) { | ||
102 | 43 | webappCookieStore.moved.disconnect(internal.onMoved) | ||
103 | 44 | if (!result) { | ||
104 | 45 | console.error("Unable to move cookies") | ||
105 | 46 | } | ||
106 | 47 | accountsPage.done() | ||
107 | 48 | } | ||
108 | 49 | } | ||
109 | 50 | |||
110 | 51 | onDone: { | ||
111 | 52 | if (!accountsPage.visible) | ||
112 | 53 | return | ||
113 | 54 | if (!credentialsId) { | ||
114 | 55 | accountsPage.done() | ||
115 | 56 | return | ||
116 | 57 | } | ||
117 | 58 | |||
118 | 59 | if (webappCookieStore) { | ||
119 | 60 | var instance = onlineAccountStoreComponent.createObject(accountsLogin, {accountId: credentialsId}) | ||
120 | 61 | webappCookieStore.moved.connect(internal.onMoved) | ||
121 | 62 | webappCookieStore.moveFrom(instance) | ||
122 | 63 | } else { | ||
123 | 64 | accountsPage.done() | ||
124 | 65 | } | ||
125 | 66 | } | ||
126 | 67 | } | ||
127 | 68 | |||
128 | 69 | Component { | ||
129 | 70 | id: onlineAccountStoreComponent | ||
130 | 71 | OnlineAccountsCookieStore { } | ||
131 | 72 | } | ||
132 | 73 | } | ||
133 | 0 | 74 | ||
134 | === modified file 'src/app/webcontainer/CMakeLists.txt' | |||
135 | --- src/app/webcontainer/CMakeLists.txt 2014-04-03 12:01:59 +0000 | |||
136 | +++ src/app/webcontainer/CMakeLists.txt 2014-06-02 11:59:43 +0000 | |||
137 | @@ -9,7 +9,11 @@ | |||
138 | 9 | set(WEBAPP_CONTAINER webapp-container) | 9 | set(WEBAPP_CONTAINER webapp-container) |
139 | 10 | 10 | ||
140 | 11 | set(WEBAPP_CONTAINER_SRC | 11 | set(WEBAPP_CONTAINER_SRC |
141 | 12 | chrome-cookie-store.cpp | ||
142 | 13 | cookie-store.cpp | ||
143 | 14 | online-accounts-cookie-store.cpp | ||
144 | 12 | webapp-container.cpp | 15 | webapp-container.cpp |
145 | 16 | webkit-cookie-store.cpp | ||
146 | 13 | session-utils.cpp | 17 | session-utils.cpp |
147 | 14 | url-pattern-utils.cpp | 18 | url-pattern-utils.cpp |
148 | 15 | ) | 19 | ) |
149 | @@ -18,7 +22,7 @@ | |||
150 | 18 | 22 | ||
151 | 19 | target_link_libraries(${WEBAPP_CONTAINER} ${COMMONLIB}) | 23 | target_link_libraries(${WEBAPP_CONTAINER} ${COMMONLIB}) |
152 | 20 | 24 | ||
154 | 21 | qt5_use_modules(${WEBAPP_CONTAINER} Core Widgets Quick) | 25 | qt5_use_modules(${WEBAPP_CONTAINER} Core Widgets Quick Sql DBus) |
155 | 22 | 26 | ||
156 | 23 | install(TARGETS ${WEBAPP_CONTAINER} | 27 | install(TARGETS ${WEBAPP_CONTAINER} |
157 | 24 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | 28 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) |
158 | 25 | 29 | ||
159 | === added file 'src/app/webcontainer/chrome-cookie-store.cpp' | |||
160 | --- src/app/webcontainer/chrome-cookie-store.cpp 1970-01-01 00:00:00 +0000 | |||
161 | +++ src/app/webcontainer/chrome-cookie-store.cpp 2014-06-02 11:59:43 +0000 | |||
162 | @@ -0,0 +1,218 @@ | |||
163 | 1 | /* | ||
164 | 2 | * Copyright 2014 Canonical Ltd. | ||
165 | 3 | * | ||
166 | 4 | * This file is part of webbrowser-app. | ||
167 | 5 | * | ||
168 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
169 | 7 | * it under the terms of the GNU General Public License as published by | ||
170 | 8 | * the Free Software Foundation; version 3. | ||
171 | 9 | * | ||
172 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
173 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
174 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
175 | 13 | * GNU General Public License for more details. | ||
176 | 14 | * | ||
177 | 15 | * You should have received a copy of the GNU General Public License | ||
178 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
179 | 17 | */ | ||
180 | 18 | |||
181 | 19 | #include "chrome-cookie-store.h" | ||
182 | 20 | |||
183 | 21 | #include <QDebug> | ||
184 | 22 | #include <QFileInfo> | ||
185 | 23 | #include <QNetworkCookie> | ||
186 | 24 | #include <QSqlError> | ||
187 | 25 | #include <QSqlQuery> | ||
188 | 26 | #include <QStandardPaths> | ||
189 | 27 | |||
190 | 28 | static int connectionCounter = 0; | ||
191 | 29 | |||
192 | 30 | static qint64 dateTimeToChrome(const QDateTime &time) | ||
193 | 31 | { | ||
194 | 32 | /* Chrome uses Mon Jan 01 00:00:00 UTC 1601 as the epoch, hence the | ||
195 | 33 | * magic number */ | ||
196 | 34 | return (time.toMSecsSinceEpoch() + 11644473600000) * 1000; | ||
197 | 35 | } | ||
198 | 36 | |||
199 | 37 | static QDateTime dateTimeFromChrome(qint64 chromeTimeStamp) | ||
200 | 38 | { | ||
201 | 39 | qint64 msecsSinceEpoch = chromeTimeStamp / 1000 - 11644473600000; | ||
202 | 40 | return QDateTime::fromMSecsSinceEpoch(msecsSinceEpoch); | ||
203 | 41 | } | ||
204 | 42 | |||
205 | 43 | ChromeCookieStore::ChromeCookieStore(QObject* parent): | ||
206 | 44 | CookieStore(parent) | ||
207 | 45 | { | ||
208 | 46 | QString connectionName = | ||
209 | 47 | QString("chromeCookieStore-%1").arg(connectionCounter++); | ||
210 | 48 | m_db = QSqlDatabase::addDatabase("QSQLITE", connectionName); | ||
211 | 49 | } | ||
212 | 50 | |||
213 | 51 | Cookies ChromeCookieStore::doGetCookies() | ||
214 | 52 | { | ||
215 | 53 | Cookies cookies; | ||
216 | 54 | m_db.setDatabaseName(m_dbPath); | ||
217 | 55 | |||
218 | 56 | if (Q_UNLIKELY(!m_db.open())) { | ||
219 | 57 | qCritical() << "Could not open cookie database:" << m_dbPath | ||
220 | 58 | << m_db.lastError(); | ||
221 | 59 | return cookies; | ||
222 | 60 | } | ||
223 | 61 | |||
224 | 62 | QSqlQuery q(m_db); | ||
225 | 63 | q.exec("SELECT host_key, name, value, path, expires_utc, secure, httponly, has_expires FROM cookies;"); | ||
226 | 64 | |||
227 | 65 | while (q.next()) { | ||
228 | 66 | /* Build the cookie string from its parts */ | ||
229 | 67 | QNetworkCookie cookie(q.value(1).toString().toUtf8(), | ||
230 | 68 | q.value(2).toString().toUtf8()); | ||
231 | 69 | cookie.setSecure(q.value(5).toBool()); | ||
232 | 70 | cookie.setHttpOnly(q.value(6).toBool()); | ||
233 | 71 | if (q.value(7).toBool()) { | ||
234 | 72 | QDateTime expires = dateTimeFromChrome(q.value(4).toULongLong()); | ||
235 | 73 | cookie.setExpirationDate(expires); | ||
236 | 74 | } | ||
237 | 75 | cookie.setDomain(q.value(0).toString()); | ||
238 | 76 | cookie.setPath(q.value(3).toString()); | ||
239 | 77 | cookies.append(cookie.toRawForm()); | ||
240 | 78 | } | ||
241 | 79 | |||
242 | 80 | m_db.close(); | ||
243 | 81 | return cookies; | ||
244 | 82 | } | ||
245 | 83 | |||
246 | 84 | QDateTime ChromeCookieStore::lastUpdateTimeStamp() const | ||
247 | 85 | { | ||
248 | 86 | QFileInfo dbFileInfo(m_dbPath); | ||
249 | 87 | return dbFileInfo.lastModified(); | ||
250 | 88 | } | ||
251 | 89 | |||
252 | 90 | bool ChromeCookieStore::createDb() | ||
253 | 91 | { | ||
254 | 92 | if (Q_UNLIKELY(!m_db.transaction())) return false; | ||
255 | 93 | |||
256 | 94 | QSqlQuery q(m_db); | ||
257 | 95 | bool ok; | ||
258 | 96 | ok = q.exec("CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," | ||
259 | 97 | "value LONGVARCHAR)"); | ||
260 | 98 | if (Q_UNLIKELY(!ok)) { | ||
261 | 99 | m_db.rollback(); | ||
262 | 100 | return false; | ||
263 | 101 | } | ||
264 | 102 | |||
265 | 103 | ok = q.exec("CREATE TABLE cookies (creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," | ||
266 | 104 | "host_key TEXT NOT NULL," | ||
267 | 105 | "name TEXT NOT NULL," | ||
268 | 106 | "value TEXT NOT NULL," | ||
269 | 107 | "path TEXT NOT NULL," | ||
270 | 108 | "expires_utc INTEGER NOT NULL," | ||
271 | 109 | "secure INTEGER NOT NULL," | ||
272 | 110 | "httponly INTEGER NOT NULL," | ||
273 | 111 | "last_access_utc INTEGER NOT NULL," | ||
274 | 112 | "has_expires INTEGER NOT NULL DEFAULT 1," | ||
275 | 113 | "persistent INTEGER NOT NULL DEFAULT 1," | ||
276 | 114 | "priority INTEGER NOT NULL DEFAULT 1," | ||
277 | 115 | "encrypted_value BLOB DEFAULT '')"); | ||
278 | 116 | if (Q_UNLIKELY(!ok)) { | ||
279 | 117 | m_db.rollback(); | ||
280 | 118 | return false; | ||
281 | 119 | } | ||
282 | 120 | |||
283 | 121 | ok = q.exec("CREATE INDEX domain ON cookies(host_key)"); | ||
284 | 122 | if (Q_UNLIKELY(!ok)) { | ||
285 | 123 | m_db.rollback(); | ||
286 | 124 | return false; | ||
287 | 125 | } | ||
288 | 126 | |||
289 | 127 | ok = q.exec("INSERT INTO meta (key, value) VALUES ('version', '7')"); | ||
290 | 128 | if (Q_UNLIKELY(!ok)) { | ||
291 | 129 | m_db.rollback(); | ||
292 | 130 | return false; | ||
293 | 131 | } | ||
294 | 132 | |||
295 | 133 | ok = q.exec("INSERT INTO meta (key, value) VALUES ('last_compatible_version', '5')"); | ||
296 | 134 | if (Q_UNLIKELY(!ok)) { | ||
297 | 135 | m_db.rollback(); | ||
298 | 136 | return false; | ||
299 | 137 | } | ||
300 | 138 | |||
301 | 139 | return m_db.commit(); | ||
302 | 140 | } | ||
303 | 141 | |||
304 | 142 | bool ChromeCookieStore::doSetCookies(const Cookies& cookies) | ||
305 | 143 | { | ||
306 | 144 | m_db.setDatabaseName(m_dbPath); | ||
307 | 145 | |||
308 | 146 | if (!m_db.open()) { | ||
309 | 147 | qCritical() << "Could not open cookie database:" << | ||
310 | 148 | m_dbPath << m_db.lastError().text(); | ||
311 | 149 | return false; | ||
312 | 150 | } | ||
313 | 151 | |||
314 | 152 | QSqlQuery q(m_db); | ||
315 | 153 | // Check whether the table already exists | ||
316 | 154 | q.exec("SELECT name FROM sqlite_master WHERE type='table' AND name='cookies'"); | ||
317 | 155 | if (!q.next() && !createDb()) { | ||
318 | 156 | qCritical() << "Could not create cookie database:" << | ||
319 | 157 | m_dbPath << m_db.lastError().text(); | ||
320 | 158 | return false; | ||
321 | 159 | } | ||
322 | 160 | |||
323 | 161 | QList<QNetworkCookie> parsedCookies; | ||
324 | 162 | |||
325 | 163 | Q_FOREACH(const QByteArray &cookie, cookies) { | ||
326 | 164 | parsedCookies.append(QNetworkCookie::parseCookies(cookie)); | ||
327 | 165 | } | ||
328 | 166 | |||
329 | 167 | q.prepare("INSERT INTO cookies (creation_utc," | ||
330 | 168 | "host_key, name, value, path," | ||
331 | 169 | "expires_utc, secure, httponly, last_access_utc," | ||
332 | 170 | "has_expires, persistent, priority, encrypted_value) " | ||
333 | 171 | "VALUES (:creation_utc," | ||
334 | 172 | ":host_key, :name, :value, :path," | ||
335 | 173 | ":expires_utc, :secure, :httponly, :last_access_utc," | ||
336 | 174 | ":has_expires, :persistent, :priority, :encrypted_value)"); | ||
337 | 175 | Q_FOREACH(const QNetworkCookie &cookie, parsedCookies) { | ||
338 | 176 | q.bindValue(":creation_utc", | ||
339 | 177 | dateTimeToChrome(QDateTime::currentDateTimeUtc())); | ||
340 | 178 | q.bindValue(":host_key", cookie.domain()); | ||
341 | 179 | q.bindValue(":name", cookie.name()); | ||
342 | 180 | q.bindValue(":value", cookie.value()); | ||
343 | 181 | q.bindValue(":path", cookie.path()); | ||
344 | 182 | q.bindValue(":expires_utc", | ||
345 | 183 | dateTimeToChrome(cookie.expirationDate().toUTC())); | ||
346 | 184 | q.bindValue(":secure", cookie.isSecure()); | ||
347 | 185 | q.bindValue(":httponly", cookie.isHttpOnly()); | ||
348 | 186 | q.bindValue(":last_access_utc", | ||
349 | 187 | dateTimeToChrome(QDateTime::currentDateTimeUtc())); | ||
350 | 188 | q.bindValue(":has_expires", cookie.expirationDate().isValid()); | ||
351 | 189 | q.bindValue(":persistent", true); | ||
352 | 190 | q.bindValue(":priority", 1); | ||
353 | 191 | q.bindValue(":encrypted_value", 1); | ||
354 | 192 | q.exec(); | ||
355 | 193 | } | ||
356 | 194 | |||
357 | 195 | m_db.close(); | ||
358 | 196 | |||
359 | 197 | return true; | ||
360 | 198 | } | ||
361 | 199 | |||
362 | 200 | void ChromeCookieStore::setDbPath(const QString &path) | ||
363 | 201 | { | ||
364 | 202 | // If path is a URL, strip the initial "file://" | ||
365 | 203 | QString normalizedPath = path.startsWith("file://") ? path.mid(7) : path; | ||
366 | 204 | |||
367 | 205 | if (normalizedPath != m_dbPath) { | ||
368 | 206 | if (Q_UNLIKELY(!normalizedPath.startsWith('/'))) { | ||
369 | 207 | qWarning() << "Invalid database path (must be absolute):" << path; | ||
370 | 208 | return; | ||
371 | 209 | } | ||
372 | 210 | m_dbPath = normalizedPath; | ||
373 | 211 | Q_EMIT dbPathChanged(); | ||
374 | 212 | } | ||
375 | 213 | } | ||
376 | 214 | |||
377 | 215 | QString ChromeCookieStore::dbPath () const | ||
378 | 216 | { | ||
379 | 217 | return m_dbPath; | ||
380 | 218 | } | ||
381 | 0 | 219 | ||
382 | === added file 'src/app/webcontainer/chrome-cookie-store.h' | |||
383 | --- src/app/webcontainer/chrome-cookie-store.h 1970-01-01 00:00:00 +0000 | |||
384 | +++ src/app/webcontainer/chrome-cookie-store.h 2014-06-02 11:59:43 +0000 | |||
385 | @@ -0,0 +1,53 @@ | |||
386 | 1 | /* | ||
387 | 2 | * Copyright 2014 Canonical Ltd. | ||
388 | 3 | * | ||
389 | 4 | * This file is part of webbrowser-app. | ||
390 | 5 | * | ||
391 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
392 | 7 | * it under the terms of the GNU General Public License as published by | ||
393 | 8 | * the Free Software Foundation; version 3. | ||
394 | 9 | * | ||
395 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
396 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
397 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
398 | 13 | * GNU General Public License for more details. | ||
399 | 14 | * | ||
400 | 15 | * You should have received a copy of the GNU General Public License | ||
401 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
402 | 17 | */ | ||
403 | 18 | |||
404 | 19 | #ifndef CHROME_COOKIE_STORE_H | ||
405 | 20 | #define CHROME_COOKIE_STORE_H | ||
406 | 21 | |||
407 | 22 | #include "cookie-store.h" | ||
408 | 23 | |||
409 | 24 | #include <QSqlDatabase> | ||
410 | 25 | |||
411 | 26 | class ChromeCookieStore : public CookieStore | ||
412 | 27 | { | ||
413 | 28 | Q_OBJECT | ||
414 | 29 | Q_PROPERTY(QString dbPath READ dbPath WRITE setDbPath NOTIFY dbPathChanged) | ||
415 | 30 | |||
416 | 31 | public: | ||
417 | 32 | ChromeCookieStore(QObject* parent = 0); | ||
418 | 33 | |||
419 | 34 | void setDbPath(const QString& path); | ||
420 | 35 | QString dbPath() const; | ||
421 | 36 | |||
422 | 37 | QDateTime lastUpdateTimeStamp() const Q_DECL_OVERRIDE; | ||
423 | 38 | |||
424 | 39 | Q_SIGNALS: | ||
425 | 40 | void dbPathChanged(); | ||
426 | 41 | |||
427 | 42 | private: | ||
428 | 43 | virtual Cookies doGetCookies() Q_DECL_OVERRIDE; | ||
429 | 44 | virtual bool doSetCookies(const Cookies& cookies) Q_DECL_OVERRIDE; | ||
430 | 45 | |||
431 | 46 | bool createDb(); | ||
432 | 47 | |||
433 | 48 | private: | ||
434 | 49 | QString m_dbPath; | ||
435 | 50 | QSqlDatabase m_db; | ||
436 | 51 | }; | ||
437 | 52 | |||
438 | 53 | #endif // CHROME_COOKIE_STORE_H | ||
439 | 0 | 54 | ||
440 | === renamed file 'src/app/webcontainer/cookiestore.cpp' => 'src/app/webcontainer/cookie-store.cpp' | |||
441 | --- src/app/webcontainer/cookiestore.cpp 2014-01-27 22:58:55 +0000 | |||
442 | +++ src/app/webcontainer/cookie-store.cpp 2014-06-02 11:59:43 +0000 | |||
443 | @@ -1,5 +1,5 @@ | |||
444 | 1 | /* | 1 | /* |
446 | 2 | * Copyright 2013 Canonical Ltd. | 2 | * Copyright 2014 Canonical Ltd. |
447 | 3 | * | 3 | * |
448 | 4 | * This file is part of webbrowser-app. | 4 | * This file is part of webbrowser-app. |
449 | 5 | * | 5 | * |
450 | @@ -18,10 +18,10 @@ | |||
451 | 18 | 18 | ||
452 | 19 | #include <QDebug> | 19 | #include <QDebug> |
453 | 20 | 20 | ||
455 | 21 | #include "cookiestore.h" | 21 | #include "cookie-store.h" |
456 | 22 | 22 | ||
459 | 23 | CookieStore::CookieStore(QObject *parent) | 23 | CookieStore::CookieStore(QObject* parent): |
460 | 24 | : QObject(parent) | 24 | QObject(parent) |
461 | 25 | { | 25 | { |
462 | 26 | qRegisterMetaType<Cookies>("Cookies"); | 26 | qRegisterMetaType<Cookies>("Cookies"); |
463 | 27 | } | 27 | } |
464 | @@ -31,19 +31,26 @@ | |||
465 | 31 | return doGetCookies(); | 31 | return doGetCookies(); |
466 | 32 | } | 32 | } |
467 | 33 | 33 | ||
469 | 34 | void CookieStore::setCookies(Cookies cookies) | 34 | bool CookieStore::setCookies(const Cookies& cookies) |
470 | 35 | { | 35 | { |
472 | 36 | doSetCookies(cookies); | 36 | if (doSetCookies(cookies)) { |
473 | 37 | Q_EMIT cookiesChanged(); | ||
474 | 38 | return true; | ||
475 | 39 | } else { | ||
476 | 40 | return false; | ||
477 | 41 | } | ||
478 | 37 | } | 42 | } |
479 | 38 | 43 | ||
480 | 39 | Cookies CookieStore::doGetCookies() | 44 | Cookies CookieStore::doGetCookies() |
481 | 40 | { | 45 | { |
482 | 46 | Q_UNIMPLEMENTED(); | ||
483 | 41 | return Cookies(); | 47 | return Cookies(); |
484 | 42 | } | 48 | } |
485 | 43 | 49 | ||
487 | 44 | void CookieStore::doSetCookies(Cookies cookies) | 50 | bool CookieStore::doSetCookies(const Cookies& cookies) |
488 | 45 | { | 51 | { |
489 | 46 | Q_UNUSED(cookies); | 52 | Q_UNUSED(cookies); |
490 | 53 | Q_UNIMPLEMENTED(); | ||
491 | 47 | } | 54 | } |
492 | 48 | 55 | ||
493 | 49 | QDateTime CookieStore::lastUpdateTimeStamp() const | 56 | QDateTime CookieStore::lastUpdateTimeStamp() const |
494 | @@ -51,33 +58,32 @@ | |||
495 | 51 | return _lastUpdateTimeStamp; | 58 | return _lastUpdateTimeStamp; |
496 | 52 | } | 59 | } |
497 | 53 | 60 | ||
499 | 54 | void CookieStore::updateLastUpdateTimestamp(const QDateTime & timestamp) | 61 | void CookieStore::updateLastUpdateTimestamp(const QDateTime& timestamp) |
500 | 55 | { | 62 | { |
501 | 56 | _lastUpdateTimeStamp = timestamp; | 63 | _lastUpdateTimeStamp = timestamp; |
502 | 57 | } | 64 | } |
503 | 58 | 65 | ||
505 | 59 | void CookieStore::moveFrom(CookieStore *store) | 66 | void CookieStore::moveFrom(CookieStore* store) |
506 | 60 | { | 67 | { |
508 | 61 | if (! store) | 68 | if (Q_UNLIKELY(!store)) |
509 | 62 | return; | 69 | return; |
510 | 63 | 70 | ||
523 | 64 | Cookies cookies = | 71 | Cookies cookies = store->cookies(); |
524 | 65 | store->cookies(); | 72 | |
525 | 66 | 73 | QDateTime lastRemoteCookieUpdate = store->lastUpdateTimeStamp(); | |
526 | 67 | QDateTime lastRemoteCookieUpdate = | 74 | QDateTime lastLocalCookieUpdate = lastUpdateTimeStamp(); |
527 | 68 | store->lastUpdateTimeStamp(); | 75 | |
528 | 69 | 76 | if (lastRemoteCookieUpdate.isValid() && | |
529 | 70 | QDateTime lastLocalCookieUpdate = | 77 | lastLocalCookieUpdate.isValid() && |
530 | 71 | lastUpdateTimeStamp(); | 78 | (lastRemoteCookieUpdate < lastLocalCookieUpdate)) |
519 | 72 | |||
520 | 73 | if (lastRemoteCookieUpdate.isValid() | ||
521 | 74 | && lastLocalCookieUpdate.isValid() | ||
522 | 75 | && (lastRemoteCookieUpdate < lastLocalCookieUpdate)) | ||
531 | 76 | { | 79 | { |
532 | 77 | Q_EMIT moved(false); | 80 | Q_EMIT moved(false); |
533 | 78 | return; | 81 | return; |
534 | 79 | } | 82 | } |
535 | 80 | 83 | ||
537 | 81 | setCookies(cookies); | 84 | if (setCookies(cookies)) { |
538 | 85 | Q_EMIT moved(true); | ||
539 | 86 | } else { | ||
540 | 87 | Q_EMIT moved(false); | ||
541 | 88 | } | ||
542 | 82 | } | 89 | } |
543 | 83 | |||
544 | 84 | 90 | ||
545 | === renamed file 'src/app/webcontainer/cookiestore.h' => 'src/app/webcontainer/cookie-store.h' | |||
546 | --- src/app/webcontainer/cookiestore.h 2014-01-27 22:58:55 +0000 | |||
547 | +++ src/app/webcontainer/cookie-store.h 2014-06-02 11:59:43 +0000 | |||
548 | @@ -1,5 +1,5 @@ | |||
549 | 1 | /* | 1 | /* |
551 | 2 | * Copyright 2013 Canonical Ltd. | 2 | * Copyright 2014 Canonical Ltd. |
552 | 3 | * | 3 | * |
553 | 4 | * This file is part of webbrowser-app. | 4 | * This file is part of webbrowser-app. |
554 | 5 | * | 5 | * |
555 | @@ -16,62 +16,50 @@ | |||
556 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
557 | 17 | */ | 17 | */ |
558 | 18 | 18 | ||
561 | 19 | #ifndef __COOKIESTORE_H__ | 19 | #ifndef __COOKIE_STORE_H__ |
562 | 20 | #define __COOKIESTORE_H__ | 20 | #define __COOKIE_STORE_H__ |
563 | 21 | 21 | ||
564 | 22 | #include <QByteArray> | ||
565 | 23 | #include <QDateTime> | ||
566 | 24 | #include <QList> | ||
567 | 22 | #include <QObject> | 25 | #include <QObject> |
568 | 23 | #include <QtCore/QList> | ||
569 | 24 | #include <QtCore/QString> | ||
570 | 25 | #include <QDateTime> | ||
571 | 26 | #include <QString> | ||
572 | 27 | #include <QMap> | ||
573 | 28 | 26 | ||
575 | 29 | typedef QMap<QString, QString> Cookies; | 27 | typedef QList<QByteArray> Cookies; |
576 | 30 | Q_DECLARE_METATYPE(Cookies); | 28 | Q_DECLARE_METATYPE(Cookies); |
577 | 31 | 29 | ||
578 | 32 | 30 | ||
579 | 33 | class CookieStore : public QObject | 31 | class CookieStore : public QObject |
580 | 34 | { | 32 | { |
581 | 35 | Q_OBJECT | 33 | Q_OBJECT |
584 | 36 | Q_PROPERTY(Cookies cookies READ \ | 34 | Q_PROPERTY(Cookies cookies READ cookies WRITE setCookies \ |
583 | 37 | cookies WRITE setCookies \ | ||
585 | 38 | NOTIFY cookiesChanged) | 35 | NOTIFY cookiesChanged) |
588 | 39 | Q_PROPERTY(QDateTime lastUpdateTimeStamp \ | 36 | Q_PROPERTY(QDateTime lastUpdateTimeStamp READ lastUpdateTimeStamp \ |
587 | 40 | READ lastUpdateTimeStamp \ | ||
589 | 41 | NOTIFY lastUpdateTimeStampChanged) | 37 | NOTIFY lastUpdateTimeStampChanged) |
590 | 42 | 38 | ||
591 | 43 | public: | 39 | public: |
595 | 44 | 40 | CookieStore(QObject* parent = 0); | |
596 | 45 | CookieStore(QObject *parent = 0); | 41 | |
597 | 46 | 42 | bool setCookies(const Cookies& cookies); | |
598 | 47 | Cookies cookies(); | 43 | Cookies cookies(); |
599 | 48 | void setCookies(Cookies); | ||
600 | 49 | 44 | ||
601 | 50 | virtual QDateTime lastUpdateTimeStamp() const; | 45 | virtual QDateTime lastUpdateTimeStamp() const; |
602 | 51 | 46 | ||
604 | 52 | Q_INVOKABLE void moveFrom (CookieStore * store); | 47 | Q_INVOKABLE void moveFrom(CookieStore* store); |
605 | 53 | 48 | ||
606 | 54 | Q_SIGNALS: | 49 | Q_SIGNALS: |
607 | 55 | |||
608 | 56 | void moved(bool); | 50 | void moved(bool); |
609 | 57 | void cookiesChanged(); | 51 | void cookiesChanged(); |
610 | 58 | void lastUpdateTimeStampChanged(); | 52 | void lastUpdateTimeStampChanged(); |
611 | 59 | 53 | ||
612 | 60 | protected: | 54 | protected: |
616 | 61 | 55 | void updateLastUpdateTimestamp(const QDateTime& timestamp); | |
614 | 62 | void updateLastUpdateTimestamp(const QDateTime & timestamp); | ||
615 | 63 | |||
617 | 64 | 56 | ||
618 | 65 | private: | 57 | private: |
619 | 66 | |||
620 | 67 | virtual Cookies doGetCookies(); | 58 | virtual Cookies doGetCookies(); |
622 | 68 | virtual void doSetCookies(Cookies); | 59 | virtual bool doSetCookies(const Cookies& Cookies); |
623 | 69 | 60 | ||
624 | 70 | private: | 61 | private: |
625 | 71 | |||
626 | 72 | QDateTime _lastUpdateTimeStamp; | 62 | QDateTime _lastUpdateTimeStamp; |
627 | 73 | }; | 63 | }; |
628 | 74 | 64 | ||
632 | 75 | 65 | #endif // __COOKIE_STORE_H__ | |
630 | 76 | #endif // __COOKIESTORE_H__ | ||
631 | 77 | |||
633 | 78 | 66 | ||
634 | === renamed file 'src/app/webcontainer/onlineaccountscookiestore.cpp' => 'src/app/webcontainer/online-accounts-cookie-store.cpp' | |||
635 | --- src/app/webcontainer/onlineaccountscookiestore.cpp 2014-01-27 22:58:55 +0000 | |||
636 | +++ src/app/webcontainer/online-accounts-cookie-store.cpp 2014-06-02 11:59:43 +0000 | |||
637 | @@ -1,5 +1,5 @@ | |||
638 | 1 | /* | 1 | /* |
640 | 2 | * Copyright 2013 Canonical Ltd. | 2 | * Copyright 2013-2014 Canonical Ltd. |
641 | 3 | * | 3 | * |
642 | 4 | * This file is part of webbrowser-app. | 4 | * This file is part of webbrowser-app. |
643 | 5 | * | 5 | * |
644 | @@ -16,7 +16,7 @@ | |||
645 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
646 | 17 | */ | 17 | */ |
647 | 18 | 18 | ||
649 | 19 | #include "onlineaccountscookiestore.h" | 19 | #include "online-accounts-cookie-store.h" |
650 | 20 | 20 | ||
651 | 21 | #include <QList> | 21 | #include <QList> |
652 | 22 | #include <QVariant> | 22 | #include <QVariant> |
653 | @@ -44,15 +44,12 @@ | |||
654 | 44 | # define ONLINE_ACCOUNTS_COOKIE_STORE_METHOD "cookiesForIdentity" | 44 | # define ONLINE_ACCOUNTS_COOKIE_STORE_METHOD "cookiesForIdentity" |
655 | 45 | #endif | 45 | #endif |
656 | 46 | 46 | ||
658 | 47 | class OnlineAccountsCookieStorePrivate : public QObject | 47 | class OnlineAccountsCookieStorePrivate |
659 | 48 | { | 48 | { |
660 | 49 | Q_OBJECT | ||
661 | 50 | |||
662 | 51 | public: | 49 | public: |
667 | 52 | OnlineAccountsCookieStorePrivate (QObject * parent = 0) | 50 | OnlineAccountsCookieStorePrivate(): |
668 | 53 | : QObject(parent), | 51 | _id(0), |
669 | 54 | _id (0), | 52 | m_connection(QDBusConnection::sessionBus()) |
666 | 55 | m_connection (QDBusConnection::sessionBus()) | ||
670 | 56 | {} | 53 | {} |
671 | 57 | 54 | ||
672 | 58 | quint32 _id; | 55 | quint32 _id; |
673 | @@ -135,9 +132,8 @@ | |||
674 | 135 | return qdbus_cast<Cookies>(arguments.front()); | 132 | return qdbus_cast<Cookies>(arguments.front()); |
675 | 136 | } | 133 | } |
676 | 137 | 134 | ||
678 | 138 | void OnlineAccountsCookieStore::doSetCookies(Cookies cookies) | 135 | bool OnlineAccountsCookieStore::doSetCookies(const Cookies& cookies) |
679 | 139 | { | 136 | { |
680 | 140 | Q_UNUSED(cookies); | 137 | Q_UNUSED(cookies); |
681 | 138 | return false; | ||
682 | 141 | } | 139 | } |
683 | 142 | |||
684 | 143 | #include "onlineaccountscookiestore.moc" | ||
685 | 144 | 140 | ||
686 | === renamed file 'src/app/webcontainer/onlineaccountscookiestore.h' => 'src/app/webcontainer/online-accounts-cookie-store.h' | |||
687 | --- src/app/webcontainer/onlineaccountscookiestore.h 2014-01-27 22:58:55 +0000 | |||
688 | +++ src/app/webcontainer/online-accounts-cookie-store.h 2014-06-02 11:59:43 +0000 | |||
689 | @@ -1,5 +1,5 @@ | |||
690 | 1 | /* | 1 | /* |
692 | 2 | * Copyright 2013 Canonical Ltd. | 2 | * Copyright 2013-2014 Canonical Ltd. |
693 | 3 | * | 3 | * |
694 | 4 | * This file is part of webbrowser-app. | 4 | * This file is part of webbrowser-app. |
695 | 5 | * | 5 | * |
696 | @@ -16,10 +16,10 @@ | |||
697 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
698 | 17 | */ | 17 | */ |
699 | 18 | 18 | ||
702 | 19 | #ifndef ONLINEACCOUNTSCOOKIESTORE_H | 19 | #ifndef ONLINE_ACCOUNTS_COOKIE_STORE_H |
703 | 20 | #define ONLINEACCOUNTSCOOKIESTORE_H | 20 | #define ONLINE_ACCOUNTS_COOKIE_STORE_H |
704 | 21 | 21 | ||
706 | 22 | #include "cookiestore.h" | 22 | #include "cookie-store.h" |
707 | 23 | 23 | ||
708 | 24 | class OnlineAccountsCookieStorePrivate; | 24 | class OnlineAccountsCookieStorePrivate; |
709 | 25 | 25 | ||
710 | @@ -45,7 +45,7 @@ | |||
711 | 45 | private: | 45 | private: |
712 | 46 | 46 | ||
713 | 47 | virtual Cookies doGetCookies() Q_DECL_OVERRIDE; | 47 | virtual Cookies doGetCookies() Q_DECL_OVERRIDE; |
715 | 48 | virtual void doSetCookies(Cookies) Q_DECL_OVERRIDE; | 48 | virtual bool doSetCookies(const Cookies& cookies) Q_DECL_OVERRIDE; |
716 | 49 | 49 | ||
717 | 50 | 50 | ||
718 | 51 | private: | 51 | private: |
719 | @@ -54,4 +54,4 @@ | |||
720 | 54 | Q_DECLARE_PRIVATE(OnlineAccountsCookieStore) | 54 | Q_DECLARE_PRIVATE(OnlineAccountsCookieStore) |
721 | 55 | }; | 55 | }; |
722 | 56 | 56 | ||
724 | 57 | #endif // ONLINEACCOUNTSCOOKIESTORE_H | 57 | #endif // ONLINE_ACCOUNTS_COOKIE_STORE_H |
725 | 58 | 58 | ||
726 | === removed file 'src/app/webcontainer/sqlitecookiestore.cpp' | |||
727 | --- src/app/webcontainer/sqlitecookiestore.cpp 2014-02-07 16:44:50 +0000 | |||
728 | +++ src/app/webcontainer/sqlitecookiestore.cpp 1970-01-01 00:00:00 +0000 | |||
729 | @@ -1,99 +0,0 @@ | |||
730 | 1 | /* | ||
731 | 2 | * Copyright 2013 Canonical Ltd. | ||
732 | 3 | * | ||
733 | 4 | * This file is part of webbrowser-app. | ||
734 | 5 | * | ||
735 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
736 | 7 | * it under the terms of the GNU General Public License as published by | ||
737 | 8 | * the Free Software Foundation; version 3. | ||
738 | 9 | * | ||
739 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
740 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
741 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
742 | 13 | * GNU General Public License for more details. | ||
743 | 14 | * | ||
744 | 15 | * You should have received a copy of the GNU General Public License | ||
745 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
746 | 17 | */ | ||
747 | 18 | |||
748 | 19 | #include "sqlitecookiestore.h" | ||
749 | 20 | |||
750 | 21 | #include <QSqlDatabase> | ||
751 | 22 | #include <QSqlError> | ||
752 | 23 | #include <QSqlQuery> | ||
753 | 24 | #include <QFileInfo> | ||
754 | 25 | #include <QStandardPaths> | ||
755 | 26 | #include <QDebug> | ||
756 | 27 | |||
757 | 28 | |||
758 | 29 | SqliteCookieStore::SqliteCookieStore(QObject *parent) | ||
759 | 30 | : CookieStore(parent) | ||
760 | 31 | {} | ||
761 | 32 | |||
762 | 33 | Cookies SqliteCookieStore::doGetCookies() | ||
763 | 34 | { | ||
764 | 35 | return Cookies(); | ||
765 | 36 | } | ||
766 | 37 | |||
767 | 38 | QDateTime SqliteCookieStore::lastUpdateTimeStamp() const | ||
768 | 39 | { | ||
769 | 40 | QFileInfo dbFileInfo(getFullDbPathName ()); | ||
770 | 41 | return dbFileInfo.lastModified(); | ||
771 | 42 | } | ||
772 | 43 | |||
773 | 44 | void SqliteCookieStore::doSetCookies(Cookies cookies) | ||
774 | 45 | { | ||
775 | 46 | QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); | ||
776 | 47 | db.setDatabaseName (getFullDbPathName ()); | ||
777 | 48 | |||
778 | 49 | if ( ! db.open()) | ||
779 | 50 | { | ||
780 | 51 | qCritical() << "Could not open cookie database: " << getFullDbPathName() << db.lastError(); | ||
781 | 52 | Q_EMIT moved(false); | ||
782 | 53 | return; | ||
783 | 54 | } | ||
784 | 55 | |||
785 | 56 | QSqlQuery q(db); | ||
786 | 57 | q.exec("CREATE TABLE IF NOT EXISTS cookies " | ||
787 | 58 | "(cookieId VARCHAR PRIMARY KEY, cookie BLOB)"); | ||
788 | 59 | q.exec ("DELETE FROM cookies;"); | ||
789 | 60 | |||
790 | 61 | q.prepare("INSERT INTO cookies (cookieId, cookie) " | ||
791 | 62 | "VALUES (:cookieId, :cookie)"); | ||
792 | 63 | |||
793 | 64 | for (Cookies::const_iterator it = cookies.constBegin(); | ||
794 | 65 | it != cookies.constEnd(); | ||
795 | 66 | ++it) | ||
796 | 67 | { | ||
797 | 68 | q.bindValue(":cookieId", it.key()); | ||
798 | 69 | q.bindValue(":cookie", it.value()); | ||
799 | 70 | |||
800 | 71 | if ( ! q.exec()) | ||
801 | 72 | { | ||
802 | 73 | qWarning() << "Couldn't insert cookie into DB" | ||
803 | 74 | << it.key(); | ||
804 | 75 | } | ||
805 | 76 | } | ||
806 | 77 | |||
807 | 78 | Q_EMIT moved(true); | ||
808 | 79 | } | ||
809 | 80 | |||
810 | 81 | QString SqliteCookieStore::getFullDbPathName() const | ||
811 | 82 | { | ||
812 | 83 | return QStandardPaths::standardLocations(QStandardPaths::HomeLocation)[0] + "/" + dbPath(); | ||
813 | 84 | } | ||
814 | 85 | |||
815 | 86 | void SqliteCookieStore::setDbPath(const QString &path) | ||
816 | 87 | { | ||
817 | 88 | if (path != m_dbPath) | ||
818 | 89 | { | ||
819 | 90 | m_dbPath = path; | ||
820 | 91 | Q_EMIT dbPathChanged(); | ||
821 | 92 | } | ||
822 | 93 | } | ||
823 | 94 | |||
824 | 95 | QString SqliteCookieStore::dbPath () const | ||
825 | 96 | { | ||
826 | 97 | return m_dbPath; | ||
827 | 98 | } | ||
828 | 99 | |||
829 | 100 | 0 | ||
830 | === removed file 'src/app/webcontainer/sqlitecookiestore.h' | |||
831 | --- src/app/webcontainer/sqlitecookiestore.h 2014-01-27 22:58:55 +0000 | |||
832 | +++ src/app/webcontainer/sqlitecookiestore.h 1970-01-01 00:00:00 +0000 | |||
833 | @@ -1,58 +0,0 @@ | |||
834 | 1 | /* | ||
835 | 2 | * Copyright 2013 Canonical Ltd. | ||
836 | 3 | * | ||
837 | 4 | * This file is part of webbrowser-app. | ||
838 | 5 | * | ||
839 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
840 | 7 | * it under the terms of the GNU General Public License as published by | ||
841 | 8 | * the Free Software Foundation; version 3. | ||
842 | 9 | * | ||
843 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
844 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
845 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
846 | 13 | * GNU General Public License for more details. | ||
847 | 14 | * | ||
848 | 15 | * You should have received a copy of the GNU General Public License | ||
849 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
850 | 17 | */ | ||
851 | 18 | |||
852 | 19 | #ifndef SQLITECOOKIESTORE_H | ||
853 | 20 | #define SQLITECOOKIESTORE_H | ||
854 | 21 | |||
855 | 22 | #include "cookiestore.h" | ||
856 | 23 | #include <QString> | ||
857 | 24 | |||
858 | 25 | |||
859 | 26 | class SqliteCookieStore : public CookieStore | ||
860 | 27 | { | ||
861 | 28 | Q_OBJECT | ||
862 | 29 | Q_PROPERTY(QString dbPath READ dbPath WRITE setDbPath NOTIFY dbPathChanged) | ||
863 | 30 | |||
864 | 31 | |||
865 | 32 | public: | ||
866 | 33 | SqliteCookieStore(QObject *parent = 0); | ||
867 | 34 | |||
868 | 35 | void setDbPath (const QString & path); | ||
869 | 36 | QString dbPath () const; | ||
870 | 37 | |||
871 | 38 | QDateTime lastUpdateTimeStamp() const Q_DECL_OVERRIDE; | ||
872 | 39 | |||
873 | 40 | |||
874 | 41 | Q_SIGNALS: | ||
875 | 42 | |||
876 | 43 | void dbPathChanged(); | ||
877 | 44 | |||
878 | 45 | |||
879 | 46 | private: | ||
880 | 47 | |||
881 | 48 | virtual Cookies doGetCookies() Q_DECL_OVERRIDE; | ||
882 | 49 | virtual void doSetCookies(Cookies) Q_DECL_OVERRIDE; | ||
883 | 50 | |||
884 | 51 | QString getFullDbPathName() const; | ||
885 | 52 | |||
886 | 53 | |||
887 | 54 | private: | ||
888 | 55 | QString m_dbPath; | ||
889 | 56 | }; | ||
890 | 57 | |||
891 | 58 | #endif // SQLITECOOKIESTORE_H | ||
892 | 59 | 0 | ||
893 | === modified file 'src/app/webcontainer/webapp-container.cpp' | |||
894 | --- src/app/webcontainer/webapp-container.cpp 2014-05-08 16:51:08 +0000 | |||
895 | +++ src/app/webcontainer/webapp-container.cpp 2014-06-02 11:59:43 +0000 | |||
896 | @@ -19,8 +19,11 @@ | |||
897 | 19 | #include "config.h" | 19 | #include "config.h" |
898 | 20 | #include "webapp-container.h" | 20 | #include "webapp-container.h" |
899 | 21 | 21 | ||
900 | 22 | #include "chrome-cookie-store.h" | ||
901 | 23 | #include "online-accounts-cookie-store.h" | ||
902 | 22 | #include "session-utils.h" | 24 | #include "session-utils.h" |
903 | 23 | #include "url-pattern-utils.h" | 25 | #include "url-pattern-utils.h" |
904 | 26 | #include "webkit-cookie-store.h" | ||
905 | 24 | 27 | ||
906 | 25 | // Qt | 28 | // Qt |
907 | 26 | #include <QtCore/QCoreApplication> | 29 | #include <QtCore/QCoreApplication> |
908 | @@ -30,14 +33,17 @@ | |||
909 | 30 | #include <QtCore/QtGlobal> | 33 | #include <QtCore/QtGlobal> |
910 | 31 | #include <QtCore/QRegularExpression> | 34 | #include <QtCore/QRegularExpression> |
911 | 32 | #include <QtCore/QTextStream> | 35 | #include <QtCore/QTextStream> |
912 | 33 | #include <QtQuick/QQuickWindow> | ||
913 | 34 | #include <QtQml/QQmlComponent> | 36 | #include <QtQml/QQmlComponent> |
914 | 35 | #include <QtQml/QQmlContext> | 37 | #include <QtQml/QQmlContext> |
915 | 36 | #include <QtQml/QQmlEngine> | 38 | #include <QtQml/QQmlEngine> |
916 | 39 | #include <QtQml> | ||
917 | 40 | #include <QtQuick/QQuickWindow> | ||
918 | 37 | 41 | ||
919 | 38 | #include <QStandardPaths> | 42 | #include <QStandardPaths> |
920 | 39 | #include <QSettings> | 43 | #include <QSettings> |
921 | 40 | 44 | ||
922 | 45 | static const char privateModuleUri[] = "webcontainer.private"; | ||
923 | 46 | |||
924 | 41 | namespace | 47 | namespace |
925 | 42 | { | 48 | { |
926 | 43 | 49 | ||
927 | @@ -103,6 +109,7 @@ | |||
928 | 103 | m_window->setProperty("webappName", m_webappName); | 109 | m_window->setProperty("webappName", m_webappName); |
929 | 104 | m_window->setProperty("backForwardButtonsVisible", m_backForwardButtonsVisible); | 110 | m_window->setProperty("backForwardButtonsVisible", m_backForwardButtonsVisible); |
930 | 105 | m_window->setProperty("addressBarVisible", m_addressBarVisible); | 111 | m_window->setProperty("addressBarVisible", m_addressBarVisible); |
931 | 112 | m_window->setProperty("accountProvider", m_accountProvider); | ||
932 | 106 | 113 | ||
933 | 107 | qDebug() << "Using" << (m_withOxide ? "Oxide" : "QtWebkit") << "as the web engine backend"; | 114 | qDebug() << "Using" << (m_withOxide ? "Oxide" : "QtWebkit") << "as the web engine backend"; |
934 | 108 | m_window->setProperty("oxide", m_withOxide); | 115 | m_window->setProperty("oxide", m_withOxide); |
935 | @@ -134,6 +141,18 @@ | |||
936 | 134 | } | 141 | } |
937 | 135 | } | 142 | } |
938 | 136 | 143 | ||
939 | 144 | void WebappContainer::qmlEngineCreated(QQmlEngine* engine) | ||
940 | 145 | { | ||
941 | 146 | if (engine) { | ||
942 | 147 | qmlRegisterType<ChromeCookieStore>(privateModuleUri, 0, 1, | ||
943 | 148 | "ChromeCookieStore"); | ||
944 | 149 | qmlRegisterType<WebkitCookieStore>(privateModuleUri, 0, 1, | ||
945 | 150 | "WebkitCookieStore"); | ||
946 | 151 | qmlRegisterType<OnlineAccountsCookieStore>(privateModuleUri, 0, 1, | ||
947 | 152 | "OnlineAccountsCookieStore"); | ||
948 | 153 | } | ||
949 | 154 | } | ||
950 | 155 | |||
951 | 137 | void WebappContainer::printUsage() const | 156 | void WebappContainer::printUsage() const |
952 | 138 | { | 157 | { |
953 | 139 | QTextStream out(stdout); | 158 | QTextStream out(stdout); |
954 | @@ -147,6 +166,7 @@ | |||
955 | 147 | " [--webapp=name]" | 166 | " [--webapp=name]" |
956 | 148 | " [--webappModelSearchPath=PATH]" | 167 | " [--webappModelSearchPath=PATH]" |
957 | 149 | " [--webappUrlPatterns=URL_PATTERNS]" | 168 | " [--webappUrlPatterns=URL_PATTERNS]" |
958 | 169 | " [--accountProvider=PROVIDER_NAME]" | ||
959 | 150 | " [--enable-back-forward]" | 170 | " [--enable-back-forward]" |
960 | 151 | " [--enable-addressbar]" | 171 | " [--enable-addressbar]" |
961 | 152 | " [--store-session-cookies]" | 172 | " [--store-session-cookies]" |
962 | @@ -162,6 +182,7 @@ | |||
963 | 162 | out << " --webapp=name try to match the webapp by name with an installed integration script" << endl; | 182 | out << " --webapp=name try to match the webapp by name with an installed integration script" << endl; |
964 | 163 | out << " --webappModelSearchPath=PATH alter the search path for installed webapps and set it to PATH. PATH can be an absolute or path relative to CWD" << endl; | 183 | out << " --webappModelSearchPath=PATH alter the search path for installed webapps and set it to PATH. PATH can be an absolute or path relative to CWD" << endl; |
965 | 164 | out << " --webappUrlPatterns=URL_PATTERNS list of comma-separated url patterns (wildcard based) that the webapp is allowed to navigate to" << endl; | 184 | out << " --webappUrlPatterns=URL_PATTERNS list of comma-separated url patterns (wildcard based) that the webapp is allowed to navigate to" << endl; |
966 | 185 | out << " --accountProvider=PROVIDER_NAME Online account provider for the application if the application is to reuse a local account." << endl; | ||
967 | 165 | out << " --store-session-cookies store session cookies on disk" << endl; | 186 | out << " --store-session-cookies store session cookies on disk" << endl; |
968 | 166 | out << "Chrome options (if none specified, no chrome is shown by default):" << endl; | 187 | out << "Chrome options (if none specified, no chrome is shown by default):" << endl; |
969 | 167 | out << " --enable-back-forward enable the display of the back and forward buttons" << endl; | 188 | out << " --enable-back-forward enable the display of the back and forward buttons" << endl; |
970 | @@ -190,6 +211,8 @@ | |||
971 | 190 | QStringList includePatterns = tail.split(URL_PATTERN_SEPARATOR); | 211 | QStringList includePatterns = tail.split(URL_PATTERN_SEPARATOR); |
972 | 191 | m_webappUrlPatterns = UrlPatternUtils::filterAndTransformUrlPatterns(includePatterns); | 212 | m_webappUrlPatterns = UrlPatternUtils::filterAndTransformUrlPatterns(includePatterns); |
973 | 192 | } | 213 | } |
974 | 214 | } else if (argument.startsWith("--accountProvider=")) { | ||
975 | 215 | m_accountProvider = argument.split("--accountProvider=")[1]; | ||
976 | 193 | } else if (argument == "--store-session-cookies") { | 216 | } else if (argument == "--store-session-cookies") { |
977 | 194 | m_storeSessionCookies = true; | 217 | m_storeSessionCookies = true; |
978 | 195 | } else if (argument == "--enable-back-forward") { | 218 | } else if (argument == "--enable-back-forward") { |
979 | 196 | 219 | ||
980 | === modified file 'src/app/webcontainer/webapp-container.h' | |||
981 | --- src/app/webcontainer/webapp-container.h 2014-05-08 16:51:08 +0000 | |||
982 | +++ src/app/webcontainer/webapp-container.h 2014-06-02 11:59:43 +0000 | |||
983 | @@ -34,6 +34,9 @@ | |||
984 | 34 | 34 | ||
985 | 35 | bool initialize(); | 35 | bool initialize(); |
986 | 36 | 36 | ||
987 | 37 | protected: | ||
988 | 38 | void qmlEngineCreated(QQmlEngine *); | ||
989 | 39 | |||
990 | 37 | private: | 40 | private: |
991 | 38 | virtual void printUsage() const; | 41 | virtual void printUsage() const; |
992 | 39 | void parseCommandLine(); | 42 | void parseCommandLine(); |
993 | @@ -44,6 +47,7 @@ | |||
994 | 44 | QString m_webappName; | 47 | QString m_webappName; |
995 | 45 | QString m_webappModelSearchPath; | 48 | QString m_webappModelSearchPath; |
996 | 46 | QStringList m_webappUrlPatterns; | 49 | QStringList m_webappUrlPatterns; |
997 | 50 | QString m_accountProvider; | ||
998 | 47 | bool m_withOxide; | 51 | bool m_withOxide; |
999 | 48 | bool m_storeSessionCookies; | 52 | bool m_storeSessionCookies; |
1000 | 49 | bool m_backForwardButtonsVisible; | 53 | bool m_backForwardButtonsVisible; |
1001 | 50 | 54 | ||
1002 | === modified file 'src/app/webcontainer/webapp-container.qml' | |||
1003 | --- src/app/webcontainer/webapp-container.qml 2014-04-22 15:35:16 +0000 | |||
1004 | +++ src/app/webcontainer/webapp-container.qml 2014-06-02 11:59:43 +0000 | |||
1005 | @@ -1,5 +1,5 @@ | |||
1006 | 1 | /* | 1 | /* |
1008 | 2 | * Copyright 2013 Canonical Ltd. | 2 | * Copyright 2013-2014 Canonical Ltd. |
1009 | 3 | * | 3 | * |
1010 | 4 | * This file is part of webbrowser-app. | 4 | * This file is part of webbrowser-app. |
1011 | 5 | * | 5 | * |
1012 | @@ -19,22 +19,27 @@ | |||
1013 | 19 | import QtQuick 2.0 | 19 | import QtQuick 2.0 |
1014 | 20 | import QtQuick.Window 2.0 | 20 | import QtQuick.Window 2.0 |
1015 | 21 | import Ubuntu.Components 0.1 | 21 | import Ubuntu.Components 0.1 |
1016 | 22 | import Ubuntu.Components.Extras.Browser 0.2 | ||
1017 | 23 | import webcontainer.private 0.1 | ||
1018 | 22 | 24 | ||
1019 | 23 | Window { | 25 | Window { |
1020 | 26 | id: root | ||
1021 | 24 | objectName: "webappContainer" | 27 | objectName: "webappContainer" |
1022 | 25 | 28 | ||
1035 | 26 | property alias developerExtrasEnabled: browser.developerExtrasEnabled | 29 | property bool developerExtrasEnabled: false |
1036 | 27 | 30 | ||
1037 | 28 | property alias backForwardButtonsVisible: browser.backForwardButtonsVisible | 31 | property bool backForwardButtonsVisible: true |
1038 | 29 | property alias addressBarVisible: browser.addressBarVisible | 32 | property bool addressBarVisible: true |
1039 | 30 | 33 | ||
1040 | 31 | property alias url: browser.url | 34 | property string url: "" |
1041 | 32 | property alias webappName: browser.webappName | 35 | property string webappName: "" |
1042 | 33 | property alias webappModelSearchPath: browser.webappModelSearchPath | 36 | property string webappModelSearchPath: "" |
1043 | 34 | property alias webappUrlPatterns: browser.webappUrlPatterns | 37 | property var webappUrlPatterns |
1044 | 35 | property alias oxide: browser.oxide | 38 | property bool oxide: false |
1045 | 36 | 39 | property string accountProvider: "" | |
1046 | 37 | contentOrientation: browser.screenOrientation | 40 | property var __webappCookieStore: null |
1047 | 41 | |||
1048 | 42 | contentOrientation: Screen.orientation | ||
1049 | 38 | 43 | ||
1050 | 39 | width: 800 | 44 | width: 800 |
1051 | 40 | height: 600 | 45 | height: 600 |
1052 | @@ -42,24 +47,107 @@ | |||
1053 | 42 | title: { | 47 | title: { |
1054 | 43 | if (typeof(webappName) === 'string' && webappName.length !== 0) { | 48 | if (typeof(webappName) === 'string' && webappName.length !== 0) { |
1055 | 44 | return webappName | 49 | return webappName |
1057 | 45 | } else if (browser.title) { | 50 | } else if (webappPageComponentLoader.item && |
1058 | 51 | webappPageComponentLoader.item.title) { | ||
1059 | 46 | // TRANSLATORS: %1 refers to the current page’s title | 52 | // TRANSLATORS: %1 refers to the current page’s title |
1061 | 47 | return i18n.tr("%1 - Ubuntu Web Browser").arg(browser.title) | 53 | return i18n.tr("%1 - Ubuntu Web Browser").arg(webappPageComponentLoader.item.title) |
1062 | 48 | } else { | 54 | } else { |
1063 | 49 | return i18n.tr("Ubuntu Web Browser") | 55 | return i18n.tr("Ubuntu Web Browser") |
1064 | 50 | } | 56 | } |
1065 | 51 | } | 57 | } |
1066 | 52 | 58 | ||
1078 | 53 | WebApp { | 59 | Loader { |
1079 | 54 | id: browser | 60 | id: webappPageComponentLoader |
1080 | 55 | 61 | anchors.fill: parent | |
1081 | 56 | property int screenOrientation: Screen.orientation | 62 | } |
1082 | 57 | 63 | ||
1083 | 58 | chromeless: !backForwardButtonsVisible && !addressBarVisible | 64 | Component { |
1084 | 59 | webbrowserWindow: webbrowserWindowProxy | 65 | id: webappPageComponent |
1085 | 60 | 66 | ||
1086 | 61 | anchors.fill: parent | 67 | WebApp { |
1087 | 62 | 68 | id: browser | |
1088 | 63 | Component.onCompleted: i18n.domain = "webbrowser-app" | 69 | addressBarVisible: root.addressBarVisible |
1089 | 70 | backForwardButtonsVisible: root.backForwardButtonsVisible | ||
1090 | 71 | developerExtrasEnabled: root.developerExtrasEnabled | ||
1091 | 72 | oxide: root.oxide | ||
1092 | 73 | url: root.url | ||
1093 | 74 | webappModelSearchPath: root.webappModelSearchPath | ||
1094 | 75 | webappName: root.webappName | ||
1095 | 76 | webappUrlPatterns: root.webappUrlPatterns | ||
1096 | 77 | |||
1097 | 78 | anchors.fill: parent | ||
1098 | 79 | |||
1099 | 80 | chromeless: !backForwardButtonsVisible && !addressBarVisible | ||
1100 | 81 | webbrowserWindow: webbrowserWindowProxy | ||
1101 | 82 | |||
1102 | 83 | Component.onCompleted: i18n.domain = "webbrowser-app" | ||
1103 | 84 | } | ||
1104 | 85 | } | ||
1105 | 86 | |||
1106 | 87 | Loader { | ||
1107 | 88 | id: accountsPageComponentLoader | ||
1108 | 89 | anchors.fill: parent | ||
1109 | 90 | onStatusChanged: { | ||
1110 | 91 | if (status == Loader.Error) { | ||
1111 | 92 | // Happens on the desktop, if Ubuntu.OnlineAccounts.Client | ||
1112 | 93 | // can't be imported | ||
1113 | 94 | loadWebAppView() | ||
1114 | 95 | } else if (status == Loader.Ready) { | ||
1115 | 96 | item.visible = true | ||
1116 | 97 | } | ||
1117 | 98 | } | ||
1118 | 99 | } | ||
1119 | 100 | |||
1120 | 101 | Connections { | ||
1121 | 102 | target: accountsPageComponentLoader.item | ||
1122 | 103 | onDone: loadWebAppView() | ||
1123 | 104 | } | ||
1124 | 105 | |||
1125 | 106 | Component { | ||
1126 | 107 | id: webkitCookieStoreComponent | ||
1127 | 108 | WebkitCookieStore { | ||
1128 | 109 | dbPath: dataLocation + "/.QtWebKit/cookies.db" | ||
1129 | 110 | } | ||
1130 | 111 | } | ||
1131 | 112 | |||
1132 | 113 | Component { | ||
1133 | 114 | id: chromeCookieStoreComponent | ||
1134 | 115 | ChromeCookieStore { | ||
1135 | 116 | dbPath: dataLocation + "/cookies.sqlite" | ||
1136 | 117 | } | ||
1137 | 118 | } | ||
1138 | 119 | |||
1139 | 120 | Component.onCompleted: updateCurrentView() | ||
1140 | 121 | |||
1141 | 122 | onAccountProviderChanged: updateCurrentView(); | ||
1142 | 123 | |||
1143 | 124 | function updateCurrentView() { | ||
1144 | 125 | // check if we are to display the login view | ||
1145 | 126 | // or directly switch to the webapp view | ||
1146 | 127 | if (accountProvider.length !== 0) { | ||
1147 | 128 | loadLoginView(); | ||
1148 | 129 | } else { | ||
1149 | 130 | loadWebAppView(); | ||
1150 | 131 | } | ||
1151 | 132 | } | ||
1152 | 133 | |||
1153 | 134 | function loadLoginView() { | ||
1154 | 135 | if (!__webappCookieStore) { | ||
1155 | 136 | var cookieStoreComponent = | ||
1156 | 137 | oxide ? chromeCookieStoreComponent : webkitCookieStoreComponent | ||
1157 | 138 | __webappCookieStore = cookieStoreComponent.createObject(this) | ||
1158 | 139 | } | ||
1159 | 140 | accountsPageComponentLoader.setSource("AccountsPage.qml", { | ||
1160 | 141 | "accountProvider": accountProvider, | ||
1161 | 142 | "applicationName": Qt.application.name, | ||
1162 | 143 | "webappCookieStore": __webappCookieStore | ||
1163 | 144 | }) | ||
1164 | 145 | } | ||
1165 | 146 | |||
1166 | 147 | function loadWebAppView() { | ||
1167 | 148 | webappPageComponentLoader.sourceComponent = webappPageComponent; | ||
1168 | 149 | if (accountsPageComponentLoader.item) | ||
1169 | 150 | accountsPageComponentLoader.item.visible = false; | ||
1170 | 151 | webappPageComponentLoader.item.visible = true; | ||
1171 | 64 | } | 152 | } |
1172 | 65 | } | 153 | } |
1173 | 66 | 154 | ||
1174 | === added file 'src/app/webcontainer/webkit-cookie-store.cpp' | |||
1175 | --- src/app/webcontainer/webkit-cookie-store.cpp 1970-01-01 00:00:00 +0000 | |||
1176 | +++ src/app/webcontainer/webkit-cookie-store.cpp 2014-06-02 11:59:43 +0000 | |||
1177 | @@ -0,0 +1,120 @@ | |||
1178 | 1 | /* | ||
1179 | 2 | * Copyright 2014 Canonical Ltd. | ||
1180 | 3 | * | ||
1181 | 4 | * This file is part of webbrowser-app. | ||
1182 | 5 | * | ||
1183 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
1184 | 7 | * it under the terms of the GNU General Public License as published by | ||
1185 | 8 | * the Free Software Foundation; version 3. | ||
1186 | 9 | * | ||
1187 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
1188 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1189 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1190 | 13 | * GNU General Public License for more details. | ||
1191 | 14 | * | ||
1192 | 15 | * You should have received a copy of the GNU General Public License | ||
1193 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1194 | 17 | */ | ||
1195 | 18 | |||
1196 | 19 | #include "webkit-cookie-store.h" | ||
1197 | 20 | |||
1198 | 21 | #include <QDebug> | ||
1199 | 22 | #include <QFileInfo> | ||
1200 | 23 | #include <QNetworkCookie> | ||
1201 | 24 | #include <QSqlError> | ||
1202 | 25 | #include <QSqlQuery> | ||
1203 | 26 | #include <QStandardPaths> | ||
1204 | 27 | |||
1205 | 28 | static int connectionCounter = 0; | ||
1206 | 29 | |||
1207 | 30 | WebkitCookieStore::WebkitCookieStore(QObject* parent): | ||
1208 | 31 | CookieStore(parent) | ||
1209 | 32 | { | ||
1210 | 33 | QString connectionName = | ||
1211 | 34 | QString("webkitCookieStore-%1").arg(connectionCounter++); | ||
1212 | 35 | m_db = QSqlDatabase::addDatabase("QSQLITE", connectionName); | ||
1213 | 36 | } | ||
1214 | 37 | |||
1215 | 38 | Cookies WebkitCookieStore::doGetCookies() | ||
1216 | 39 | { | ||
1217 | 40 | Cookies cookies; | ||
1218 | 41 | m_db.setDatabaseName(m_dbPath); | ||
1219 | 42 | |||
1220 | 43 | if (!m_db.open()) { | ||
1221 | 44 | qCritical() << "Could not open cookie database:" << m_dbPath << m_db.lastError(); | ||
1222 | 45 | return cookies; | ||
1223 | 46 | } | ||
1224 | 47 | |||
1225 | 48 | QSqlQuery q(m_db); | ||
1226 | 49 | q.exec("SELECT cookie FROM cookies;"); | ||
1227 | 50 | |||
1228 | 51 | while (q.next()) { | ||
1229 | 52 | cookies.append(q.value(0).toString().toUtf8()); | ||
1230 | 53 | } | ||
1231 | 54 | |||
1232 | 55 | m_db.close(); | ||
1233 | 56 | return cookies; | ||
1234 | 57 | } | ||
1235 | 58 | |||
1236 | 59 | QDateTime WebkitCookieStore::lastUpdateTimeStamp() const | ||
1237 | 60 | { | ||
1238 | 61 | QFileInfo dbFileInfo(m_dbPath); | ||
1239 | 62 | return dbFileInfo.lastModified(); | ||
1240 | 63 | } | ||
1241 | 64 | |||
1242 | 65 | bool WebkitCookieStore::doSetCookies(const Cookies& cookies) | ||
1243 | 66 | { | ||
1244 | 67 | m_db.setDatabaseName(m_dbPath); | ||
1245 | 68 | |||
1246 | 69 | if (!m_db.open()) { | ||
1247 | 70 | qCritical() << "Could not open cookie database:" << m_dbPath << m_db.lastError(); | ||
1248 | 71 | return false; | ||
1249 | 72 | } | ||
1250 | 73 | |||
1251 | 74 | QSqlQuery q(m_db); | ||
1252 | 75 | q.exec("CREATE TABLE IF NOT EXISTS cookies " | ||
1253 | 76 | "(cookieId VARCHAR PRIMARY KEY, cookie BLOB)"); | ||
1254 | 77 | q.exec ("DELETE FROM cookies;"); | ||
1255 | 78 | |||
1256 | 79 | q.prepare("INSERT INTO cookies (cookieId, cookie) " | ||
1257 | 80 | "VALUES (:cookieId, :cookie)"); | ||
1258 | 81 | |||
1259 | 82 | Q_FOREACH(const QByteArray& cookie, cookies) { | ||
1260 | 83 | /* The unique key is the hostname + the cookie name */ | ||
1261 | 84 | QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie); | ||
1262 | 85 | if (parsed.isEmpty()) continue; | ||
1263 | 86 | |||
1264 | 87 | const QNetworkCookie& c = parsed.first(); | ||
1265 | 88 | q.bindValue(":cookieId", c.domain() + c.name()); | ||
1266 | 89 | q.bindValue(":cookie", cookie); | ||
1267 | 90 | |||
1268 | 91 | if (!q.exec()) { | ||
1269 | 92 | qWarning() << "Couldn't insert cookie into DB" << cookie; | ||
1270 | 93 | } | ||
1271 | 94 | } | ||
1272 | 95 | |||
1273 | 96 | m_db.close(); | ||
1274 | 97 | |||
1275 | 98 | return true; | ||
1276 | 99 | } | ||
1277 | 100 | |||
1278 | 101 | void WebkitCookieStore::setDbPath(const QString& path) | ||
1279 | 102 | { | ||
1280 | 103 | // If path is a URL, strip the initial "file://" | ||
1281 | 104 | QString normalizedPath = path.startsWith("file://") ? path.mid(7) : path; | ||
1282 | 105 | |||
1283 | 106 | if (path != m_dbPath) { | ||
1284 | 107 | if (Q_UNLIKELY(!normalizedPath.startsWith('/'))) { | ||
1285 | 108 | qWarning() << "Invalid database path (must be absolute):" << path; | ||
1286 | 109 | return; | ||
1287 | 110 | } | ||
1288 | 111 | m_dbPath = path; | ||
1289 | 112 | Q_EMIT dbPathChanged(); | ||
1290 | 113 | } | ||
1291 | 114 | } | ||
1292 | 115 | |||
1293 | 116 | QString WebkitCookieStore::dbPath() const | ||
1294 | 117 | { | ||
1295 | 118 | return m_dbPath; | ||
1296 | 119 | } | ||
1297 | 120 | |||
1298 | 0 | 121 | ||
1299 | === added file 'src/app/webcontainer/webkit-cookie-store.h' | |||
1300 | --- src/app/webcontainer/webkit-cookie-store.h 1970-01-01 00:00:00 +0000 | |||
1301 | +++ src/app/webcontainer/webkit-cookie-store.h 2014-06-02 11:59:43 +0000 | |||
1302 | @@ -0,0 +1,51 @@ | |||
1303 | 1 | /* | ||
1304 | 2 | * Copyright 2014 Canonical Ltd. | ||
1305 | 3 | * | ||
1306 | 4 | * This file is part of webbrowser-app. | ||
1307 | 5 | * | ||
1308 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
1309 | 7 | * it under the terms of the GNU General Public License as published by | ||
1310 | 8 | * the Free Software Foundation; version 3. | ||
1311 | 9 | * | ||
1312 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
1313 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1314 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1315 | 13 | * GNU General Public License for more details. | ||
1316 | 14 | * | ||
1317 | 15 | * You should have received a copy of the GNU General Public License | ||
1318 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1319 | 17 | */ | ||
1320 | 18 | |||
1321 | 19 | #ifndef WEBKIT_COOKIE_STORE_H | ||
1322 | 20 | #define WEBKIT_COOKIE_STORE_H | ||
1323 | 21 | |||
1324 | 22 | #include "cookie-store.h" | ||
1325 | 23 | |||
1326 | 24 | #include <QSqlDatabase> | ||
1327 | 25 | |||
1328 | 26 | class WebkitCookieStore : public CookieStore | ||
1329 | 27 | { | ||
1330 | 28 | Q_OBJECT | ||
1331 | 29 | Q_PROPERTY(QString dbPath READ dbPath WRITE setDbPath NOTIFY dbPathChanged) | ||
1332 | 30 | |||
1333 | 31 | public: | ||
1334 | 32 | WebkitCookieStore(QObject* parent = 0); | ||
1335 | 33 | |||
1336 | 34 | void setDbPath(const QString& path); | ||
1337 | 35 | QString dbPath() const; | ||
1338 | 36 | |||
1339 | 37 | QDateTime lastUpdateTimeStamp() const Q_DECL_OVERRIDE; | ||
1340 | 38 | |||
1341 | 39 | Q_SIGNALS: | ||
1342 | 40 | void dbPathChanged(); | ||
1343 | 41 | |||
1344 | 42 | private: | ||
1345 | 43 | virtual Cookies doGetCookies() Q_DECL_OVERRIDE; | ||
1346 | 44 | virtual bool doSetCookies(const Cookies& cookies) Q_DECL_OVERRIDE; | ||
1347 | 45 | |||
1348 | 46 | private: | ||
1349 | 47 | QString m_dbPath; | ||
1350 | 48 | QSqlDatabase m_db; | ||
1351 | 49 | }; | ||
1352 | 50 | |||
1353 | 51 | #endif // WEBKIT_COOKIE_STORE_H | ||
1354 | 0 | 52 | ||
1355 | === modified file 'tests/unittests/CMakeLists.txt' | |||
1356 | --- tests/unittests/CMakeLists.txt 2014-04-03 12:54:12 +0000 | |||
1357 | +++ tests/unittests/CMakeLists.txt 2014-06-02 11:59:43 +0000 | |||
1358 | @@ -10,3 +10,4 @@ | |||
1359 | 10 | add_subdirectory(tabs-model) | 10 | add_subdirectory(tabs-model) |
1360 | 11 | add_subdirectory(bookmarks-model) | 11 | add_subdirectory(bookmarks-model) |
1361 | 12 | add_subdirectory(container-url-patterns) | 12 | add_subdirectory(container-url-patterns) |
1362 | 13 | add_subdirectory(cookie-store) | ||
1363 | 13 | 14 | ||
1364 | === added directory 'tests/unittests/cookie-store' | |||
1365 | === added file 'tests/unittests/cookie-store/CMakeLists.txt' | |||
1366 | --- tests/unittests/cookie-store/CMakeLists.txt 1970-01-01 00:00:00 +0000 | |||
1367 | +++ tests/unittests/cookie-store/CMakeLists.txt 2014-06-02 11:59:43 +0000 | |||
1368 | @@ -0,0 +1,11 @@ | |||
1369 | 1 | set(TEST tst_CookieStoreTests) | ||
1370 | 2 | set(SOURCES | ||
1371 | 3 | ${webapp-container_SOURCE_DIR}/chrome-cookie-store.cpp | ||
1372 | 4 | ${webapp-container_SOURCE_DIR}/cookie-store.cpp | ||
1373 | 5 | ${webapp-container_SOURCE_DIR}/webkit-cookie-store.cpp | ||
1374 | 6 | tst_CookieStore.cpp | ||
1375 | 7 | ) | ||
1376 | 8 | add_executable(${TEST} ${SOURCES}) | ||
1377 | 9 | include_directories(${webapp-container_SOURCE_DIR}) | ||
1378 | 10 | qt5_use_modules(${TEST} Core Network Sql Test) | ||
1379 | 11 | add_test(${TEST} ${CMAKE_CURRENT_BINARY_DIR}/${TEST} -xunitxml -o ${TEST}.xml) | ||
1380 | 0 | 12 | ||
1381 | === added file 'tests/unittests/cookie-store/tst_CookieStore.cpp' | |||
1382 | --- tests/unittests/cookie-store/tst_CookieStore.cpp 1970-01-01 00:00:00 +0000 | |||
1383 | +++ tests/unittests/cookie-store/tst_CookieStore.cpp 2014-06-02 11:59:43 +0000 | |||
1384 | @@ -0,0 +1,189 @@ | |||
1385 | 1 | /* | ||
1386 | 2 | * Copyright 2014 Canonical Ltd. | ||
1387 | 3 | * | ||
1388 | 4 | * This file is part of webbrowser-app. | ||
1389 | 5 | * | ||
1390 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
1391 | 7 | * it under the terms of the GNU General Public License as published by | ||
1392 | 8 | * the Free Software Foundation; version 3. | ||
1393 | 9 | * | ||
1394 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
1395 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1396 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1397 | 13 | * GNU General Public License for more details. | ||
1398 | 14 | * | ||
1399 | 15 | * You should have received a copy of the GNU General Public License | ||
1400 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1401 | 17 | */ | ||
1402 | 18 | |||
1403 | 19 | // Qt | ||
1404 | 20 | #include <QtCore/QDir> | ||
1405 | 21 | #include <QtCore/QSet> | ||
1406 | 22 | #include <QtCore/QTemporaryDir> | ||
1407 | 23 | #include <QtNetwork/QNetworkCookie> | ||
1408 | 24 | #include <QtTest/QSignalSpy> | ||
1409 | 25 | #include <QtTest/QtTest> | ||
1410 | 26 | |||
1411 | 27 | // local | ||
1412 | 28 | #include "chrome-cookie-store.h" | ||
1413 | 29 | #include "webkit-cookie-store.h" | ||
1414 | 30 | |||
1415 | 31 | uint qHash(const QNetworkCookie &cookie, uint seed) | ||
1416 | 32 | { | ||
1417 | 33 | return qHash(cookie.toRawForm(), seed); | ||
1418 | 34 | } | ||
1419 | 35 | |||
1420 | 36 | class CookieStoreTest : public QObject | ||
1421 | 37 | { | ||
1422 | 38 | Q_OBJECT | ||
1423 | 39 | |||
1424 | 40 | private Q_SLOTS: | ||
1425 | 41 | void testChromeProperties(); | ||
1426 | 42 | void testWebkitProperties(); | ||
1427 | 43 | |||
1428 | 44 | void testChromeReadWrite_data() { setupCookieData(); } | ||
1429 | 45 | void testWebkitReadWrite_data() { setupCookieData(); } | ||
1430 | 46 | void testChromeReadWrite(); | ||
1431 | 47 | void testWebkitReadWrite(); | ||
1432 | 48 | |||
1433 | 49 | void testMoving_data() { setupCookieData(); } | ||
1434 | 50 | void testMoving(); | ||
1435 | 51 | |||
1436 | 52 | private: | ||
1437 | 53 | void setupCookieData(); | ||
1438 | 54 | QSet<QNetworkCookie> parseCookies(const Cookies &rawCookies); | ||
1439 | 55 | }; | ||
1440 | 56 | |||
1441 | 57 | QSet<QNetworkCookie> | ||
1442 | 58 | CookieStoreTest::parseCookies(const Cookies &rawCookies) | ||
1443 | 59 | { | ||
1444 | 60 | QList<QNetworkCookie> cookies; | ||
1445 | 61 | Q_FOREACH(const QByteArray &rawCookie, rawCookies) { | ||
1446 | 62 | cookies.append(QNetworkCookie::parseCookies(rawCookie)); | ||
1447 | 63 | } | ||
1448 | 64 | return cookies.toSet(); | ||
1449 | 65 | } | ||
1450 | 66 | |||
1451 | 67 | void CookieStoreTest::testChromeProperties() | ||
1452 | 68 | { | ||
1453 | 69 | QTemporaryDir tmpDir; | ||
1454 | 70 | QVERIFY(tmpDir.isValid()); | ||
1455 | 71 | QTemporaryDir tmpDir2; | ||
1456 | 72 | QVERIFY(tmpDir2.isValid()); | ||
1457 | 73 | |||
1458 | 74 | ChromeCookieStore store; | ||
1459 | 75 | QSignalSpy dbPathChanged(&store, SIGNAL(dbPathChanged())); | ||
1460 | 76 | |||
1461 | 77 | store.setProperty("dbPath", tmpDir.path()); | ||
1462 | 78 | QCOMPARE(dbPathChanged.count(), 1); | ||
1463 | 79 | QCOMPARE(store.property("dbPath").toString(), tmpDir.path()); | ||
1464 | 80 | dbPathChanged.clear(); | ||
1465 | 81 | |||
1466 | 82 | store.setProperty("dbPath", "file://" + tmpDir2.path()); | ||
1467 | 83 | QCOMPARE(dbPathChanged.count(), 1); | ||
1468 | 84 | QCOMPARE(store.property("dbPath").toString(), tmpDir2.path()); | ||
1469 | 85 | |||
1470 | 86 | QVERIFY(store.property("cookies").value<Cookies>().isEmpty()); | ||
1471 | 87 | } | ||
1472 | 88 | |||
1473 | 89 | void CookieStoreTest::testWebkitProperties() | ||
1474 | 90 | { | ||
1475 | 91 | QTemporaryDir tmpDir; | ||
1476 | 92 | QVERIFY(tmpDir.isValid()); | ||
1477 | 93 | |||
1478 | 94 | WebkitCookieStore store; | ||
1479 | 95 | QSignalSpy dbPathChanged(&store, SIGNAL(dbPathChanged())); | ||
1480 | 96 | |||
1481 | 97 | store.setProperty("dbPath", tmpDir.path()); | ||
1482 | 98 | QCOMPARE(dbPathChanged.count(), 1); | ||
1483 | 99 | QCOMPARE(store.property("dbPath").toString(), tmpDir.path()); | ||
1484 | 100 | |||
1485 | 101 | QVERIFY(store.property("cookies").value<Cookies>().isEmpty()); | ||
1486 | 102 | } | ||
1487 | 103 | |||
1488 | 104 | void CookieStoreTest::setupCookieData() | ||
1489 | 105 | { | ||
1490 | 106 | QTest::addColumn<Cookies>("cookies"); | ||
1491 | 107 | |||
1492 | 108 | Cookies cookies; | ||
1493 | 109 | |||
1494 | 110 | cookies << "LSID=DQAAAKEaem_vYg; Domain=docs.foo.com; Path=/accounts; " | ||
1495 | 111 | "Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly"; | ||
1496 | 112 | QTest::newRow("Single cookie") << cookies; | ||
1497 | 113 | |||
1498 | 114 | cookies.clear(); | ||
1499 | 115 | cookies << "LSID=DQAAAKEaem_vYg; Domain=docs.foo.com; Path=/accounts; " | ||
1500 | 116 | "Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly"; | ||
1501 | 117 | cookies << "HSID=AYQEVnDKrdst; Domain=.foo.com; Path=/; " | ||
1502 | 118 | "Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly"; | ||
1503 | 119 | cookies << "SSID=Ap4PGTEq; Domain=foo.com; Path=/; " | ||
1504 | 120 | "Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure"; | ||
1505 | 121 | cookies << "made_write_conn=1295214458; Path=/; Domain=.example.com"; | ||
1506 | 122 | QTest::newRow("Few cookies") << cookies; | ||
1507 | 123 | } | ||
1508 | 124 | |||
1509 | 125 | void CookieStoreTest::testChromeReadWrite() | ||
1510 | 126 | { | ||
1511 | 127 | QFETCH(Cookies, cookies); | ||
1512 | 128 | |||
1513 | 129 | QTemporaryDir tmpDir; | ||
1514 | 130 | QVERIFY(tmpDir.isValid()); | ||
1515 | 131 | QDir testDir(tmpDir.path()); | ||
1516 | 132 | |||
1517 | 133 | ChromeCookieStore store; | ||
1518 | 134 | QSignalSpy cookiesChanged(&store, SIGNAL(cookiesChanged())); | ||
1519 | 135 | store.setDbPath(testDir.filePath("cookies.db")); | ||
1520 | 136 | |||
1521 | 137 | QCOMPARE(cookiesChanged.count(), 0); | ||
1522 | 138 | store.setProperty("cookies", QVariant::fromValue(cookies)); | ||
1523 | 139 | QCOMPARE(cookiesChanged.count(), 1); | ||
1524 | 140 | Cookies readCookies = store.property("cookies").value<Cookies>(); | ||
1525 | 141 | QCOMPARE(parseCookies(readCookies), parseCookies(cookies)); | ||
1526 | 142 | } | ||
1527 | 143 | |||
1528 | 144 | void CookieStoreTest::testWebkitReadWrite() | ||
1529 | 145 | { | ||
1530 | 146 | QFETCH(Cookies, cookies); | ||
1531 | 147 | |||
1532 | 148 | QTemporaryDir tmpDir; | ||
1533 | 149 | QVERIFY(tmpDir.isValid()); | ||
1534 | 150 | QDir testDir(tmpDir.path()); | ||
1535 | 151 | |||
1536 | 152 | WebkitCookieStore store; | ||
1537 | 153 | QSignalSpy cookiesChanged(&store, SIGNAL(cookiesChanged())); | ||
1538 | 154 | store.setDbPath(testDir.filePath("cookies.db")); | ||
1539 | 155 | |||
1540 | 156 | QCOMPARE(cookiesChanged.count(), 0); | ||
1541 | 157 | store.setProperty("cookies", QVariant::fromValue(cookies)); | ||
1542 | 158 | QCOMPARE(cookiesChanged.count(), 1); | ||
1543 | 159 | Cookies readCookies = store.property("cookies").value<Cookies>(); | ||
1544 | 160 | QCOMPARE(parseCookies(readCookies), parseCookies(cookies)); | ||
1545 | 161 | } | ||
1546 | 162 | |||
1547 | 163 | void CookieStoreTest::testMoving() | ||
1548 | 164 | { | ||
1549 | 165 | QFETCH(Cookies, cookies); | ||
1550 | 166 | |||
1551 | 167 | QTemporaryDir tmpDir; | ||
1552 | 168 | QVERIFY(tmpDir.isValid()); | ||
1553 | 169 | QDir testDir(tmpDir.path()); | ||
1554 | 170 | |||
1555 | 171 | WebkitCookieStore webkitStore; | ||
1556 | 172 | webkitStore.setDbPath(testDir.filePath("webkit.db")); | ||
1557 | 173 | webkitStore.setProperty("cookies", QVariant::fromValue(cookies)); | ||
1558 | 174 | |||
1559 | 175 | ChromeCookieStore chromeStore; | ||
1560 | 176 | chromeStore.setDbPath(testDir.filePath("chrome.db")); | ||
1561 | 177 | |||
1562 | 178 | QSignalSpy moved(&chromeStore, SIGNAL(moved(bool))); | ||
1563 | 179 | chromeStore.moveFrom(&webkitStore); | ||
1564 | 180 | |||
1565 | 181 | QCOMPARE(moved.count(), 1); | ||
1566 | 182 | QCOMPARE(moved.at(0).at(0).toBool(), true); | ||
1567 | 183 | |||
1568 | 184 | Cookies movedCookies = chromeStore.property("cookies").value<Cookies>(); | ||
1569 | 185 | QCOMPARE(parseCookies(movedCookies), parseCookies(cookies)); | ||
1570 | 186 | } | ||
1571 | 187 | |||
1572 | 188 | QTEST_MAIN(CookieStoreTest) | ||
1573 | 189 | #include "tst_CookieStore.moc" |
FAILED: Continuous integration, rev:470 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 648/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 4061/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/3646 jenkins. qa.ubuntu. com/job/ webbrowser- app-trusty- amd64-ci/ 150 jenkins. qa.ubuntu. com/job/ webbrowser- app-trusty- armhf-ci/ 150 jenkins. qa.ubuntu. com/job/ webbrowser- app-trusty- armhf-ci/ 150/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-trusty- i386-ci/ 150 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-trusty/ 3545/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/4113 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/4113/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/3648 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/3648/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- runner- mako/5971 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 4970
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 648/rebuild
http://