31 #include <QNetworkRequest>
32 #include <QNetworkReply>
48 QUrl URLFromClientID (
const QString&
id,
const QStringList& scope)
50 QUrl url = QUrl::fromEncoded (
"https://oauth.vk.com/authorize?redirect_uri=http%3A%2F%2Foauth.vk.com%2Fblank.html&response_type=token&state=");
51 url.addQueryItem (
"client_id",
id);
52 url.addQueryItem (
"scope", scope.join (
","));
58 const QString&
id,
const QStringList& scope,
63 , AccountHR_ (accName)
64 , AuthNAM_ (new QNetworkAccessManager (this))
68 , IsRequesting_ (false)
70 , URL_ (URLFromClientID (ID_, scope))
71 , IsRequestScheduled_ (false)
72 , ScheduleTimer_ (new QTimer (this))
74 AuthNAM_->setCookieJar (Cookies_);
75 Cookies_->
Load (cookies);
77 ScheduleTimer_->setSingleShot (
true);
78 connect (ScheduleTimer_,
81 SLOT (execScheduledRequest ()));
86 return !Token_.isEmpty () &&
87 (!ValidFor_ || ReceivedAt_.secsTo (QDateTime::currentDateTime ()) < ValidFor_);
92 return !Token_.isEmpty () || !Cookies_->allCookies ().isEmpty ();
97 const auto& newUrl = URLFromClientID (ID_, scope);
103 ReceivedAt_ = QDateTime ();
111 PrioManagedQueues_.clear ();
112 ManagedQueues_.clear ();
122 InvokeQueues (Token_);
130 qWarning () << Q_FUNC_INFO
131 <<
"cannot manage request queue if queue manager wasn't set";
135 ManagedQueues_ << queue;
140 ManagedQueues_.removeAll (queue);
147 qWarning () << Q_FUNC_INFO
148 <<
"cannot manage request queue if queue manager wasn't set";
152 PrioManagedQueues_ << queue;
157 PrioManagedQueues_.removeAll (queue);
162 SilentMode_ = silent;
165 void VkAuthManager::InvokeQueues (
const QString& token)
167 for (
auto queue : PrioManagedQueues_)
168 while (!queue->isEmpty ())
170 const auto& pair = queue->takeFirst ();
171 const auto& f = pair.first;
172 Queue_->
Schedule ([f, token] { f (token); },
nullptr, pair.second);
175 for (
auto queue : ManagedQueues_)
176 while (!queue->isEmpty ())
178 const auto& f = queue->takeFirst ();
179 Queue_->
Schedule ([f, token] { f (token); });
183 void VkAuthManager::HandleError ()
185 IsRequesting_ =
false;
188 void VkAuthManager::RequestURL (
const QUrl& url)
190 qDebug () << Q_FUNC_INFO << url;
191 auto reply = AuthNAM_->get (QNetworkRequest (url));
193 SIGNAL (finished ()),
195 SLOT (handleGotForm ()));
198 void VkAuthManager::RequestAuthKey ()
200 if (IsRequestScheduled_ && ScheduleTimer_->isActive ())
201 ScheduleTimer_->stop ();
207 IsRequesting_ =
true;
210 bool VkAuthManager::CheckIsBlank (QUrl location)
212 if (location.path () !=
"/blank.html")
215 location = QUrl::fromEncoded (location.toEncoded ().replace (
'#',
'?'));
216 Token_ = location.queryItemValue (
"access_token");
217 ValidFor_ = location.queryItemValue (
"expires_in").toInt ();
218 ReceivedAt_ = QDateTime::currentDateTime ();
219 qDebug () << Q_FUNC_INFO << Token_ << ValidFor_;
220 IsRequesting_ =
false;
222 InvokeQueues (Token_);
233 ReceivedAt_ = QDateTime ();
239 class CloseEventFilter :
public QObject
243 CloseEventFilter (
const std::function<
void ()>& handler, QObject *handlee)
244 : QObject { handlee }
245 , Handler_ { handler }
247 handlee->installEventFilter (
this);
250 bool eventFilter (QObject*, QEvent *event)
261 auto view =
new QWebView;
262 view->setWindowTitle (tr (
"VK.com authentication for %1")
265 view->resize (800, 600);
266 view->page ()->setNetworkAccessManager (AuthNAM_);
272 SIGNAL (urlChanged (QUrl)),
274 SLOT (handleViewUrlChanged (QUrl)));
276 new CloseEventFilter ([
this] { emit
authCanceled (); }, view);
279 void VkAuthManager::execScheduledRequest ()
281 IsRequestScheduled_ =
false;
286 void VkAuthManager::handleGotForm ()
288 auto reply = qobject_cast<QNetworkReply*> (sender ());
289 reply->deleteLater ();
291 if (reply->error () != QNetworkReply::NoError)
293 qWarning () << Q_FUNC_INFO
294 << reply->errorString ();
296 IsRequesting_ =
false;
298 if (!IsRequestScheduled_)
300 IsRequestScheduled_ =
true;
301 ScheduleTimer_->start (30000);
307 const auto& location = reply->header (QNetworkRequest::LocationHeader).toUrl ();
308 if (location.isEmpty ())
314 if (CheckIsBlank (location))
317 RequestURL (location);
320 void VkAuthManager::handleViewUrlChanged (
const QUrl& url)
322 if (!CheckIsBlank (url))
326 sender ()->deleteLater ();
void ManageQueue(RequestQueue_ptr)
void UpdateScope(const QStringList &)
void gotAuthKey(const QString &)
std::shared_ptr< ICoreProxy > ICoreProxy_ptr
void Schedule(std::function< void()> functor, QObject *dependent=0, QueuePriority prio=QueuePriority::Normal)
Adds the given functor.
bool HadAuthentication() const
void UnmanageQueue(RequestQueue_ptr)
A simple scheduling manager for a queue of functors.
bool IsAuthenticated() const
void cookiesChanged(const QByteArray &)
VkAuthManager(const QString &accountName, const QString &clientId, const QStringList &scope, const QByteArray &cookies, ICoreProxy_ptr, QueueManager *=nullptr, QObject *=nullptr)
A customized cookie jar with additional features.
const std::function< void()> Handler_
void Load(const QByteArray &data)