PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/QTweetLib-0.5/src/oauthtwitter.cpp

#
C++ | 230 lines | 129 code | 37 blank | 64 comment | 12 complexity | 1d12ab3cd3b26037b13015812df9d2a2 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /* Copyright (c) 2010, Antonie Jovanoski
  2. *
  3. * All rights reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * Contact e-mail: Antonie Jovanoski <minimoog77_at_gmail.com>
  19. */
  20. #include "oauthtwitter.h"
  21. #include <QtDebug>
  22. #include <QUrl>
  23. #include <QNetworkReply>
  24. #include <QTimer>
  25. #include <QNetworkAccessManager>
  26. #include <QEventLoop>
  27. #include <QDesktopServices>
  28. #define TWITTER_REQUEST_TOKEN_URL "https://twitter.com/oauth/request_token"
  29. #define TWITTER_ACCESS_TOKEN_URL "https://twitter.com/oauth/access_token"
  30. #define TWITTER_AUTHORIZE_URL "https://twitter.com/oauth/authorize"
  31. #define TWITTER_ACCESS_TOKEN_XAUTH_URL "https://api.twitter.com/oauth/access_token"
  32. /**
  33. * Constructor
  34. */
  35. OAuthTwitter::OAuthTwitter(QObject *parent)
  36. : OAuth(parent), m_netManager(0)
  37. {
  38. }
  39. /**
  40. * Constructor
  41. */
  42. OAuthTwitter::OAuthTwitter(QNetworkAccessManager *netManager, QObject *parent) :
  43. OAuth(parent), m_netManager(netManager)
  44. {
  45. }
  46. /**
  47. * Constructor
  48. * @param consumerKey OAuth consumer key
  49. * @param consumerSecret OAuth consumer secret
  50. * @param parent parent object
  51. */
  52. OAuthTwitter::OAuthTwitter(const QByteArray &consumerKey, const QByteArray &consumerSecret, QObject *parent) :
  53. OAuth(consumerKey, consumerSecret, parent), m_netManager(0)
  54. {
  55. }
  56. /**
  57. * Sets network access manager
  58. * @remarks Must be set to work properly
  59. */
  60. void OAuthTwitter::setNetworkAccessManager(QNetworkAccessManager* netManager)
  61. {
  62. m_netManager = netManager;
  63. }
  64. /**
  65. * Gets network access manager
  66. */
  67. QNetworkAccessManager* OAuthTwitter::networkAccessManager() const
  68. {
  69. return m_netManager;
  70. }
  71. /**
  72. * Gets oauth tokens using XAuth method (starts authorization process)
  73. * @param username username
  74. * @param password password
  75. * @remarks Async, emits authorizeXAuthFinished or authorizeXAuthError when there is error
  76. */
  77. void OAuthTwitter::authorizeXAuth(const QString &username, const QString &password)
  78. {
  79. Q_ASSERT(m_netManager != 0);
  80. QUrl url(TWITTER_ACCESS_TOKEN_XAUTH_URL);
  81. url.addEncodedQueryItem("x_auth_username", username.toUtf8().toPercentEncoding());
  82. url.addEncodedQueryItem("x_auth_password", password.toUtf8().toPercentEncoding());
  83. url.addQueryItem("x_auth_mode", "client_auth");
  84. QByteArray oauthHeader = generateAuthorizationHeader(url, OAuth::POST);
  85. QNetworkRequest req(url);
  86. req.setRawHeader(AUTH_HEADER, oauthHeader);
  87. QNetworkReply *reply = m_netManager->post(req, QByteArray());
  88. connect(reply, SIGNAL(finished()), this, SLOT(finishedAuthorization()));
  89. }
  90. /**
  91. * Called when authorization is finished
  92. */
  93. void OAuthTwitter::finishedAuthorization()
  94. {
  95. QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
  96. if (reply) {
  97. if (reply->error() == QNetworkReply::NoError) {
  98. QByteArray response = reply->readAll();
  99. parseTokens(response);
  100. emit authorizeXAuthFinished();
  101. } else {
  102. //dump error
  103. qDebug() << "Network Error: " << reply->error();
  104. qDebug() << "Response error: " << reply->readAll();
  105. emit authorizeXAuthError();
  106. }
  107. reply->deleteLater();
  108. }
  109. }
  110. /**
  111. * Starts PIN based OAuth authorization
  112. */
  113. void OAuthTwitter::authorizePin()
  114. {
  115. Q_ASSERT(m_netManager != 0);
  116. QUrl url(TWITTER_REQUEST_TOKEN_URL);
  117. QByteArray oauthHeader = generateAuthorizationHeader(url, OAuth::POST);
  118. QNetworkRequest req(url);
  119. req.setRawHeader(AUTH_HEADER, oauthHeader);
  120. req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
  121. //enters event loop, simulate blocking io
  122. QEventLoop q;
  123. QTimer t;
  124. t.setSingleShot(true);
  125. connect(&t, SIGNAL(timeout()), &q, SLOT(quit()));
  126. QNetworkReply *reply = m_netManager->post(req, QByteArray());
  127. connect(reply, SIGNAL(finished()), &q, SLOT(quit()));
  128. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error()));
  129. t.start(5000);
  130. q.exec();
  131. if (t.isActive()) {
  132. t.stop();
  133. QByteArray response = reply->readAll();
  134. parseTokens(response);
  135. reply->deleteLater();
  136. requestAuthorization();
  137. const QString pin = authorizationWidget();
  138. if (!pin.isEmpty()) {
  139. requestAccessToken(pin);
  140. }
  141. } else {
  142. qDebug() << "Timeout";
  143. }
  144. }
  145. /**
  146. * Opens authorization url
  147. * @remarks Override if you want to show another browser
  148. */
  149. void OAuthTwitter::requestAuthorization()
  150. {
  151. QUrl authorizeUrl(TWITTER_AUTHORIZE_URL);
  152. authorizeUrl.addEncodedQueryItem("oauth_token", oauthToken());
  153. authorizeUrl.addEncodedQueryItem("oauth_callback", "oob");
  154. QDesktopServices::openUrl(authorizeUrl);
  155. }
  156. /**
  157. * Gets access tokens for user entered pin number
  158. * @param pin entered pin number
  159. */
  160. void OAuthTwitter::requestAccessToken(const QString& pin)
  161. {
  162. Q_ASSERT(m_netManager != 0);
  163. QUrl url(TWITTER_ACCESS_TOKEN_URL);
  164. url.addEncodedQueryItem("oauth_verifier", pin.toAscii());
  165. QByteArray oauthHeader = generateAuthorizationHeader(url, OAuth::POST);
  166. QEventLoop q;
  167. QTimer t;
  168. t.setSingleShot(true);
  169. connect(&t, SIGNAL(timeout()), &q, SLOT(quit()));
  170. QNetworkRequest req(url);
  171. req.setRawHeader(AUTH_HEADER, oauthHeader);
  172. req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
  173. QNetworkReply *reply = m_netManager->post(req, QByteArray());
  174. connect(reply, SIGNAL(finished()), &q, SLOT(quit()));
  175. connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error()));
  176. t.start(5000);
  177. q.exec();
  178. if(t.isActive()){
  179. QByteArray response = reply->readAll();
  180. parseTokens(response);
  181. reply->deleteLater();
  182. } else {
  183. qDebug() << "Timeout";
  184. }
  185. }
  186. /**
  187. * Override to show the authorization widget where users enters pin number
  188. * @return entered pin number by the user
  189. */
  190. const QString OAuthTwitter::authorizationWidget()
  191. {
  192. return QString();
  193. }