Giter Site home page Giter Site logo

o2's Introduction

OAuth 1.0 and 2.0 for Qt

This library encapsulates the OAuth 1.0 and 2.0 client authentication flows, and the sending of authenticated HTTP requests.

The primary target is Qt Quick applications on embedded devices.

Supported Qt versions: 5 and 6.

Notes to contributors:

  • Please follow the coding style of the existing source code
  • Code contributions are released under Simplified BSD License, as specified in LICENSE. Do not contribute if this license does not suit your code

Classes

Class Header Purpose
O0AbstractStore o0abstractstore.h Base class of persistent stores
O0BaseAuth o0baseauth.h Base class of OAuth authenticators
O0SettingsStore o0settingsstore.h QSettings-based persistent store
o0keyChainStore o0keychainstore.h Settings stored through the system keychain keychain
O0SimpleCrypt o0simplecrypt.h Simple encryption and decryption by Andre Somers
O1 o1.h Generic OAuth 1.0 authenticator
O1Dropbox o1dropbox.h Dropbox OAuth specialization
O1Flickr o1flickr.h Flickr OAuth specialization
O1Freshbooks o1freshbooks.h Freshbooks OAuth specialization
O1Requestor o1requestor.h Makes authenticated OAuth 1.0 requests: GET, POST or PUT, handles timeouts
O1RequestParameter o1.h An extra request parameter participating in request signing
O1Twitter o1twitter.h Twitter OAuth specialization
O1SmugMug o1smugmug.h SmugMug OAuth specialization
O2 o2.h Generic OAuth 2.0 authenticator
O2Facebook o2facebook.h Facebook OAuth specialization
O2Gft o2gft.h Google Fusion Tables OAuth specialization
O2Google o2google.h Google Oauth specialization scopes
O2GoogleDevice o2google.h Google Sign-In for TVs and Devices
O2Hubic o2hubic.h Hubic OAuth specialization
O2Msgraph o2msgraph.h Microsoft Graph OAuth specialization
O2Reply o2reply.h A network request/reply that can time out
O2ReplyServer o2replyserver.h HTTP server to process authentication responses
O2Requestor o2requestor.h Makes authenticated OAuth 2.0 requests (GET, POST or PUT), handles timeouts and token expiry
O2Skydrive o2skydrive.h OneDrive OAuth specialization
O2SurveyMonkey o2surveymonkey.h SurveyMonkey OAuth specialization
OXTwitter oxtwitter.h Twitter XAuth specialization
O2Uber o2uber.h Uber OAuth specialization

Installation

Clone the Github repository, then add all files in src to your Qt project, by including src/src.pri.

Basic Usage

This example assumes a hypothetical Twitter client that will post tweets. Twitter is using OAuth 1.0.

Setup

Include the required header files, and have some member variables that will be used for authentication and sending requests:

#include "o1twitter.h"
#include "o1requestor.h"
O1Twitter *o1;

Initialization

Instantiate one of the authenticator classes, like O1Twitter, set your application ID and application secret, and install the signal handlers:

o1 = new O1Twitter(this);
o1->setClientId(MY_CLIENT_ID);
o1->setClientSecret(MY_CLIENT_SECRET);
connect(o1, SIGNAL(linkedChanged()), this, SLOT(onLinkedChanged()));
connect(o1, SIGNAL(linkingFailed()), this, SLOT(onLinkingFailed()));
connect(o1, SIGNAL(linkingSucceeded()), this, SLOT(onLinkingSucceeded()));
connect(o1, SIGNAL(openBrowser(QUrl)), this, SLOT(onOpenBrowser(QUrl)));
connect(o1, SIGNAL(closeBrowser()), this, SLOT(onCloseBrowser()));

Note: For browserless Twitter authentication, you can use the OXTwitter specialized class that can do Twitter XAuth. You will need to additionally provide your Twitter login credentials (username & password) before calling link().

Handling Signals

O2 is an asynchronous library. It will send signals at various stages of authentication and request processing.

To handle these signals, implement the following slots in your code:

void onLinkedChanged() {
    // Linking (login) state has changed.
    // Use o1->linked() to get the actual state
}

void onLinkingFailed() {
    // Login has failed
}

void onLinkingSucceeded() {
    // Login has succeeded
}

void onOpenBrowser(const QUrl *url) {
    // Open a web browser or a web view with the given URL.
    // The user will interact with this browser window to
    // enter login name, password, and authorize your application
    // to access the Twitter account
}

void onCloseBrowser() {
    // Close the browser window opened in openBrowser()
}

Note: From onOpenBrowser, prefer opening a web view, instead of a full-blown external browser.

Note: If you must use an external browser on Android, change this line in the Qt-generated manifest.xml:

meta-data android:name="android.app.background_running" android:value="true"

Logging In

To log in (e.g. to link your application to the OAuth service), call the link() method:

o1->link();

This initiates the authentication sequence. Your signal handlers above will be called at various stages. Lastly, if linking succeeds, onLinkingSucceeded() will be called.

Logging Out

To log out, call the unlink() method:

o1->unlink();

Logging out always succeeds, and requires no user interaction.

Sending Authenticated Requests

Once linked, you can start sending authenticated requests to the service. We start with a simple example of sending a text-only tweet or as it's known in Twitter docs, a 'status update'.

First we need a Qt network manager and an O1 requestor object:

QNetworkAccessManager *manager = new QNetworkAccessManager(this);
O1Requestor *requestor = new O1Requestor(manager, o1, this);

Next, create parameters for posting the update:

QByteArray paramName("status");
QByteArray tweetText("My first tweet!");

QList<O1RequestParameter> requestParams = QList<O1RequestParameter>();
requestParams << O1RequestParameter(paramName, tweetText);

QByteArray postData = O1::createQueryParams(requestParams);

// Using Twitter's REST API ver 1.1
QUrl url = QUrl("https://api.twitter.com/1.1/statuses/update.json");

QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);

Finally we authenticate and send the request using the O1 requestor object:

QNetworkReply *reply = requestor->post(request, reqestParams, postData);

Continuing with the example, we will now send a tweet containing an image as well as a message.

We create an HTTP request containing the image and the message, in the format specified by Twitter:

QString imagePath("/tmp/image.jpg");
QString message("My tweet with an image!");

QFileInfo fileInfo(imagePath);
QFile file(imagePath);
file.open(QIODevice::ReadOnly);

QString boundary("7d44e178b0439");
QByteArray data(QString("--" + boundary + "\r\n").toAscii());
data += "Content-Disposition: form-data; name=\"media[]\"; filename=\"" + fileInfo.fileName() + "\"\r\n";
data += "Content-Transfer-Encoding: binary\r\n";
data += "Content-Type: application/octet-stream\r\n\r\n";
data += file.readAll();
file.close();
data += QString("\r\n--") + boundary + "\r\n";
data += "Content-Disposition: form-data; name=\"status\"\r\n";
data += "Content-Transfer-Encoding: binary\r\n";
data += "Content-Type: text/plain; charset=utf-8\r\n\r\n";
data += message.toUtf8();
data += QString("\r\n--") + boundary + "--\r\n";

QNetworkRequest request;
// Using Twitter's REST API ver 1.1
request.setUrl(QUrl("https://api.twitter.com/1.1/statuses/update_with_media.json"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary);
request.setHeader(QNetworkRequest::ContentLengthHeader, data.length());

QNetworkReply *reply = requestor->post(request, QList<O1RequestParameter>(), data);

That's it. Tweets using the O2 library!

Storing OAuth Tokens

O2 provides simple storage classes for writing OAuth tokens in a peristent location. Currently, a QSettings based backing store O0SettingsStore is provided in O2. O2SettingsStore keeps all token values in an encrypted form. You have to specify the encryption key to use while constructing the object:

O0SettingsStore *settings = new O0SettingsStore("myencryptionkey");
// Set the store before starting OAuth, i.e before calling link()
o1->setStore(settings);
// ...

Once set, the O0BaseAuth takes ownership of the O0SettingsStore object.

You can also create it with your customized QSettings object. O2SettingsStore will then use that QSettings object for storing the tokens:

O0SettingsStore *settings = new O0SettingsStore(mySettingsObject, "myencryptionkey");

Once set, O2SettingsStore takes ownership of the QSettings object.

Note: If you do not specify a storage object to use, O2 will create one by default (which QSettings based), and use it. In such a case, a default encryption key is used for encrypting the data. This is not a secure solution: prefer storing the tokens in a Keychain or Wallet based facility instead.

Note: If using O2SettingsStore, make sure organization name, domain and application name are set:

QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");

Extra OAuth Tokens

Some OAuth services provide additional information in the access token response. For example Twitter returns two additional tokens: screen_name and user_id.

O2 exposes such tokens via the property extraTokens. You can query this property after a successful OAuth exchange, i.e after the linkingSucceeded() signal has been emitted.

More Examples

The examples folder contains complete example applications:

Name Description
facebookdemo Command line application authenticating with Facebook
sialis QT Quick Twitter client using OAuth 1
twitterdemo Command line client for authenticating with Twitter and posting status updates. Uses OAuth 1 or Twitter XAuth

Change Log

1.0.2

  • Last Qt5-only release

0.1.0

  • Persist the extra tokens, too
  • Add Qt Quick Twitter client example

o2's People

Contributors

3nids avatar agarny avatar archangelsdy avatar bluehaunter avatar dakcarto avatar dbrnz avatar farindk avatar gavrushkin avatar ghosalmartin avatar hdijkema avatar hyperglow avatar ikushn-s avatar ildar-gilmanov avatar ilpianista avatar lemirep avatar lukedirtwalker avatar mariusor avatar martinmikita avatar montel avatar parapente avatar pipacs avatar pollend avatar quantisproject avatar risca avatar sherlock221b avatar shimomura1004 avatar stpetruk avatar tereius avatar vic-elgato avatar vogtinator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

o2's Issues

GET Method return ERROR: "Host requires authentication" code : 32 Could not authenticate you

I discovered lately all the OAuth process and for POST method, your great lib worked just fine.

Until I tried to use Oembed from Twitter using the GET method.

I've seen the issue #19 which use setToken and setTokenSecret. I wonder how since these methods are protected.

For my part, it's nothing fancy, I just try this

    O1Requestor* requestor = new O1Requestor(manager, o1, this);
    QList<O1RequestParameter> reqParams = QList<O1RequestParameter>();
    QUrl url = QUrl(QString("https://api.twitter.com/1.1/statuses/oembed.json?id=" + tweet_id));
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    QNetworkReply *replyEmbed = requestor->get(request, reqParams);
    connect(replyEmbed, SIGNAL(finished()), this, SLOT(addTweet()));

with

    o1 = new O1Twitter(this);
    o1->setClientId("shshshshshshshsh");
    o1->setClientSecret("shshshshshshshshshshshshshshshshshshshshshshshsh");

and successfully linked.

No matter what, I always get in response

ERROR: "Host requires authentication"
content: "{"errors":[{"code":32,"message":"Could not authenticate you."}]}"

I tried to qDebug the authParams, but it seems quite the same as the Twitter Oauth Generator

Any help would be really appreciated.
Thanks.

Sorry for troubling you again....But I really need your help~

After reading the lastest README doucument you just uploaded,I still can't use this library to make an Open Platform Client(Sina weibo, like facebook) through oauth2 authorization which based on desktop(win7) enviorment.Is that this library not support in desktop application?

According to my poor knowledge about network and HTTP methods.I learnt that the o2reply is use for deal with the QNetworkreply queue.And the o2replyserver is use for handle the data from the TCP socket.At last,the o2requestor is for GET or POST with the token to use the API.But what make me painful is how all these stuff works in a project.I really want to know is the procedure of the the library(very hopeful).

1.Why it use the TCP instead of the QNetworkReply for processing the Authorization Reply?
2.
(1)What is the purpose of O2::LINK?
(2)Why the RediretUrl is http://localhost:%1/").arg(replyServer_->serverPort()?Can I change it which I had setted on callbackURL setting of the platform I used?
(3)It that right once the SIGNAL openBrowser(url) is emited,the newconnection from QTCP will be emitted?It's that means that we open the brwoser(Qurl) just for get response from the TCP port and have a TCP newconnecttion?If is is not?And how to active the SIGNAL newconnection?
(4).All the problems troubles me,because it is impossible to get the "CODE" with for acces the TOKEN. without sloving these problem.And could you please give me some advice for getting the CODE from the firt step of the oauth2.0 protocol.

Anyway,no matter you answer all these problems or no,still thanks for share such wonderful oauth2.0 library based on QT,cause such properties is extremly less.And all these problems may only for one reason------I am a typical noob~~~ orz

textual error strings for network errors

Currently, the finished-signal of O2Requestor passes an error code. In order to get a textual error message, the preferred way is to get it from QNetworkReply::errorString(). However, this is not available when the finished signal has been emitted as the QNetworkReply object is not accessible and may already have been destroyed.

How about adding the error string as a parameter to the finished signal?

In order to avoid breaking existing code, one could add another finished signal overload with the error string parameter.
What do you think about this? I can provide a pull-request if needed.

void O2::setExpires(int v) causes warnings because qint64 passed as parameter

There are multiple lines in o2 using the setExpires() function like in o2.cpp:343 :
setExpires(QDateTime::currentMSecsSinceEpoch() / 1000 + expiresIn);

These lines cause a warning because a qint64 is passed as parameter but the setExpires function uses an int as parameter.

All the warnings would be fixed by changing the prototype of setExpires from
void O2::setExpires(int v)
to
void O2::setExpires(qint64 v)

Automatic favicon retrieval breaks the link shortly after it has been established

I managed to get o2 to work with SoundCloud. On a x64 Arch Linux with chromium, the function O2ReplyServer::onBytesReady() is called twice!

Once for the original redirect and another time for the favicon request that chromium issues automatically. A quick workaround is to quickly grab the token from the O2 object before it is deleted again:

void MainWindow::onLinkingSucceeded() {
    // Login has succeeded
    qDebug() << "Gained like a boss!";
    isReady = true;
    token = authenticator->token();
}

Of course this should not be left as it is. If I am able to fix it, I will give you a pull request!

Add %20 causes "Host requires authentication" error

First I have to say that I'm using this library in a slightly weird way. I'm storing the consumer secret/key and the token/token secret in my DB and creating an O1 object using this code:

O1 *AbstractMessage::createO1()
{
    O1 *oauth = new O1(this);
    oauth->setClientId(loginInfo->consumerKey);
    oauth->setClientSecret(loginInfo->consumerSecret);
    oauth->setToken(loginInfo->token);
    oauth->setTokenSecret(loginInfo->tokenSecret);
    return oauth;
}

QNetworkReply *AbstractMessage::oauthGetRequest(const QString &url)
{
    O1 *oauth = this->createO1();
    O1Requestor *requestor = new O1Requestor(this->networkAccessManager, oauth, this);
    return requestor->get(QNetworkRequest(url), QList<O1RequestParameter>());
}

I don't know if this can cause the error.

Calling to "oauthGetRequest()" with a URL like "https://one.ubuntu.com/api/file_storage/v1/~/foo" works like a charm.

However, when I try to do exactly the same with this URL "https://one.ubuntu.com/api/file_storage/v1/~/foo%20bar" or this other "https://one.ubuntu.com/api/file_storage/v1/~/foo?include_children=true" I'm getting a "Host requires authentication" error.

Could be this a problem with the way I'm using the library or could it be a bug?

Switching accounts

Assume that I have two accounts (in my case two OneDrive accounts) and I login to the first account with O2. After I log out again (unlink()) and try to log in again, I am automatically logged into my first account. There is no way to select the second account.

The only workaround I see is to open the web-browser, open the OneDrive website and log out from there. Then, when I link() from O2, I can now select which account I want to log in to.

Is there a way I can force O2 (i.e. force the web-browser through O2) to let me select a new account?

Refresh token is deleted when generating a new access token

The O2::refresh() function is used to generate a new access token using the refresh token.
In the O2::onRefreshFinished() callback, the new access token is saved as expected. However O2::onRefreshFinished() assumes that the authorization server will provide the refresh token in the response. If the authorization server does not provide a refresh token, the old refresh token is replaced by an empty string. This issue is easily reproducible with YouTube where the access token expires each hour.

According to the OAuth v2 specs, when generating a new access token using a refresh token, the authorization server is not required to return the old refresh token nor a new refresh token. See https://tools.ietf.org/html/draft-ietf-oauth-v2-31
Also YouTube explicitly tells that the response when refreshing an access token DOES NOT contain the refresh token ( https://developers.google.com/youtube/v3/guides/auth/installed-apps ):

As long as the user has not revoked the access granted to the application, the token server returns a JSON object that contains a new access token. The following snippet shows a sample response:
{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in":3920,
"token_type":"Bearer"
}

Steps to reproduce:

1- Launch an application using O2
2- Add a YouTube account
3- Quit the application
4- Delete the access token (while leaving the refresh token for this account)
5- Launch again the application

Result: You can see that a new access token has been generated but the refresh token is gone.

6- Quit the application
7- Delete the access token
8- Launch again the application

Result: Since we have no access token and no refresh token, we need to request the user credentials.

No install documentation for noobs

Even I'm still trying to figure out how to use this with my project

Qt-5.9 - Windows. 8.1 Ming-Gw - cmake installed

This in no way is entirely on pipac. But people new to Qt like myself, have no idea how to implement this in our projects.

I have a qt-quick project which will import o2.
I have opened a new quick project and (open project'd) cmake'd the 02 file system, the problem is how do I link o2 with keychain?
Not only that, but how do I link o2 to my quick-project?

The documentation doesn't layout the steps, which is the exact reason noobs stay away from c++ and qt all together.

" Application is not linked to Twitter!" after link succeeded messege

When I run the twitterdemo it starts the browser like it should and after I authorize the application I see the link succeeded message in the console but after that if I try to post a status it says application is not linked to twitter. I tried this with 2 different computers connected to different networks but still couldn't work it out. Could you help me to solve this problem?

note: I added
LIBS += -LC:/OpenSSL-Win32 -llibssl32
LIBS += -LC:/OpenSSL-Win32 -llibeay32
LIBS += -LC:/OpenSSL-Win32 -lssleay32
to the .pro file to get rid of ssl problems.
I use qt 5.5 and msvc2012 32 bit on windows 10

Getting "unresolved resolved external symbol" error in the example apps

Hi all,

I tried to build the library and the example applications. Building the lib itself works fine in VisualStudio 2019.
Btw. I am working on windows 10.

In the top CMakeLists.txt I set the "o2_WITH_VIMEO" option to ON.
When I want to build the Vimeo example app (also with the lib), I get errors with unresolved external symbols.
public: __cdecl O2PollServer::O2PollServer(class QNetworkAccessManager *,class QNetworkRequest const &,class QByteArray const &,int,class QObject *)" " in function ""protected: void __cdecl O2::startPollServer(class QMap<class QString,class QVariant> const &)"
Also for "O2PollServer::setInterval(int)", "O2PollServer::startPolling(void)", "O2Vimeo::O2Vimeo(class QObject *)".
I first tried to implement my own auth class (like O2Vimeo), then I got a few different unresolved errors, but same picture.

I downloaded the master and run the cmake command: cmake -D CMAKE_PREFIX_PATH=C:\Qt\Qt5.12.3\5.12.3\msvc2015_64 -DBUILD_SHARED_LIBS=1 -Do2_WITH_KEYCHAIN=OFF .

Does anybody know what I did wrong or misconfigured? Or why the linker? does not find these symbols? Could it be that the linker does not find the o2.lib file?

Malformed oauth_callback under Qt 5 on Windows

If running on Windows (tested with the Qt 5.1 beta), the oauth_callback URL looks strange... it works if you reverse the slashes, but otherwise you just get a blank page instead of a login form. Not sure if this is o2's fault or QUrlQuery's.

It works just fine on both Mac and Linux.

http://i.imgur.com/tUVsl0w.png

MSGraph example not working for Native apps

I've created a desktop app in Azure AD and I've added a redirect URL for 127.0.0.1.
I've put the client id and the client secret in the msgraph example, but at the end of the authentication I get an error:

O2::onTokenReplyError:  QNetworkReply::AuthenticationRequiredError :  "Host requires authentication"
O2::onTokenReplyError:  "{\"error\":\"invalid_client\",\"error_description\":\"AADSTS700025: Client is public so neither 'client_assertion' nor 'client_secret' should be presented

The example uses O2::GrantFlowAuthorizationCode authentication method. The workaround I've found is to comment the line

parameters.insert(O2_OAUTH2_CLIENT_SECRET, clientSecret_);

from O2::onVerificationReceived.

Is there a better way? Do you think this is due to MS Graph OAuth dialect?

o2.cpp : patch from digiKam core about scope and state parameters

Hi,

In digiKam core we host the O2 source code internally to communicate with remote web service and export items from photo collections.

Few days ago, digiKam have been ported to Qt6 (it still compatible with Qt5) and i updated as well O2 library with last code available (previous version dating a lots)

Recently, a student working on ImgUr plugin for digiKam, has restored a small patch that i forget to re-integrate to O2:

https://invent.kde.org/graphics/digikam/-/merge_requests/170/diffs#842297e068b45b02767c92fbe54bbceec08c8ae8

Typically, in some conditions (probably an older Qt5 version), this patch must be applied to communicate properly.

We will re-integrate this patch to the O2 source code from digiKam core.

Best regards

Gilles Caulier

O2::setRefreshToken is not set properly / is empty

After receiving the refresh token in void O2::onTokenReplyFinished() where the token is present.
It never arrives in void O2::setRefreshToken(const QString &v) function somehow in my case.

Any ideas on that?

O1::onTokenRequestError: 204 "Host requires authentication"

I am developing a Qt5 Twitter application, but was running into an issue during authentication. When my application attempts to authenticate, I get the following on stdout:

"The name org.ofono was not provided by any .service files"
"The name org.ofono was not provided by any .service files"
O1::link
O1::onTokenRequestError: 204 "Host requires authentication" "<?xml version="1.0" encoding="UTF-8"?>
<hash>
<error>Desktop applications only support the oauth_callback value 'oob'</error>
<request>/oauth/request_token</request>
</hash>
"

What's strange is I am able to launch OAuth from the twitterdemo example application provided.

Here is the relevant snippets of my class.

Again, the provided twitterdemo doesn't output any sort of stderr/stdout errors, and behaves exactly as expected.

I'm including all of the o2 source files, through the pri file provided, so I don't think it's any sort of missing dependency.

I'm using the following QT modules in my pro file: core gui network webkit webkitwidgets script

O2 Outlook handler

I've created a handler for Office365 Outlook.
Maybe it's something to add to the o2 library.

Upload photo to flickr

Hi

I am trying to use o2 library to upload photos to flickr. Authentication process goes well, but I am unable to upload a photo. The error says:
"Error when uploading file: authentication required"

I am sending a photo with

manager_ = new QNetworkAccessManager(this);
 o1_ = new O1Flickr(this);
 requestor_ = new O1Requestor(manager_, o1_, this)
QNetworkRequest request(uploadUrl_);
request.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE);
request.setHeader(QNetworkRequest::ContentLengthHeader, postData.length());
QNetworkReply *reply = requestor_->post(request, QList<O0RequestParameter>(), postData);

postData is a QbyteArray constructed as shown below:

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"title\"\r\n";
    requestData += "\r\n"+title_+"\r\n";

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"description\"\r\n";
    requestData += "\r\n"+description_+"\r\n";

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"tags\"\r\n";
    requestData += "\r\n"+tags_+"\r\n";

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"is_public\"\r\n";
    requestData += "\r\n"+isPublic_+"\r\n";

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"is_friend\"\r\n";
    requestData += "\r\n"+isFriend_+"\r\n";

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"is_family\"\r\n";
    requestData += "\r\n"+isFamily_+"\r\n";

    requestData += QString("--" HTTP_PART_BOUNDARY "\r\n").toUtf8();
    requestData += "Content-Disposition: form-data; name=\"photo\"; filename=\""+
            fileInfo.fileName()+"\"\r\n";
    QMimeDatabase db;
    QMimeType mimeType = db.mimeTypeForFile(filename);
    requestData += "Content-Type: "+mimeType.name()+"\r\n";
    requestData += "\r\n"+file.readAll()+"\r\n";
    file.close();

    requestData += QString("--" HTTP_PART_BOUNDARY "--\r\n").toUtf8();

Could someone tell me what I am doing wrong ?

thanks
Bogdan

hmac-sha256

just wanted to pass this back -- changes made to send OAuth1 hmac-sha256 instead of sha1's for services that have stopped accepting them

hmac-sha256_patch.txt
.

Silent failure on windows

Hey all, just spent the day tracking down a bug when using o2 on windows. If
QCoreApplication::setOrganizationName();
QCoreApplication::setApplicationName();
Are not set then the Qsettings used in o2 will fail to write key value pairs (but will continue to run!). The return values end up being empty strings which causes everything to fail and when porting an application this can be quite annoying.

I'm mostly sharing so that others that hit this issue can find a quick fix, but it might be worth having o2 check if these are set and to set some defaults if not.

Reply content does not work

When using setReplyContent, this does not show up in the browser. For example, we can extend the facebookdemo by adding the following line to FBDemo::FBDemo

o2Facebook_->setReplyContent("You have succesfully authenticated to Facebook. ");

Expected behaviour:
After authenticating to Facebook, the browser displays the content "You have succesfully authenticated to Facebook."

Actual behaviour:
An empty page is shown. HTTP headers also do not seem to be received by the browser.

I tested this on MacOS High Sierra 10.13.3, using Firefox, Chromium and Safari. It also doesn't work when using a webview such as in the facebookexternalinterceptordemo.

Previously, I was on commit c0e33a8. It did work back then, but after pulling in all changes since then, it stopped working. I don't know which change/changes caused this problem.

https uri for replyserver possible ?

Hello,

Wondering if there has been any luck with oauth2 and https enforced redirect_uri (aka callback, or replyserver) ?

I'm thinking along the lines of fudging QSslSocket bits into o2replyserver code.

Any idea's ?

Build errors on Windows 10 with QT version 5

I have followed the steps under Installation from the README.md but I get errors when building the project. It complains about: 'inconsistent dll linkage' and 'definition of dllimport static data member not allowed'. See picture below. This also happens when trying to compile the Twitter example.

Does anyone knows a solution for this? I am building using QT version 5.8.0 on Window 10 64 bit.

capture

o2Requestor methods returns id instead of QNetworkReply

So yeah when attempting to do

QNetworkReply *reply = requestor->get(request);

this error is thrown

uberlogin.cpp:38: error: invalid conversion from 'int' to 'QNetworkReply*' [-fpermissive] QNetworkReply *reply = requestor->get(request);

what am I supposed to do with the id?

Reply content not shown on Android

If you follow the Readme closely and open the browser in Android on
void onOpenBrowser(const QUrl *url)
then the QTcpSocket in O2ReplyServer will pause processing network requests and the reply content will never be shown.
An easy fix is to change this line in the Qt-generated manifest.xml.

meta-data android:name="android.app.background_running" android:value="true"

This should be documented in the Readme.

Twitter Demo don't work

Hi, I tried the example you gave with the librairie, but they didn't work. Or at least I can not make it work.
The program run without error, but only the help is displayed,
Do you have any idea where the problem come from ?

O2ReplyServer bug

Chrome sometimes issues a request for /favicon.ico which causes the token to reset.

Maintained?

Will it be worthwhile to create new issue and requests?
Is there any plan to further develop this?

Allow for multiple accounts (virtual token() and tokenSecret())

O2 currently takes liberties with the credential storage, which causes trouble for applications which can handle multiple accounts. Declaring O1::token(), O1::tokenSecret() and appropriate functions in O2 as virtual would allow subclasses to easily handle their own storage.

Password grant?

Hi,

Your lib is great. Perfect for allowing my c++ app to get access to my Twitter or Facebook account without having a web server in the way.

What I want to do is authenticate against my own oauth server using a simple password grant ( user, password, clientid only). Your lib handles adding tokens to subsequent outbound requests nicely but is geared towards an authorisation grant type, not a simple password grant against my own server.

Would you consider a pull request that filled that gap? Right now I have php and .net oauth auth servers that I want my c++ apps to authorise against but your lib only does part of what I need, ie: it assumes url redirects etc, when I have no need for such mechanisms as I have my own simple oauth password grant server.

If you'd be interested, I'd write one and submit a pull request.

Thanks,
Rich

Hello sir, Can you please upload some example by using this oauth2.0 library?

I am just a QT beginner and I have learnt your files for a few days.But I can't totally get all of these programs.
In the O2.h header of your project,some signal function suck like "openbrowser()" and"linkingSucceeded() " are declared in a moc_o2.cpp.And it's extremly hard to understand this method for me.And while I use the"link()" to test the "emit openBrowser(url)",but my browser did not have any reaction,why?
The oauth2 authorization is start with the SIGNAL of a newconnecttion(),right?But how to active a newconnecttion?
I hope I can use it to develop Sina API's based on QT and the main purpose is make my program having the ability to update a state through the facebook or other API platform,not for serve it to the public,that means I am both the appilication Client and the Resource Owner.
Please help give me a hand. ^ ^

Regard

Memory leak in o2requestor.cpp

In o2requestor.cpp, new O2Reply objects are added to an O2ReplyList when a new request is made. The pointers are however never deleted after removing them from the list (once the request is finished). This leads to a memory leak.

Twitter media/upload end point produces an error saying : code 32 Could not authenticate you.

Hi
I am trying to upload photos to twitter from my app and i am using your library.
The following is the code that i am using:

QFile file(imgPath);
if (!file.open(QIODevice::ReadOnly))
    {
        return false;
    }
QByteArray m_buffer = file.readAll();

O1Requestor* requestor = new O1Requestor(d->netMngr, d->o1Twitter, this);
QList<O0RequestParameter> reqParams = QList<O0RequestParameter>();

reqParams << O0RequestParameter(QByteArray("media"), m_buffer);
reqParams << O0RequestParameter(QByteArray("media_type"), QByteArray("image/jpeg"));

QByteArray postData = O1::createQueryParameters(reqParams);

QUrl url = QUrl("https://upload.twitter.com/1.1/media/upload.json");
QNetworkRequest request(url);

request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);
QNetworkReply *reply = requestor->post(request, reqParams, postData);

The result is the following:

ERROR: "Host requires authentication"
Content: "{"errors":[{"code":32,"message":"Could not authenticate you."}]}"

I tried doing something simple like posting a tweet saying Hello to test the authentication using statuses/update endpoint and it worked with no errors.
The following is the code also if it is required:

QUrl url2 = QUrl("https://api.twitter.com/1.1/statuses/update.json);

reqParams = QList<O0RequestParameter>();
reqParams << O0RequestParameter(QByteArray("status"), "Hello");
postData = O1::createQueryParameters(reqParams);

request.setUrl(url2);
request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);
QNetworkReply *reply = requestor->post(request, reqParams, postData);

Could you please help me with this issue.
Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.