1 /*
2 * Copyright (C) by Daniel Molkentin <danimo@owncloud.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include "cookiejar.h"
16
17 #include "configfile.h"
18
19 #include <QFile>
20 #include <QDateTime>
21 #include <QLoggingCategory>
22 #include <QNetworkCookie>
23 #include <QDataStream>
24 #include <QDir>
25
26 namespace OCC {
27
28 Q_LOGGING_CATEGORY(lcCookieJar, "sync.cookiejar", QtInfoMsg)
29
30 namespace {
31 const unsigned int JAR_VERSION = 23;
32 }
33
operator <<(QDataStream & stream,const QList<QNetworkCookie> & list)34 QDataStream &operator<<(QDataStream &stream, const QList<QNetworkCookie> &list)
35 {
36 stream << JAR_VERSION;
37 stream << quint32(list.size());
38 for (int i = 0; i < list.size(); ++i)
39 stream << list.at(i).toRawForm();
40 return stream;
41 }
42
operator >>(QDataStream & stream,QList<QNetworkCookie> & list)43 QDataStream &operator>>(QDataStream &stream, QList<QNetworkCookie> &list)
44 {
45 list.clear();
46
47 quint32 version;
48 stream >> version;
49
50 if (version != JAR_VERSION)
51 return stream;
52
53 quint32 count;
54 stream >> count;
55 for (quint32 i = 0; i < count; ++i) {
56 QByteArray value;
57 stream >> value;
58 QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(value);
59 if (newCookies.count() == 0 && value.length() != 0) {
60 qCWarning(lcCookieJar) << "CookieJar: Unable to parse saved cookie:" << value;
61 }
62 for (int j = 0; j < newCookies.count(); ++j)
63 list.append(newCookies.at(j));
64 if (stream.atEnd())
65 break;
66 }
67 return stream;
68 }
69
CookieJar(QObject * parent)70 CookieJar::CookieJar(QObject *parent)
71 : QNetworkCookieJar(parent)
72 {
73 }
74
~CookieJar()75 CookieJar::~CookieJar()
76 {
77 }
78
setCookiesFromUrl(const QList<QNetworkCookie> & cookieList,const QUrl & url)79 bool CookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
80 {
81 if (QNetworkCookieJar::setCookiesFromUrl(cookieList, url)) {
82 Q_EMIT newCookiesForUrl(cookieList, url);
83 return true;
84 }
85
86 return false;
87 }
88
cookiesForUrl(const QUrl & url) const89 QList<QNetworkCookie> CookieJar::cookiesForUrl(const QUrl &url) const
90 {
91 QList<QNetworkCookie> cookies = QNetworkCookieJar::cookiesForUrl(url);
92 qCDebug(lcCookieJar) << url << "requests:" << cookies;
93 return cookies;
94 }
95
clearSessionCookies()96 void CookieJar::clearSessionCookies()
97 {
98 setAllCookies(removeExpired(allCookies()));
99 }
100
save(const QString & fileName)101 bool CookieJar::save(const QString &fileName)
102 {
103 const QFileInfo info(fileName);
104 if (!info.dir().exists())
105 {
106 info.dir().mkpath(QStringLiteral("."));
107 }
108
109 qCDebug(lcCookieJar) << fileName;
110 QFile file(fileName);
111 if (!file.open(QIODevice::WriteOnly))
112 {
113 return false;
114 }
115 QDataStream stream(&file);
116 stream << removeExpired(allCookies());
117 file.close();
118 return true;
119 }
120
restore(const QString & fileName)121 bool CookieJar::restore(const QString &fileName)
122 {
123 const QFileInfo info(fileName);
124 if (!info.exists())
125 {
126 return false;
127 }
128
129 QFile file(fileName);
130 if (!file.open(QIODevice::ReadOnly))
131 {
132 return false;
133 }
134 QDataStream stream(&file);
135 QList<QNetworkCookie> list;
136 stream >> list;
137 setAllCookies(removeExpired(list));
138 file.close();
139 return true;
140 }
141
removeExpired(const QList<QNetworkCookie> & cookies)142 QList<QNetworkCookie> CookieJar::removeExpired(const QList<QNetworkCookie> &cookies)
143 {
144 QList<QNetworkCookie> updatedList;
145 foreach (const QNetworkCookie &cookie, cookies) {
146 if (cookie.expirationDate() > QDateTime::currentDateTimeUtc() && !cookie.isSessionCookie()) {
147 updatedList << cookie;
148 }
149 }
150 return updatedList;
151 }
152
153 } // namespace OCC
154