Skip to content

Commit

Permalink
Dynamic oidc registration
Browse files Browse the repository at this point in the history
  • Loading branch information
TheOneRing committed Jan 18, 2021
1 parent 98c92b7 commit c0b04e4
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 57 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/8350
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Change: Add support for dynamic client registration with OIDC

We implemented support for dynamic client registration with an
OpenID Connect provider.

https://github.com/owncloud/client/pull/8350/
6 changes: 6 additions & 0 deletions src/libsync/creds/abstractcredentials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <QString>
#include <QCoreApplication>

#include "account.h"
#include "common/asserts.h"
#include "creds/abstractcredentials.h"

Expand All @@ -35,6 +36,11 @@ void AbstractCredentials::setAccount(Account *account)
_account = account;
}

QString AbstractCredentials::keychainServerWideKey(Account *acc, const QString &key)
{
return keychainKey(acc->url().toString(), key, {});
}

QString AbstractCredentials::keychainKey(const QString &url, const QString &user, const QString &accountId)
{
QString u(url);
Expand Down
2 changes: 2 additions & 0 deletions src/libsync/creds/abstractcredentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ class OWNCLOUDSYNC_EXPORT AbstractCredentials : public QObject
*/
virtual void forgetSensitiveData() = 0;

// TODO: keys shared for a server could cause a clash when multiple accounts are used
static QString keychainServerWideKey(Account *acc, const QString &key);
static QString keychainKey(const QString &url, const QString &user, const QString &accountId);

Q_SIGNALS:
Expand Down
2 changes: 1 addition & 1 deletion src/libsync/creds/httpcredentials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ void HttpCredentials::persist()
// it's just written if it gets passed into the constructor.
_account->setCredentialSetting(clientCertBundleC(), _clientCertBundle);
}
_account->wantsAccountSaved(_account);
Q_EMIT _account->wantsAccountSaved(_account);

// write secrets to the keychain
if (!_clientCertBundle.isEmpty()) {
Expand Down
235 changes: 184 additions & 51 deletions src/libsync/creds/oauth.cpp

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions src/libsync/creds/oauth.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
#include "accountfwd.h"
#include "owncloudlib.h"

class SimpleNetworkJob;

namespace OCC {
class SimpleNetworkJob;

/**
* Job that do the authorization grant and fetch the access token
Expand Down Expand Up @@ -88,23 +88,26 @@ class OWNCLOUDSYNC_EXPORT OAuth : public QObject
private:

void fetchWellKnown();
void finalize(QPointer<QTcpSocket> socket, const QString &accessToken,
const QString &refreshToken, const QString &userId, const QUrl &messageUrl);
void finalize(const QPointer<QTcpSocket> &socket, const QString &accessToken,
const QString &refreshToken, const QString &userId, const QUrl &messageUrl);

SimpleNetworkJob *postTokenRequest(const QList<QPair<QString, QString>> &queryItems);

QByteArray generateRandomString(size_t size) const;

QVariant getRequiredField(const QJsonObject &json, const QString &s, QString *error);

Account* _account;
QTcpServer _server;
bool _wellKnownFinished = false;

QString _clientId;
QString _clientSecret;

QUrl _authEndpoint;
QUrl _tokenEndpoint;
QUrl _registrationEndpoint;
QByteArray _pkceCodeVerifier;
QByteArray _state;
};


} // namespace OCC
20 changes: 20 additions & 0 deletions src/libsync/networkjobs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,26 @@ void SimpleNetworkJob::prepareRequest(const QByteArray &verb, const QUrl &url,
_simpleBody = requestBody;
}

void SimpleNetworkJob::prepareRequest(const QByteArray &verb, const QUrl &url, const QNetworkRequest &req, const QUrlQuery &arguments)
{
// not a leak
auto requestBody = new QBuffer {};
requestBody->setData(arguments.query(QUrl::FullyEncoded).toUtf8());
auto newReq = req;
newReq.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded; charset=UTF-8"));
return prepareRequest(verb, url, newReq, requestBody);
}

void SimpleNetworkJob::prepareRequest(const QByteArray &verb, const QUrl &url, const QNetworkRequest &req, const QJsonObject &arguments)
{
// not a leak
auto requestBody = new QBuffer {};
requestBody->setData(QJsonDocument(arguments).toJson());
auto newReq = req;
newReq.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
return prepareRequest(verb, url, newReq, requestBody);
}

bool SimpleNetworkJob::finished()
{
emit finishedSignal(reply());
Expand Down
8 changes: 8 additions & 0 deletions src/libsync/networkjobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,14 @@ class OWNCLOUDSYNC_EXPORT SimpleNetworkJob : public AbstractNetworkJob
QNetworkRequest req = QNetworkRequest(),
QIODevice *requestBody = nullptr);

void prepareRequest(const QByteArray &verb, const QUrl &url,
const QNetworkRequest &req,
const QUrlQuery &arguments);

void prepareRequest(const QByteArray &verb, const QUrl &url,
const QNetworkRequest &req,
const QJsonObject &arguments);

void start() override;

signals:
Expand Down

0 comments on commit c0b04e4

Please sign in to comment.