mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-04 21:27:58 +02:00
Update Hatchet account type to current protocol workflow.
This commit is contained in:
@@ -86,7 +86,7 @@ HatchetAccount::HatchetAccount( const QString& accountId )
|
|||||||
setAccountServiceName( "Hatchet" );
|
setAccountServiceName( "Hatchet" );
|
||||||
// We're connecting peers.
|
// We're connecting peers.
|
||||||
setTypes( SipType );
|
setTypes( SipType );
|
||||||
|
/*
|
||||||
QFile pemFile( ":/hatchet-account/mandella.pem" );
|
QFile pemFile( ":/hatchet-account/mandella.pem" );
|
||||||
pemFile.open( QIODevice::ReadOnly );
|
pemFile.open( QIODevice::ReadOnly );
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "certs/mandella.pem: " << pemFile.readAll();
|
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "certs/mandella.pem: " << pemFile.readAll();
|
||||||
@@ -100,6 +100,7 @@ HatchetAccount::HatchetAccount( const QString& accountId )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_publicKey = new QCA::PublicKey( publicKey );
|
m_publicKey = new QCA::PublicKey( publicKey );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -223,66 +224,128 @@ uint
|
|||||||
HatchetAccount::refreshTokenExpiration() const
|
HatchetAccount::refreshTokenExpiration() const
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
return credentials().value( "expiration" ).toUInt( &ok );
|
return credentials().value( "refresh_token_expiration" ).toUInt( &ok );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray
|
||||||
|
HatchetAccount::mandellaAccessToken() const
|
||||||
|
{
|
||||||
|
return credentials().value( "mandella_access_token" ).toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint
|
||||||
|
HatchetAccount::mandellaAccessTokenExpiration() const
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
return credentials().value( "mandella_access_token_expiration" ).toUInt( &ok );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray
|
||||||
|
HatchetAccount::mandellaTokenType() const
|
||||||
|
{
|
||||||
|
return credentials().value( "mandella_token_type" ).toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HatchetAccount::loginWithPassword( const QString& username, const QString& password, const QString &otp )
|
HatchetAccount::loginWithPassword( const QString& username, const QString& password, const QString &otp )
|
||||||
{
|
{
|
||||||
if ( username.isEmpty() || password.isEmpty() || !m_publicKey )
|
//if ( username.isEmpty() || password.isEmpty() || !m_publicKey )
|
||||||
|
if ( username.isEmpty() || password.isEmpty() )
|
||||||
{
|
{
|
||||||
tLog() << "No tomahawk account username or pw or public key, not logging in";
|
tLog() << "No tomahawk account username or pw or public key, not logging in";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
m_uuid = QUuid::createUuid().toString();
|
m_uuid = QUuid::createUuid().toString();
|
||||||
QCA::SecureArray sa( m_uuid.toLatin1() );
|
QCA::SecureArray sa( m_uuid.toLatin1() );
|
||||||
QCA::SecureArray result = m_publicKey->encrypt( sa, QCA::EME_PKCS1_OAEP );
|
QCA::SecureArray result = m_publicKey->encrypt( sa, QCA::EME_PKCS1_OAEP );
|
||||||
|
|
||||||
QVariantMap params;
|
|
||||||
params[ "password" ] = password;
|
|
||||||
params[ "username" ] = username;
|
|
||||||
if ( !otp.isEmpty() )
|
|
||||||
params[ "otp" ] = otp;
|
|
||||||
params[ "client" ] = "Tomahawk (" + QHostInfo::localHostName() + ")";
|
|
||||||
params[ "nonce" ] = QString( result.toByteArray().toBase64() );
|
params[ "nonce" ] = QString( result.toByteArray().toBase64() );
|
||||||
|
*/
|
||||||
|
|
||||||
QJson::Serializer s;
|
QNetworkRequest req( QUrl( c_loginServer + "/authentication/password") );
|
||||||
const QByteArray msgJson = s.serialize( params );
|
req.setHeader( QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded" );
|
||||||
|
|
||||||
|
QUrl params;
|
||||||
|
params.addQueryItem( "username", username );
|
||||||
|
params.addQueryItem( "password", password );
|
||||||
|
params.addQueryItem( "grant_type", "password" );
|
||||||
|
if ( !otp.isEmpty() )
|
||||||
|
params.addQueryItem( "otp", otp );
|
||||||
|
|
||||||
QNetworkRequest req( QUrl( c_loginServer + "/auth/credentials") );
|
QByteArray data = params.encodedQuery();
|
||||||
req.setHeader( QNetworkRequest::ContentTypeHeader, "application/json; charset=utf-8" );
|
|
||||||
QNetworkReply* reply = Tomahawk::Utils::nam()->post( req, msgJson );
|
QNetworkReply* reply = Tomahawk::Utils::nam()->post( req, data );
|
||||||
|
|
||||||
NewClosure( reply, SIGNAL( finished() ), this, SLOT( onPasswordLoginFinished( QNetworkReply*, const QString& ) ), reply, username );
|
NewClosure( reply, SIGNAL( finished() ), this, SLOT( onPasswordLoginFinished( QNetworkReply*, const QString& ) ), reply, username );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HatchetAccount::fetchAccessTokens( const QString& type )
|
HatchetAccount::fetchAccessToken( const QString& type )
|
||||||
{
|
{
|
||||||
if ( username().isEmpty() || refreshToken().isEmpty() )
|
if ( username().isEmpty() )
|
||||||
{
|
{
|
||||||
tLog() << "No refresh token, not logging in";
|
tLog() << "No username, not logging in";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( mandellaAccessToken().isEmpty() ||
|
||||||
|
(mandellaAccessTokenExpiration() < QDateTime::currentDateTime().toTime_t() &&
|
||||||
|
(refreshToken().isEmpty() ||
|
||||||
|
(refreshTokenExpiration() != 0 && refreshTokenExpiration() < QDateTime::currentDateTime().toTime_t()))) )
|
||||||
|
{
|
||||||
|
tLog() << "No valid combination of access/refresh tokens, not logging in";
|
||||||
|
tLog() << "Mandella access token expiration:" << mandellaAccessTokenExpiration() << ", refresh token expiration:" << refreshTokenExpiration();
|
||||||
|
emit authError( "No valid credentials are stored locally, please log in again.", 401, QVariantMap() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( refreshTokenExpiration() < ( QDateTime::currentMSecsSinceEpoch() / 1000 ) )
|
uint matExpiration = mandellaAccessTokenExpiration();
|
||||||
tLog() << "Refresh token has expired, but may still be valid on the server";
|
bool interceptionNeeded = false;
|
||||||
|
|
||||||
tLog() << "Fetching access tokens";
|
if ( matExpiration < QDateTime::currentDateTime().toTime_t() )
|
||||||
QNetworkRequest req( QUrl( c_accessTokenServer + "/tokens/" + type + "?username=" + username() + "&refresh_token=" + refreshToken() ) );
|
{
|
||||||
|
interceptionNeeded = true;
|
||||||
|
tLog() << "Mandella access token has expired, fetching new ones first";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tLog() << "Fetching access tokens of type" << type;
|
||||||
|
}
|
||||||
|
|
||||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( req );
|
QNetworkRequest req( QUrl( c_accessTokenServer + "/tokens/" + (interceptionNeeded ? "refresh/" + QString::fromUtf8(mandellaTokenType()).toLower() : "fetch/" + type) ) );
|
||||||
|
QNetworkReply* reply;
|
||||||
|
|
||||||
connect( reply, SIGNAL( finished() ), this, SLOT( onFetchAccessTokensFinished() ) );
|
if ( interceptionNeeded )
|
||||||
|
{
|
||||||
|
tLog() << "Intercepting; new mandella access token needed";
|
||||||
|
req.setHeader( QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded" );
|
||||||
|
QUrl params;
|
||||||
|
params.addQueryItem( "grant_type", "refresh_token" );
|
||||||
|
params.addQueryItem( "refresh_token", refreshToken() );
|
||||||
|
QByteArray data = params.encodedQuery();
|
||||||
|
reply = Tomahawk::Utils::nam()->post( req, data );
|
||||||
|
reply->setProperty( "originalType", type );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tLog() << "Fetching token of type" << type;
|
||||||
|
req.setRawHeader( "Authorization", QString( mandellaTokenType() + " " + mandellaAccessToken()).toUtf8() );
|
||||||
|
reply = Tomahawk::Utils::nam()->get( req );
|
||||||
|
}
|
||||||
|
|
||||||
|
NewClosure( reply, SIGNAL( finished() ), this, SLOT( onFetchAccessTokenFinished( QNetworkReply*, const QString& ) ), reply, type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HatchetAccount::onPasswordLoginFinished( QNetworkReply* reply, const QString& username )
|
HatchetAccount::onPasswordLoginFinished( QNetworkReply* reply, const QString& username )
|
||||||
{
|
{
|
||||||
|
tLog() << Q_FUNC_INFO;
|
||||||
Q_ASSERT( reply );
|
Q_ASSERT( reply );
|
||||||
bool ok;
|
bool ok;
|
||||||
int statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt( &ok );
|
int statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt( &ok );
|
||||||
@@ -307,12 +370,13 @@ HatchetAccount::onPasswordLoginFinished( QNetworkReply* reply, const QString& us
|
|||||||
}
|
}
|
||||||
if ( statusCode >= 400 )
|
if ( statusCode >= 400 )
|
||||||
{
|
{
|
||||||
QString errString = resp.value( "result" ).toMap().value( "errorinfo" ).toMap().value( "description" ).toString();
|
QString errString = resp.value( "error_description" ).toString();
|
||||||
tLog() << Q_FUNC_INFO << "An error was returned from the authentication server: " << errString;
|
tLog() << Q_FUNC_INFO << "An error was returned from the authentication server: " << errString;
|
||||||
emit authError( errString, statusCode, resp );
|
emit authError( errString, statusCode, resp );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
const QString nonce = resp.value( "result" ).toMap().value( "nonce" ).toString();
|
const QString nonce = resp.value( "result" ).toMap().value( "nonce" ).toString();
|
||||||
if ( nonce != m_uuid )
|
if ( nonce != m_uuid )
|
||||||
{
|
{
|
||||||
@@ -320,32 +384,59 @@ HatchetAccount::onPasswordLoginFinished( QNetworkReply* reply, const QString& us
|
|||||||
emit authError( "The nonce value was incorrect. YOUR ACCOUNT MAY BE COMPROMISED.", statusCode, resp );
|
emit authError( "The nonce value was incorrect. YOUR ACCOUNT MAY BE COMPROMISED.", statusCode, resp );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
const QByteArray refreshTokenBytes = resp.value( "result" ).toMap().value( "refresh_token" ).toByteArray();
|
const QByteArray refreshTokenBytes = resp.value( "refresh_token" ).toByteArray();
|
||||||
uint expiration = resp.value( "result" ).toMap().value( "expiration" ).toUInt( &ok );
|
uint refreshTokenExpiration = resp.value( "refresh_token_expires_in" ).toUInt( &ok );
|
||||||
|
if ( refreshTokenBytes.isEmpty() || !ok )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Error reading refresh token or its expiration";
|
||||||
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QByteArray accessTokenBytes = resp.value( "access_token" ).toByteArray();
|
||||||
|
uint accessTokenExpiration = resp.value( "expires_in" ).toUInt( &ok );
|
||||||
|
if ( accessTokenBytes.isEmpty() || !ok )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Error reading access token or its expiration";
|
||||||
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QByteArray tokenTypeBytes = resp.value( "token_type" ).toByteArray();
|
||||||
|
if ( tokenTypeBytes.isEmpty() )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Error reading access token type";
|
||||||
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QVariantHash creds = credentials();
|
QVariantHash creds = credentials();
|
||||||
creds[ "username" ] = username;
|
creds[ "username" ] = username;
|
||||||
creds[ "refresh_token" ] = refreshTokenBytes;
|
creds[ "refresh_token" ] = refreshTokenBytes;
|
||||||
creds[ "expiration" ] = expiration;
|
creds[ "refresh_token_expiration" ] = refreshTokenExpiration == 0 ? 0 : QDateTime::currentDateTime().toTime_t() + refreshTokenExpiration;
|
||||||
|
creds[ "mandella_access_token" ] = accessTokenBytes;
|
||||||
|
creds[ "mandella_access_token_expiration" ] = QDateTime::currentDateTime().toTime_t() + accessTokenExpiration;
|
||||||
|
creds[ "mandella_token_type" ] = tokenTypeBytes;
|
||||||
setCredentials( creds );
|
setCredentials( creds );
|
||||||
syncConfig();
|
syncConfig();
|
||||||
|
|
||||||
if ( !refreshTokenBytes.isEmpty() )
|
if ( sipPlugin() )
|
||||||
{
|
sipPlugin()->connectPlugin();
|
||||||
if ( sipPlugin() )
|
|
||||||
sipPlugin()->connectPlugin();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HatchetAccount::onFetchAccessTokensFinished()
|
HatchetAccount::onFetchAccessTokenFinished( QNetworkReply* reply, const QString& type )
|
||||||
{
|
{
|
||||||
tLog() << Q_FUNC_INFO;
|
tLog() << Q_FUNC_INFO;
|
||||||
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
|
|
||||||
Q_ASSERT( reply );
|
Q_ASSERT( reply );
|
||||||
|
|
||||||
|
QString originalType;
|
||||||
|
if ( reply->property( "originalType" ).isValid() )
|
||||||
|
{
|
||||||
|
originalType = reply->property( "originalType" ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
int statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt( &ok );
|
int statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt( &ok );
|
||||||
if ( !ok )
|
if ( !ok )
|
||||||
@@ -369,36 +460,59 @@ HatchetAccount::onFetchAccessTokensFinished()
|
|||||||
}
|
}
|
||||||
if ( statusCode >= 400 )
|
if ( statusCode >= 400 )
|
||||||
{
|
{
|
||||||
QString errString = resp.value( "result" ).toMap().value( "errorinfo" ).toMap().value( "description" ).toString();
|
QString errString = resp.value( "error_description" ).toString();
|
||||||
tLog() << Q_FUNC_INFO << "An error was returned from the authentication server: " << errString;
|
tLog() << Q_FUNC_INFO << "An error was returned from the authentication server: " << errString;
|
||||||
emit authError( errString, statusCode, resp );
|
emit authError( errString, statusCode, resp );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantHash creds = credentials();
|
QVariantHash creds = credentials();
|
||||||
QStringList tokenTypesFound;
|
|
||||||
|
|
||||||
tDebug() << Q_FUNC_INFO << "resp: " << resp;
|
if ( !originalType.isEmpty() )
|
||||||
|
|
||||||
if ( resp[ "result" ].toMap().contains( "refresh_token_expiration" ) )
|
|
||||||
{
|
{
|
||||||
bool ok;
|
const QByteArray accessTokenBytes = resp.value( "access_token" ).toByteArray();
|
||||||
uint expiration = resp.value( "result" ).toMap().value( "refresh_token_expiration" ).toUInt( &ok );
|
uint accessTokenExpiration = resp.value( "expires_in" ).toUInt( &ok );
|
||||||
creds[ "expiration" ] = expiration;
|
if ( accessTokenBytes.isEmpty() || !ok )
|
||||||
}
|
|
||||||
|
|
||||||
foreach( QVariant tokenVariant, resp[ "result" ].toMap()[ "tokens" ].toList() )
|
|
||||||
{
|
|
||||||
QVariantMap tokenMap = tokenVariant.toMap();
|
|
||||||
QString tokenTypeName = tokenMap[ "type" ].toString() + "tokens";
|
|
||||||
if ( !tokenTypesFound.contains( tokenTypeName ) )
|
|
||||||
{
|
{
|
||||||
creds[ tokenTypeName ] = QVariantList();
|
tLog() << Q_FUNC_INFO << "Error reading access token or its expiration";
|
||||||
tokenTypesFound.append( tokenTypeName );
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
creds[ tokenTypeName ] = creds[ tokenTypeName ].toList() << tokenMap;
|
const QByteArray tokenTypeBytes = resp.value( "token_type" ).toByteArray();
|
||||||
|
if ( tokenTypeBytes.isEmpty() )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Error reading access token type";
|
||||||
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
creds[ "mandella_access_token" ] = accessTokenBytes;
|
||||||
|
creds[ "mandella_access_token_expiration" ] = QDateTime::currentDateTime().toTime_t() + accessTokenExpiration;
|
||||||
|
creds[ "mandella_token_type" ] = tokenTypeBytes;
|
||||||
|
setCredentials( creds );
|
||||||
|
syncConfig();
|
||||||
|
|
||||||
|
fetchAccessToken( originalType );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QByteArray accessTokenBytes = resp.value( "access_token" ).toByteArray();
|
||||||
|
uint accessTokenExpiration = resp.value( "expires_in" ).toUInt( &ok );
|
||||||
|
if ( accessTokenBytes.isEmpty() || !ok )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Error reading access token or its expiration";
|
||||||
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const QByteArray tokenTypeBytes = resp.value( "token_type" ).toByteArray();
|
||||||
|
if ( tokenTypeBytes.isEmpty() )
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Error reading access token type";
|
||||||
|
emit authError( "An error encountered parsing the authentication server's response", 0, QVariantMap() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
creds[ type + "_access_token" ] = accessTokenBytes;
|
||||||
|
|
||||||
tDebug() << Q_FUNC_INFO << "Creds: " << creds;
|
tDebug() << Q_FUNC_INFO << "Creds: " << creds;
|
||||||
|
|
||||||
setCredentials( creds );
|
setCredentials( creds );
|
||||||
@@ -406,7 +520,7 @@ HatchetAccount::onFetchAccessTokensFinished()
|
|||||||
|
|
||||||
tLog() << Q_FUNC_INFO << "Access tokens fetched successfully";
|
tLog() << Q_FUNC_INFO << "Access tokens fetched successfully";
|
||||||
|
|
||||||
emit accessTokensFetched();
|
emit accessTokenFetched();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -79,7 +79,6 @@ public:
|
|||||||
void setConnectionState( Account::ConnectionState connectionState );
|
void setConnectionState( Account::ConnectionState connectionState );
|
||||||
ConnectionState connectionState() const;
|
ConnectionState connectionState() const;
|
||||||
|
|
||||||
|
|
||||||
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin() { return Tomahawk::InfoSystem::InfoPluginPtr(); }
|
virtual Tomahawk::InfoSystem::InfoPluginPtr infoPlugin() { return Tomahawk::InfoSystem::InfoPluginPtr(); }
|
||||||
SipPlugin* sipPlugin( bool create = true );
|
SipPlugin* sipPlugin( bool create = true );
|
||||||
|
|
||||||
@@ -88,24 +87,29 @@ public:
|
|||||||
|
|
||||||
QString username() const;
|
QString username() const;
|
||||||
|
|
||||||
void fetchAccessTokens( const QString& type = "dreamcatcher" );
|
void fetchAccessToken( const QString& type = "dreamcatcher" );
|
||||||
|
|
||||||
QString authUrlForService( const Service& service ) const;
|
QString authUrlForService( const Service& service ) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void authError( QString error, int statusCode, const QVariantMap );
|
void authError( QString error, int statusCode, const QVariantMap );
|
||||||
void deauthenticated();
|
void deauthenticated();
|
||||||
void accessTokensFetched();
|
void accessTokenFetched();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onPasswordLoginFinished( QNetworkReply*, const QString& username );
|
void onPasswordLoginFinished( QNetworkReply*, const QString& username );
|
||||||
void onFetchAccessTokensFinished();
|
void onFetchAccessTokenFinished( QNetworkReply*, const QString& type );
|
||||||
void authUrlDiscovered( Tomahawk::Accounts::HatchetAccount::Service service, const QString& authUrl );
|
void authUrlDiscovered( Tomahawk::Accounts::HatchetAccount::Service service, const QString& authUrl );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray refreshToken() const;
|
QByteArray refreshToken() const;
|
||||||
uint refreshTokenExpiration() const;
|
uint refreshTokenExpiration() const;
|
||||||
|
|
||||||
|
QByteArray mandellaAccessToken() const;
|
||||||
|
uint mandellaAccessTokenExpiration() const;
|
||||||
|
|
||||||
|
QByteArray mandellaTokenType() const;
|
||||||
|
|
||||||
void loginWithPassword( const QString& username, const QString& password, const QString &otp );
|
void loginWithPassword( const QString& username, const QString& password, const QString &otp );
|
||||||
|
|
||||||
QVariantMap parseReply( QNetworkReply* reply, bool& ok ) const;
|
QVariantMap parseReply( QNetworkReply* reply, bool& ok ) const;
|
||||||
|
@@ -56,7 +56,7 @@ HatchetAccountConfig::HatchetAccountConfig( HatchetAccount* account )
|
|||||||
|
|
||||||
connect( m_account, SIGNAL( authError( QString, int, QVariantMap ) ), this, SLOT( authError( QString, int, QVariantMap ) ) );
|
connect( m_account, SIGNAL( authError( QString, int, QVariantMap ) ), this, SLOT( authError( QString, int, QVariantMap ) ) );
|
||||||
connect( m_account, SIGNAL( deauthenticated() ), this, SLOT( showLoggedOut() ) );
|
connect( m_account, SIGNAL( deauthenticated() ), this, SLOT( showLoggedOut() ) );
|
||||||
connect( m_account, SIGNAL( accessTokensFetched() ), this, SLOT( accountInfoUpdated() ) );
|
connect( m_account, SIGNAL( accessTokenFetched() ), this, SLOT( accountInfoUpdated() ) );
|
||||||
|
|
||||||
if ( !m_account->refreshToken().isEmpty() )
|
if ( !m_account->refreshToken().isEmpty() )
|
||||||
accountInfoUpdated();
|
accountInfoUpdated();
|
||||||
@@ -170,7 +170,7 @@ HatchetAccountConfig::accountInfoUpdated()
|
|||||||
void
|
void
|
||||||
HatchetAccountConfig::authError( const QString &error, int statusCode, const QVariantMap& resp )
|
HatchetAccountConfig::authError( const QString &error, int statusCode, const QVariantMap& resp )
|
||||||
{
|
{
|
||||||
if ( statusCode == 401 && resp["result"].toMap()["errorinfo"].toMap().contains("missingotp") )
|
if ( statusCode == 400 && error == "otp_needed" )
|
||||||
{
|
{
|
||||||
m_ui->usernameLabel->hide();
|
m_ui->usernameLabel->hide();
|
||||||
m_ui->usernameEdit->hide();
|
m_ui->usernameEdit->hide();
|
||||||
@@ -182,7 +182,7 @@ HatchetAccountConfig::authError( const QString &error, int statusCode, const QVa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( statusCode == 401 )
|
if ( statusCode == 401 )
|
||||||
m_account->deauthenticate();
|
m_account->deauthenticate();
|
||||||
QMessageBox::critical( this, "An error was encountered:", error );
|
QMessageBox::critical( this, "An error was encountered:", error );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,7 +48,7 @@ HatchetSipPlugin::HatchetSipPlugin( Tomahawk::Accounts::Account *account )
|
|||||||
{
|
{
|
||||||
tLog() << Q_FUNC_INFO;
|
tLog() << Q_FUNC_INFO;
|
||||||
|
|
||||||
connect( m_account, SIGNAL( accessTokensFetched() ), this, SLOT( connectWebSocket() ) );
|
connect( m_account, SIGNAL( accessTokenFetched() ), this, SLOT( connectWebSocket() ) );
|
||||||
connect( Servent::instance(), SIGNAL( dbSyncTriggered() ), this, SLOT( dbSyncTriggered() ));
|
connect( Servent::instance(), SIGNAL( dbSyncTriggered() ), this, SLOT( dbSyncTriggered() ));
|
||||||
|
|
||||||
QFile pemFile( ":/hatchet-account/dreamcatcher.pem" );
|
QFile pemFile( ":/hatchet-account/dreamcatcher.pem" );
|
||||||
@@ -113,7 +113,7 @@ HatchetSipPlugin::connectPlugin()
|
|||||||
}
|
}
|
||||||
|
|
||||||
hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Connecting );
|
hatchetAccount()->setConnectionState( Tomahawk::Accounts::Account::Connecting );
|
||||||
hatchetAccount()->fetchAccessTokens();
|
hatchetAccount()->fetchAccessToken( "dreamcatcher" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -156,42 +156,18 @@ HatchetSipPlugin::connectWebSocket()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_token.clear();
|
m_token = m_account->credentials()[ "dreamcatcher_access_token" ].toString();
|
||||||
|
|
||||||
QVariantList tokensCreds = m_account->credentials()[ "dreamcatchertokens" ].toList();
|
|
||||||
|
|
||||||
//FIXME: Don't blindly pick the first one that matches? Most likely, cycle through if the first one fails
|
if ( m_token.isEmpty() )
|
||||||
QVariantMap connectVals;
|
|
||||||
foreach ( QVariant credObj, tokensCreds )
|
|
||||||
{
|
{
|
||||||
QVariantMap creds = credObj.toMap();
|
tLog() << Q_FUNC_INFO << "Unable to find an access token";
|
||||||
if ( creds.contains( "type" ) && creds[ "type" ].toString() == "dreamcatcher" )
|
|
||||||
{
|
|
||||||
connectVals = creds;
|
|
||||||
m_token = creds[ "token" ].toString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString url;
|
|
||||||
if ( !connectVals.isEmpty() )
|
|
||||||
{
|
|
||||||
QString port = connectVals[ "port" ].toString();
|
|
||||||
if ( port == "443" )
|
|
||||||
url = "wss://";
|
|
||||||
else
|
|
||||||
url = "ws://";
|
|
||||||
url += connectVals[ "host" ].toString() + ':' + connectVals[ "port" ].toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( url.isEmpty() || m_token.isEmpty() )
|
|
||||||
{
|
|
||||||
tLog() << Q_FUNC_INFO << "Unable to find a proper connection endpoint; bailing";
|
|
||||||
disconnectPlugin();
|
disconnectPlugin();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
tLog() << Q_FUNC_INFO << "Connecting to Dreamcatcher endpoint at: " << url;
|
QString url( "wss://dreamcatcher.hatchet.is:443" );
|
||||||
|
tLog() << Q_FUNC_INFO << "Connecting to Dreamcatcher endpoint at: " << url;
|
||||||
|
|
||||||
m_webSocketThreadController->setUrl( url );
|
m_webSocketThreadController->setUrl( url );
|
||||||
m_webSocketThreadController->start();
|
m_webSocketThreadController->start();
|
||||||
|
Reference in New Issue
Block a user