Skip to content

Commit efe0fbf

Browse files
authored
Merge pull request #7310 from elpaso/oauth2
[auth] OAuth2 authentication plugin
2 parents 602a858 + f2245ef commit efe0fbf

File tree

125 files changed

+13115
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+13115
-31
lines changed

.ci/travis/macos/before_install.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ pip3 install \
2828
pyyaml \
2929
mock \
3030
future \
31-
termcolor
31+
termcolor \
32+
oauthlib
3233

3334
brew install \
3435
qscintilla2 \

.docker/qgis3-build-deps.dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ RUN apt-get update \
106106
future \
107107
termcolor \
108108
owslib \
109+
oauthlib \
110+
pyopenssl \
109111
&& apt-get clean
110112

111113
RUN echo "alias python=python3" >> ~/.bash_aliases

doc/modules.dox

+2
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ Contains classes related to implementation of QGIS plugins.
4242
The QgsQuick library is built on top of the CORE library and Qt Quick/QML framework. It adds reusable GUI Quick Components, mainly for mobile devices.
4343

4444
*/
45+
46+

external/o2/CHANGES.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Change Log
2+
3+
## 1.0.1
4+
5+
* Add Spotify specialization
6+
* Fix Skydrive specialization
7+
* If available, use ```qml``` instead of ```script```
8+
* Use ```Q_SIGNALS``` etc. instead of ```signals``` etc.
9+
* Add versioning, shared library support
10+
* Add Surveymonkey specialization
11+
* Add DLL import/export declarations for Windows
12+
13+
## 1.0.0
14+
15+
* O1 and O2 to share a common base class
16+
* Move common classes to the O0 name space
17+
* Cleanups and bug fixes
18+
19+
## 0.1.0
20+
21+
* Add Sialis, a Qt Quick Twitter demo client
22+
* Cleanups and bug fixes
23+
24+
## Pre-0.1.0
25+
26+
* Initial non-release

external/o2/CMakeLists.txt

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
cmake_minimum_required(VERSION 2.8.11)
2+
3+
if(POLICY CMP0048) # in CMake >= 3.0.0
4+
cmake_policy(SET CMP0048 OLD) # keep project() from clearing VERSION variables
5+
endif(POLICY CMP0048)
6+
7+
set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules )
8+
9+
set(VER_MAJOR "1")
10+
set(VER_MINOR "0")
11+
set(VER_PATCH "1")
12+
set(API_VER_PATCH "0")
13+
set(CPACK_PACKAGE_VERSION_MAJOR ${VER_MAJOR})
14+
set(CPACK_PACKAGE_VERSION_MINOR ${VER_MINOR})
15+
set(CPACK_PACKAGE_VERSION_PATCH ${VER_PATCH})
16+
set(PROJECT_VERSION ${VER_MAJOR}.${VER_MINOR}.${VER_PATCH})
17+
set(API_VERSION ${VER_MAJOR}.${VER_MINOR}.${API_VER_PATCH})
18+
19+
project(o2)
20+
21+
option(o2_WITH_QT5 "Use Qt5" ON)
22+
23+
set(o2_LIB_SUFFIX "" CACHE STRING "Suffix for install 'lib' directory, e.g. 64 for lib64")
24+
25+
option(o2_SHOW_TRACE "Show debugging messages" OFF)
26+
if(NOT o2_SHOW_TRACE)
27+
add_definitions(-DQT_NO_DEBUG_OUTPUT=1)
28+
endif()
29+
30+
option(o2_WITH_TWITTER "Authenticate with Twitter" OFF)
31+
option(o2_WITH_DROPBOX "Authenticate with Dropbox" OFF)
32+
option(o2_WITH_GOOGLE "Authenticate with Google" OFF)
33+
option(o2_WITH_FACEBOOK "Authenticate with Facebook" OFF)
34+
option(o2_WITH_SKYDRIVE "Authenticate with SkyDrive" OFF)
35+
option(o2_WITH_FLICKR "Authenticate with Flickr" OFF)
36+
option(o2_WITH_HUBIC "Authenticate with Hubic" OFF)
37+
option(o2_WITH_SPOTIFY "Authenticate with Spotify" OFF)
38+
option(o2_WITH_SURVEYMONKEY "Authenticate with SurveyMonkey" OFF)
39+
option(o2_WITH_KEYCHAIN "keychain store" ON)
40+
41+
option(o2_WITH_OAUTH1 "Include OAuth1 authentication" OFF)
42+
if(o2_WITH_TWITTER OR o2_WITH_DROPBOX OR o2_WITH_FLICKR)
43+
set(o2_WITH_OAUTH1 ON)
44+
endif()
45+
46+
option(o2_BUILD_EXAMPLES "Build examples" OFF)
47+
48+
if(WIN32)
49+
add_definitions(-DO2_DLL_EXPORT)
50+
endif()
51+
52+
add_subdirectory(src)
53+
54+
if(o2_BUILD_EXAMPLES)
55+
add_subdirectory(examples)
56+
endif(o2_BUILD_EXAMPLES)

external/o2/LICENSE

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Copyright (c) 2012, Akos Polster
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
* Redistributions of source code must retain the above copyright notice, this
8+
list of conditions and the following disclaimer.
9+
10+
* Redistributions in binary form must reproduce the above copyright notice,
11+
this list of conditions and the following disclaimer in the documentation
12+
and/or other materials provided with the distribution.
13+
14+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

external/o2/README.md

+223
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# OAuth 1.0 and 2.0 for Qt
2+
3+
This library encapsulates the OAuth 1.0 and 2.0 client authentication flows, and the sending of authenticated HTTP requests.
4+
5+
The primary target is Qt Quick applications on embedded devices.
6+
7+
Notes to contributors:
8+
9+
* Please follow the coding style of the existing source
10+
* Code contributions are released under Simplified BSD License, as specified in LICENSE. Do not contribute if this license does not suit your code
11+
12+
## Classes
13+
14+
Class | Header | Purpose
15+
:-- | :-- | :--
16+
O0AbstractStore | o0abstractstore.h | Base class of persistent stores
17+
O0BaseAuth | o0baseauth.h | Base class of OAuth authenticators
18+
O0SettingsStore | o0settingsstore.h | QSettings-based persistent store
19+
o0keyChainStore | o0keychainstore.h | Settings stored through the system keychain [keychain](https://github.com/frankosterfeld/qtkeychain)
20+
O0SimpleCrypt | o0simplecrypt.h | Simple encryption and decryption by Andre Somers
21+
O1 | o1.h | Generic OAuth 1.0 authenticator
22+
O1Dropbox | o1dropbox.h | Dropbox OAuth specialization
23+
O1Flickr | o1flickr.h | Flickr OAuth specialization
24+
O1Freshbooks | o1freshbooks.h | Freshbooks OAuth specialization
25+
O1Requestor | o1requestor.h | Makes authenticated OAuth 1.0 requests: GET, POST or PUT, handles timeouts
26+
O1RequestParameter | o1.h | An extra request parameter participating in request signing
27+
O1Twitter | o1twitter.h | Twitter OAuth specialization
28+
O2 | o2.h | Generic OAuth 2.0 authenticator
29+
O2Facebook | o2facebook.h | Facebook OAuth specialization
30+
O2Gft | o2gft.h | Google Fusion Tables OAuth specialization
31+
O2Google | o2google.h | Google Oauth specialization [scopes](https://developers.google.com/identity/protocols/googlescopes)
32+
O2Hubic | o2hubic.h | Hubic OAuth specialization
33+
O2Reply | o2reply.h | A network request/reply that can time out
34+
O2ReplyServer | o2replyserver.h | HTTP server to process authentication responses
35+
O2Requestor | o2requestor.h | Makes authenticated OAuth 2.0 requests (GET, POST or PUT), handles timeouts and token expiry
36+
O2Skydrive | o2skydrive.h | OneDrive OAuth specialization
37+
O2SurveyMonkey | o2surveymonkey.h | SurveyMonkey OAuth specialization
38+
OXTwitter | oxtwitter.h | Twitter XAuth specialization
39+
40+
## Installation
41+
42+
Clone the Github repository, then add all files in *src* to your Qt project, by including *src/src.pri*.
43+
44+
## Basic Usage
45+
46+
This example assumes a hypothetical Twitter client that will post tweets. Twitter is using OAuth 1.0.
47+
48+
### Setup
49+
50+
Include the required header files, and have some member variables that will be used for authentication and sending requests:
51+
52+
#include "o1twitter.h"
53+
#include "o1requestor.h"
54+
O1Twitter *o1;
55+
56+
### Initialization
57+
58+
Instantiate one of the authenticator classes, like O1Twitter, set your application ID and application secret, and install the signal handlers:
59+
60+
o1 = new O1Twitter(this);
61+
o1->setClientId(MY_CLIENT_ID);
62+
o1->setClientSecret(MY_CLIENT_SECRET);
63+
connect(o1, SIGNAL(linkedChanged()), this, SLOT(onLinkedChanged()));
64+
connect(o1, SIGNAL(linkingFailed()), this, SLOT(onLinkingFailed()));
65+
connect(o1, SIGNAL(linkingSucceeded()), this, SLOT(onLinkingSucceeded()));
66+
connect(o1, SIGNAL(openBrowser(QUrl)), this, SLOT(onOpenBrowser(QUrl)));
67+
connect(o1, SIGNAL(closeBrowser()), this, SLOT(onCloseBrowser()));
68+
69+
**Note:** For browserless Twitter authentication, you can use the OXTwitter specialized class which can do Twitter XAuth. You will need to additionally provide your Twitter login credentials (username & password) before calling *link()*.
70+
71+
### Handling Signals
72+
73+
O2 is an asynchronous library. It will send signals at various stages of authentication and request processing.
74+
75+
To handle these signals, implement the following slots in your code:
76+
77+
void onLinkedChanged() {
78+
// Linking (login) state has changed.
79+
// Use o1->linked() to get the actual state
80+
}
81+
82+
void onLinkingFailed() {
83+
// Login has failed
84+
}
85+
86+
void onLinkingSucceeded() {
87+
// Login has succeeded
88+
}
89+
90+
void onOpenBrowser(const QUrl *url) {
91+
// Open a web browser or a web view with the given URL.
92+
// The user will interact with this browser window to
93+
// enter login name, password, and authorize your application
94+
// to access the Twitter account
95+
}
96+
97+
void onCloseBrowser() {
98+
// Close the browser window opened in openBrowser()
99+
}
100+
101+
### Logging In
102+
103+
To log in (e.g. to link your application to the OAuth service), call the link() method:
104+
105+
o1->link();
106+
107+
This initiates the authentication sequence. Your signal handlers above will be called at various stages. Lastly, if linking succeeds, onLinkingSucceeded() will be called.
108+
109+
### Logging Out
110+
111+
To log out, call the unlink() method:
112+
113+
o1->unlink();
114+
115+
Logging out always succeeds, and requires no user interaction.
116+
117+
### Sending Authenticated Requests
118+
119+
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'.
120+
121+
First we need a Qt network manager and an O1 requestor object:
122+
123+
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
124+
O1Requestor *requestor = new O1Requestor(manager, o1, this);
125+
126+
Next, create parameters for posting the update:
127+
128+
QByteArray paramName("status");
129+
QByteArray tweetText("My first tweet!");
130+
131+
QList<O1RequestParameter> requestParams = QList<O1RequestParameter>();
132+
requestParams << O1RequestParameter(paramName, tweetText);
133+
134+
QByteArray postData = O1::createQueryParams(requestParams);
135+
136+
// Using Twitter's REST API ver 1.1
137+
QUrl url = QUrl("https://api.twitter.com/1.1/statuses/update.json");
138+
139+
QNetworkRequest request(url);
140+
request.setHeader(QNetworkRequest::ContentTypeHeader, O2_MIME_TYPE_XFORM);
141+
142+
Finally we authenticate and send the request using the O1 requestor object:
143+
144+
QNetworkReply *reply = requestor->post(request, reqestParams, postData);
145+
146+
Continuing with the example, we will now send a tweet containing an image as well as a message.
147+
148+
We create an HTTP request containing the image and the message, in the format specified by Twitter:
149+
150+
QString imagePath("/tmp/image.jpg");
151+
QString message("My tweet with an image!");
152+
153+
QFileInfo fileInfo(imagePath);
154+
QFile file(imagePath);
155+
file.open(QIODevice::ReadOnly);
156+
157+
QString boundary("7d44e178b0439");
158+
QByteArray data(QString("--" + boundary + "\r\n").toAscii());
159+
data += "Content-Disposition: form-data; name=\"media[]\"; filename=\"" + fileInfo.fileName() + "\"\r\n";
160+
data += "Content-Transfer-Encoding: binary\r\n";
161+
data += "Content-Type: application/octet-stream\r\n\r\n";
162+
data += file.readAll();
163+
file.close();
164+
data += QString("\r\n--") + boundary + "\r\n";
165+
data += "Content-Disposition: form-data; name=\"status\"\r\n";
166+
data += "Content-Transfer-Encoding: binary\r\n";
167+
data += "Content-Type: text/plain; charset=utf-8\r\n\r\n";
168+
data += message.toUtf8();
169+
data += QString("\r\n--") + boundary + "--\r\n";
170+
171+
QNetworkRequest request;
172+
// Using Twitter's REST API ver 1.1
173+
request.setUrl(QUrl("https://api.twitter.com/1.1/statuses/update_with_media.json"));
174+
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary);
175+
request.setHeader(QNetworkRequest::ContentLengthHeader, data.length());
176+
177+
QNetworkReply *reply = requestor->post(request, QList<O1RequestParameter>(), data);
178+
179+
That's it. Tweets using the O2 library!
180+
181+
### Storing OAuth Tokens
182+
183+
O2 provides simple storage classes for writing OAuth tokens in a peristent location. Currently, a QSettings based backing store **O2SettingsStore** 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:
184+
185+
O0SettingsStore settings = new O0SettingsStore("myencryptionkey");
186+
// Set the store before starting OAuth, i.e before calling link()
187+
o1->setStore(settings);
188+
...
189+
190+
You can also create it with your customized QSettings object. O2SettingsStore will then use that QSettings object for storing the tokens:
191+
192+
O0SettingsStore settings = new O0SettingsStore(mySettingsObject, "myencryptionkey");
193+
194+
Once set, O2SettingsStore takes ownership of the QSettings object.
195+
196+
**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.
197+
198+
### Extra OAuth Tokens
199+
200+
Some OAuth service providers provide additional information in the access token response. Eg: Twitter returns 2 additional tokens in it's access token response - *screen_name* and *user_id*.
201+
202+
O2 provides all 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.
203+
204+
## More Examples
205+
206+
The *examples* folder contains complete example applications:
207+
208+
Name | Description
209+
:-- | :--
210+
facebookdemo | Command line application authenticating with Facebook
211+
sialis | QT Quick Twitter client using OAuth 1
212+
twitterdemo | Command line client for authenticating with Twitter and posting status updates. Uses OAuth 1 or Twitter XAuth
213+
214+
## Change Log
215+
216+
### 0.1.0
217+
218+
* Persist the extra tokens, too
219+
* Add Qt Quick Twitter client example
220+
221+
222+
223+

external/o2/README_QGIS.txt

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
O2 Library from https://github.com/pipacs/o2/archive/31ceafb3f0c3b605110ddd20aeebd3288504ee1f.tar.gz
3+
4+
Note: current master build of O2 is broken if built with keychain support

0 commit comments

Comments
 (0)