Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Jesus Fernandez
qtoauth
Commits
54a8c221
Commit
54a8c221
authored
Jul 01, 2016
by
Jesus Fernandez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Google Calendar Example
parent
ae8f4c7a
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
196 additions
and
20 deletions
+196
-20
QtOAuth/private/qabstractoauth2_p.h
QtOAuth/private/qabstractoauth2_p.h
+2
-0
QtOAuth/private/qoauth2authorizationcodeflow_p.h
QtOAuth/private/qoauth2authorizationcodeflow_p.h
+3
-2
QtOAuth/qabstractoauth.cpp
QtOAuth/qabstractoauth.cpp
+2
-0
QtOAuth/qabstractoauth2.cpp
QtOAuth/qabstractoauth2.cpp
+5
-6
QtOAuth/qoauth2authorizationcodeflow.cpp
QtOAuth/qoauth2authorizationcodeflow.cpp
+42
-10
QtOAuth/qoauthhttpserverreplyhandler.cpp
QtOAuth/qoauthhttpserverreplyhandler.cpp
+1
-1
examples/examples.pro
examples/examples.pro
+2
-1
examples/qtgcal/main.cpp
examples/qtgcal/main.cpp
+128
-0
examples/qtgcal/qtgcal.pro
examples/qtgcal/qtgcal.pro
+11
-0
No files found.
QtOAuth/private/qabstractoauth2_p.h
View file @
54a8c221
...
...
@@ -81,10 +81,12 @@ public:
QAbstractOAuth2
::
Credential
token
;
QString
scope
;
QString
userAgent
=
"qoauth/0.1"
;
const
QString
bearerFormat
=
QStringLiteral
(
"Bearer %1"
);
struct
OAuth2KeyString
{
static
const
QString
accessToken
;
static
const
QString
apiKey
;
static
const
QString
clientId
;
static
const
QString
code
;
static
const
QString
error
;
...
...
QtOAuth/private/qoauth2authorizationcodeflow_p.h
View file @
54a8c221
...
...
@@ -70,13 +70,14 @@ public:
QOAuth2AuthorizationCodeFlowPrivate
(
QNetworkAccessManager
*
manager
,
quint16
port
);
void
handleCallback
(
const
QVariantMap
&
data
,
const
QString
state
);
void
accessTokenRequestFinished
();
void
accessTokenRequestFinished
(
QNetworkReply
*
reply
);
void
authenticate
(
QNetworkReply
*
reply
,
QAuthenticator
*
authenticator
);
private:
QUrl
accessTokenUrl
;
QString
tokenType
;
QDateTime
expiresAt
;
QString
refreshToken
;
QPointer
<
QNetworkReply
>
accessTokenReply
;
};
QT_END_NAMESPACE
...
...
QtOAuth/qabstractoauth.cpp
View file @
54a8c221
...
...
@@ -75,6 +75,8 @@ void QAbstractOAuthPrivate::setStatus(QAbstractOAuth::Status newStatus)
if
(
status
!=
newStatus
)
{
status
=
newStatus
;
Q_EMIT
q
->
statusChanged
(
status
);
if
(
status
==
QAbstractOAuth
::
Status
::
Granted
)
Q_EMIT
q
->
granted
();
}
}
...
...
QtOAuth/qabstractoauth2.cpp
View file @
54a8c221
...
...
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
typedef
QAbstractOAuth2Private
::
OAuth2KeyString
Key
;
const
QString
Key
::
accessToken
=
QStringLiteral
(
"access_token"
);
const
QString
Key
::
apiKey
=
QStringLiteral
(
"api_key"
);
const
QString
Key
::
clientId
=
QStringLiteral
(
"client_id"
);
const
QString
Key
::
code
=
QStringLiteral
(
"code"
);
const
QString
Key
::
error
=
QStringLiteral
(
"error"
);
...
...
@@ -120,10 +121,9 @@ QNetworkReply *QAbstractOAuth2::get(const QNetworkRequest &req, const QVariantMa
QNetworkRequest
request
(
req
);
request
.
setUrl
(
url
);
QByteArray
bearer
(
"bearer "
);
bearer
.
append
(
d
->
token
.
key
.
toLocal8Bit
());
request
.
setHeader
(
QNetworkRequest
::
UserAgentHeader
,
d
->
userAgent
);
request
.
setRawHeader
(
"Authorization"
,
bearer
);
const
QString
bearer
=
d
->
bearerFormat
.
arg
(
d
->
token
.
key
);
request
.
setRawHeader
(
"Authorization"
,
bearer
.
toUtf8
());
return
d
->
networkAccessManager
->
get
(
request
);
}
...
...
@@ -142,10 +142,9 @@ QNetworkReply *QAbstractOAuth2::post(const QNetworkRequest &req, const QVariantM
QNetworkRequest
request
(
req
);
request
.
setUrl
(
url
);
QByteArray
bearer
(
"bearer "
);
bearer
.
append
(
d
->
token
.
key
.
toLocal8Bit
());
request
.
setHeader
(
QNetworkRequest
::
UserAgentHeader
,
d
->
userAgent
);
request
.
setRawHeader
(
"Authorization"
,
bearer
);
const
QString
bearer
=
d
->
bearerFormat
.
arg
(
d
->
token
.
key
);
request
.
setRawHeader
(
"Authorization"
,
bearer
.
toUtf8
());
return
d
->
networkAccessManager
->
post
(
request
,
QByteArray
());
}
...
...
QtOAuth/qoauth2authorizationcodeflow.cpp
View file @
54a8c221
...
...
@@ -48,6 +48,7 @@
#include <qurlquery.h>
#include <qjsonobject.h>
#include <qjsondocument.h>
#include <qauthenticator.h>
#include <qoauthhttpserverreplyhandler.h>
#include <functional>
...
...
@@ -102,14 +103,15 @@ void QOAuth2AuthorizationCodeFlowPrivate::handleCallback(const QVariantMap &data
q
->
requestAccessToken
(
code
);
}
void
QOAuth2AuthorizationCodeFlowPrivate
::
accessTokenRequestFinished
()
void
QOAuth2AuthorizationCodeFlowPrivate
::
accessTokenRequestFinished
(
QNetworkReply
*
reply
)
{
Q_Q
(
QOAuth2AuthorizationCodeFlow
);
typedef
QAbstractOAuth2Private
::
OAuth2KeyString
Key
;
auto
reply
=
qobject_cast
<
QNetworkReply
*>
(
senders
->
sender
);
Q_ASSERT
(
reply
)
;
if
(
reply
!
=
accessTokenReply
)
return
;
if
(
reply
->
error
()
==
QNetworkReply
::
UnknownNetworkError
)
{
return
;
qWarning
(
"QOAuth2AuthorizationCodeFlow: %s"
,
qPrintable
(
reply
->
errorString
()));
setStatus
(
QAbstractOAuth
::
Status
::
NotAuthenticated
);
return
;
...
...
@@ -120,6 +122,12 @@ void QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished()
Q_ASSERT
(
document
.
isObject
());
const
auto
object
=
document
.
object
();
if
(
object
.
contains
(
Key
::
error
))
{
const
QString
error
=
object
.
value
(
Key
::
error
).
toString
();
qCritical
(
"QOAuth2AuthorizationCodeFlow Error: %s"
,
qPrintable
(
error
));
return
;
}
const
auto
accessToken
=
object
.
value
(
Key
::
accessToken
).
toString
();
tokenType
=
object
.
value
(
Key
::
tokenType
).
toString
();
const
auto
expiresIn
=
object
.
value
(
Key
::
expiresIn
).
toInt
(
-
1
);
...
...
@@ -135,6 +143,18 @@ void QOAuth2AuthorizationCodeFlowPrivate::accessTokenRequestFinished()
setStatus
(
QAbstractOAuth
::
Status
::
Granted
);
}
void
QOAuth2AuthorizationCodeFlowPrivate
::
authenticate
(
QNetworkReply
*
reply
,
QAuthenticator
*
authenticator
)
{
if
(
reply
==
accessTokenReply
){
const
auto
url
=
reply
->
url
();
if
(
url
==
accessTokenUrl
)
{
authenticator
->
setUser
(
consumer
.
key
);
authenticator
->
setPassword
(
""
);
}
}
}
QOAuth2AuthorizationCodeFlow
::
QOAuth2AuthorizationCodeFlow
(
QNetworkAccessManager
*
manager
,
quint16
port
,
QObject
*
parent
)
...
...
@@ -212,6 +232,14 @@ void QOAuth2AuthorizationCodeFlow::setAccessTokenUrl(const QUrl &accessTokenUrl)
void
QOAuth2AuthorizationCodeFlow
::
grant
()
{
Q_D
(
const
QOAuth2AuthorizationCodeFlow
);
if
(
d
->
authorizationUrl
.
isEmpty
())
{
qCritical
(
"QOAuth2AuthorizationCodeFlow: No authenticate Url set"
);
return
;
}
else
if
(
d
->
accessTokenUrl
.
isEmpty
())
{
qCritical
(
"QOAuth2AuthorizationCodeFlow: No request access token Url set"
);
return
;
}
const
QUrl
url
=
buildAuthenticateUrl
();
Q_EMIT
authorizationRequested
(
url
);
}
...
...
@@ -230,6 +258,7 @@ QUrl QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl(const QVariantMap ¶m
p
.
insert
(
Key
::
redirectUri
,
callback
());
p
.
insert
(
Key
::
scope
,
d
->
scope
);
p
.
insert
(
Key
::
state
,
state
);
p
.
insert
(
Key
::
apiKey
,
QVariant
());
if
(
d
->
modifyParametersFunction
)
d
->
modifyParametersFunction
(
Stage
::
RequestingAuthorization
,
&
p
);
url
.
setQuery
(
d
->
createQuery
(
p
));
...
...
@@ -237,6 +266,7 @@ QUrl QOAuth2AuthorizationCodeFlow::buildAuthenticateUrl(const QVariantMap ¶m
std
::
placeholders
::
_1
,
state
);
connect
(
d
->
replyHandler
.
data
(),
&
QAbstractOAuthReplyHandler
::
callbackReceived
,
bind
);
setStatus
(
QAbstractOAuth
::
Status
::
NotAuthenticated
);
qDebug
()
<<
url
;
return
url
;
}
...
...
@@ -247,22 +277,24 @@ void QOAuth2AuthorizationCodeFlow::requestAccessToken(const QString &code)
QVariantMap
parameters
;
QNetworkRequest
request
(
d
->
accessTokenUrl
);
QString
authentication
=
QString
::
fromUtf8
(
"%1:"
).
arg
(
d
->
consumer
.
key
);
QUrlQuery
query
;
parameters
.
insert
(
Key
::
grantType
,
grantType
());
parameters
.
insert
(
Key
::
code
,
code
);
parameters
.
insert
(
Key
::
redirectUri
,
callback
());
parameters
.
insert
(
Key
::
clientId
,
d
->
consumer
.
key
);
parameters
.
insert
(
Key
::
code
,
QUrl
::
toPercentEncoding
(
code
)
)
;
parameters
.
insert
(
Key
::
redirectUri
,
QUrl
::
toPercentEncoding
(
callback
())
)
;
parameters
.
insert
(
Key
::
clientId
,
QUrl
::
toPercentEncoding
(
d
->
consumer
.
key
)
)
;
if
(
d
->
modifyParametersFunction
)
d
->
modifyParametersFunction
(
Stage
::
RequestingAccessToken
,
&
parameters
);
query
=
QAbstractOAuthPrivate
::
createQuery
(
parameters
);
request
.
setRawHeader
(
"Authorization"
,
"Basic "
+
authentication
.
toLocal8Bit
().
toBase64
());
request
.
setHeader
(
QNetworkRequest
::
ContentTypeHeader
,
QStringLiteral
(
"application/x-www-form-urlencoded"
));
auto
reply
=
d
->
networkAccessManager
->
post
(
request
,
query
.
toString
().
toUtf8
());
QObjectPrivate
::
connect
(
reply
,
&
QNetworkReply
::
finished
,
const
auto
data
=
query
.
toString
(
QUrl
::
FullyEncoded
);
d
->
accessTokenReply
=
d
->
networkAccessManager
->
post
(
request
,
data
.
toUtf8
());
QObjectPrivate
::
connect
(
d
->
networkAccessManager
,
&
QNetworkAccessManager
::
finished
,
d
,
&
QOAuth2AuthorizationCodeFlowPrivate
::
accessTokenRequestFinished
);
QObjectPrivate
::
connect
(
d
->
networkAccessManager
,
&
QNetworkAccessManager
::
authenticationRequired
,
d
,
&
QOAuth2AuthorizationCodeFlowPrivate
::
authenticate
,
Qt
::
UniqueConnection
);
}
QT_END_NAMESPACE
...
...
QtOAuth/qoauthhttpserverreplyhandler.cpp
View file @
54a8c221
...
...
@@ -125,7 +125,7 @@ QString QOAuthHttpServerReplyHandler::callback() const
Q_D
(
const
QOAuthHttpServerReplyHandler
);
Q_ASSERT
(
d
->
httpServer
.
isListening
());
const
QUrl
url
(
QString
::
fromLatin1
(
"http://localhost:%1"
).
arg
(
d
->
httpServer
.
serverPort
()));
const
QUrl
url
(
QString
::
fromLatin1
(
"http://localhost:%1
/
"
).
arg
(
d
->
httpServer
.
serverPort
()));
return
url
.
toString
(
QUrl
::
EncodeDelimiters
);
}
...
...
examples/examples.pro
View file @
54a8c221
...
...
@@ -2,4 +2,5 @@ TEMPLATE = subdirs
SUBDIRS
+=
\
twittertimeline
\
redditclient
redditclient
\
qtgcal
examples/qtgcal/main.cpp
0 → 100644
View file @
54a8c221
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qoauth2authorizationcodeflow.h>
#include <QtCore>
#include <QtNetwork>
#include <QtWidgets>
const
QString
webString
=
QStringLiteral
(
"web"
);
const
QString
clientIdString
=
QStringLiteral
(
"client_id"
);
const
QString
authUriString
=
QStringLiteral
(
"auth_uri"
);
const
QString
tokenUriString
=
QStringLiteral
(
"token_uri"
);
const
QString
clientSecretString
=
QStringLiteral
(
"client_secret"
);
const
QString
redirectUriString
=
QStringLiteral
(
"redirect_uris"
);
QMap
<
QString
,
QString
>
readClientJson
(
const
QString
&
path
)
{
QMap
<
QString
,
QString
>
ret
;
QFile
file
(
path
);
if
(
!
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
))
{
qCritical
()
<<
"Failed to load file"
;
return
ret
;
}
auto
document
=
QJsonDocument
::
fromJson
(
file
.
readAll
());
Q_ASSERT
(
document
.
isObject
());
auto
webObject
=
document
.
object
()[
webString
].
toObject
();
const
auto
saveValue
=
[
&
](
const
QString
&
key
)
{
ret
.
insert
(
key
,
webObject
[
key
].
toString
());
};
saveValue
(
clientIdString
);
saveValue
(
authUriString
);
saveValue
(
authUriString
);
saveValue
(
tokenUriString
);
saveValue
(
clientSecretString
);
ret
.
insert
(
redirectUriString
,
webObject
[
redirectUriString
].
toArray
().
first
().
toString
());
return
ret
;
}
int
main
(
int
argc
,
char
**
argv
)
{
QApplication
app
(
argc
,
argv
);
QMap
<
QString
,
QString
>
clientInfo
;
QCommandLineParser
parser
;
parser
.
addPositionalArgument
(
"client_json"
,
"Specifies the file downloaded from Google APIs "
"Manager"
);
parser
.
process
(
app
);
if
(
parser
.
positionalArguments
().
size
())
clientInfo
=
readClientJson
(
parser
.
positionalArguments
().
first
());
else
parser
.
showHelp
();
QNetworkAccessManager
manager
;
QOAuth2AuthorizationCodeFlow
o2
(
&
manager
,
QUrl
(
clientInfo
[
redirectUriString
]).
port
());
o2
.
setConsumerToken
(
clientInfo
[
clientIdString
]);
o2
.
setAuthorizationUrl
(
clientInfo
[
authUriString
]);
o2
.
setAccessTokenUrl
(
clientInfo
[
tokenUriString
]);
o2
.
setScope
(
"https://www.googleapis.com/auth/calendar.readonly"
);
o2
.
setModifyParametersFunction
([
=
](
const
QAbstractOAuth
::
Stage
stage
,
QVariantMap
*
parameters
)
{
if
(
stage
==
QAbstractOAuth
::
Stage
::
RequestingAuthorization
)
{
}
if
(
stage
==
QAbstractOAuth
::
Stage
::
RequestingAccessToken
)
{
parameters
->
insert
(
clientSecretString
,
QUrl
::
toPercentEncoding
(
clientInfo
[
clientSecretString
]));
parameters
->
insert
(
"grant_type"
,
"authorization_code"
);
}
});
QObject
::
connect
(
&
o2
,
&
QOAuth2AuthorizationCodeFlow
::
authorizationRequested
,
&
QDesktopServices
::
openUrl
);
QNetworkReply
*
reply
=
nullptr
;
QObject
::
connect
(
&
o2
,
&
QOAuth2AuthorizationCodeFlow
::
granted
,
[
&
]()
{
QUrl
url
(
"https://www.googleapis.com/calendar/v3/users/me/calendarList"
);
QNetworkRequest
request
(
url
);
reply
=
o2
.
get
(
request
);
QObject
::
connect
(
reply
,
&
QNetworkReply
::
finished
,
[
reply
]()
{
auto
data
=
reply
->
readAll
();
qDebug
()
<<
data
;
});
});
o2
.
grant
();
return
app
.
exec
();
}
examples/qtgcal/qtgcal.pro
0 → 100644
View file @
54a8c221
QT
+=
network
widgets
TARGET
=
qtgcal
#
Input
SOURCES
+=
\
main
.
cpp
HEADERS
+=
\
include
(..
/../
QtOAuth
.
pri
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment