return _user;
}
-QNetworkAccessManager *ShibbolethCredentials::getQNAM() const
+QNetworkAccessManager *ShibbolethCredentials::createQNAM() const
{
QNetworkAccessManager *qnam(new AccessManager);
connect(qnam, SIGNAL(finished(QNetworkReply *)),
void setAccount(Account *account) Q_DECL_OVERRIDE;
QString authType() const Q_DECL_OVERRIDE;
QString user() const Q_DECL_OVERRIDE;
- QNetworkAccessManager *getQNAM() const Q_DECL_OVERRIDE;
+ QNetworkAccessManager *createQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
void fetchFromKeychain() Q_DECL_OVERRIDE;
void askFromUser() Q_DECL_OVERRIDE;
// The order for these two is important! Reading the credential's
// settings accesses the account as well as account->_credentials,
- // so deleteLater must be used.
- _credentials = QSharedPointer<AbstractCredentials>(cred, &QObject::deleteLater);
+ _credentials.reset(cred);
cred->setAccount(this);
- _am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
+ // Note: This way the QNAM can outlive the Account and Credentials.
+ // This is necessary to avoid issues with the QNAM being deleted while
+ // processing slotHandleSslErrors().
+ _am = QSharedPointer<QNetworkAccessManager>(_credentials->createQNAM(), &QObject::deleteLater);
if (jar) {
_am->setCookieJar(jar);
// Use a QSharedPointer to allow locking the life of the QNAM on the stack.
// Make it call deleteLater to make sure that we can return to any QNAM stack frames safely.
- _am = QSharedPointer<QNetworkAccessManager>(_credentials->getQNAM(), &QObject::deleteLater);
+ _am = QSharedPointer<QNetworkAccessManager>(_credentials->createQNAM(), &QObject::deleteLater);
_am->setCookieJar(jar); // takes ownership of the old cookie jar
connect(_am.data(), SIGNAL(sslErrors(QNetworkReply *, QList<QSslError>)),
QScopedPointer<AbstractSslErrorHandler> _sslErrorHandler;
QuotaInfo *_quotaInfo;
QSharedPointer<QNetworkAccessManager> _am;
- QSharedPointer<AbstractCredentials> _credentials;
+ QScopedPointer<AbstractCredentials> _credentials;
/// Certificates that were explicitly rejected by the user
QList<QSslCertificate> _rejectedCertificates;
virtual QString authType() const = 0;
virtual QString user() const = 0;
- virtual QNetworkAccessManager *getQNAM() const = 0;
+ virtual QNetworkAccessManager *createQNAM() const = 0;
/** Whether there are credentials that can be used for a connection attempt. */
virtual bool ready() const = 0;
return _user;
}
-QNetworkAccessManager *DummyCredentials::getQNAM() const
+QNetworkAccessManager *DummyCredentials::createQNAM() const
{
return new AccessManager;
}
QString _password;
QString authType() const Q_DECL_OVERRIDE;
QString user() const Q_DECL_OVERRIDE;
- QNetworkAccessManager *getQNAM() const Q_DECL_OVERRIDE;
+ QNetworkAccessManager *createQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
void fetchFromKeychain() Q_DECL_OVERRIDE;
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) Q_DECL_OVERRIDE
{
QNetworkRequest req(request);
- if (!_cred->password().isEmpty()) {
+ if (_cred && !_cred->password().isEmpty()) {
if (_cred->isUsingOAuth()) {
req.setRawHeader("Authorization", "Bearer " + _cred->password().toUtf8());
} else {
req.setRawHeader("Authorization", "Basic " + credHash);
}
- if (!_cred->_clientSslKey.isNull() && !_cred->_clientSslCertificate.isNull()) {
+ if (_cred && !_cred->_clientSslKey.isNull() && !_cred->_clientSslCertificate.isNull()) {
// SSL configuration
QSslConfiguration sslConfiguration = req.sslConfiguration();
sslConfiguration.setLocalCertificate(_cred->_clientSslCertificate);
}
private:
- const HttpCredentials *_cred;
+ // The credentials object dies along with the account, while the QNAM might
+ // outlive both.
+ QPointer<const HttpCredentials> _cred;
};
}
}
-QNetworkAccessManager *HttpCredentials::getQNAM() const
+QNetworkAccessManager *HttpCredentials::createQNAM() const
{
AccessManager *qnam = new HttpCredentialsAccessManager(this);
HttpCredentials(const QString &user, const QString &password, const QSslCertificate &certificate = QSslCertificate(), const QSslKey &key = QSslKey());
QString authType() const Q_DECL_OVERRIDE;
- QNetworkAccessManager *getQNAM() const Q_DECL_OVERRIDE;
+ QNetworkAccessManager *createQNAM() const Q_DECL_OVERRIDE;
bool ready() const Q_DECL_OVERRIDE;
void fetchFromKeychain() Q_DECL_OVERRIDE;
bool stillValid(QNetworkReply *reply) Q_DECL_OVERRIDE;
FakeCredentials(QNetworkAccessManager *qnam) : _qnam{qnam} { }
virtual QString authType() const { return "test"; }
virtual QString user() const { return "admin"; }
- virtual QNetworkAccessManager* getQNAM() const { return _qnam; }
+ virtual QNetworkAccessManager *createQNAM() const { return _qnam; }
virtual bool ready() const { return true; }
virtual void fetchFromKeychain() { }
virtual void askFromUser() { }