mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
more work on authentication, show login window when domain asks
This commit is contained in:
parent
c762b92e5a
commit
8a0136efe1
13 changed files with 165 additions and 35 deletions
|
@ -41,7 +41,7 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
_staticAssignmentHash(),
|
_staticAssignmentHash(),
|
||||||
_assignmentQueue(),
|
_assignmentQueue(),
|
||||||
_hasCompletedRestartHold(false),
|
_hasCompletedRestartHold(false),
|
||||||
_nodeAuthenticationHostname(DEFAULT_NODE_AUTH_URL)
|
_nodeAuthenticationURL(DEFAULT_NODE_AUTH_URL)
|
||||||
{
|
{
|
||||||
const char CUSTOM_PORT_OPTION[] = "-p";
|
const char CUSTOM_PORT_OPTION[] = "-p";
|
||||||
const char* customPortString = getCmdOption(argc, (const char**) argv, CUSTOM_PORT_OPTION);
|
const char* customPortString = getCmdOption(argc, (const char**) argv, CUSTOM_PORT_OPTION);
|
||||||
|
@ -65,9 +65,9 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
const QString NO_AUTH_OPTION = "--noAuth";
|
const QString NO_AUTH_OPTION = "--noAuth";
|
||||||
const QString CUSTOM_AUTH_OPTION = "--customAuth";
|
const QString CUSTOM_AUTH_OPTION = "--customAuth";
|
||||||
if ((argumentIndex = argumentList.indexOf(NO_AUTH_OPTION) != -1)) {
|
if ((argumentIndex = argumentList.indexOf(NO_AUTH_OPTION) != -1)) {
|
||||||
_nodeAuthenticationHostname = QUrl();
|
_nodeAuthenticationURL = QUrl();
|
||||||
} else if ((argumentIndex = argumentList.indexOf(CUSTOM_AUTH_OPTION)) != -1) {
|
} else if ((argumentIndex = argumentList.indexOf(CUSTOM_AUTH_OPTION)) != -1) {
|
||||||
_nodeAuthenticationHostname = QUrl(argumentList.value(argumentIndex + 1));
|
_nodeAuthenticationURL = QUrl(argumentList.value(argumentIndex + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort);
|
NodeList* nodeList = NodeList::createInstance(NodeType::DomainServer, domainServerPort);
|
||||||
|
@ -254,14 +254,14 @@ void DomainServer::readAvailableDatagrams() {
|
||||||
|
|
||||||
QUuid nodeUUID = uuidFromPacketHeader(receivedPacket);
|
QUuid nodeUUID = uuidFromPacketHeader(receivedPacket);
|
||||||
|
|
||||||
if (!_nodeAuthenticationHostname.isEmpty() &&
|
if (!_nodeAuthenticationURL.isEmpty() &&
|
||||||
(nodeUUID.isNull() || !nodeList->nodeWithUUID(nodeUUID))) {
|
(nodeUUID.isNull() || !nodeList->nodeWithUUID(nodeUUID))) {
|
||||||
// this is a node we do not recognize and we need authentication - ask them to do so
|
// this is a node we do not recognize and we need authentication - ask them to do so
|
||||||
// by providing them the hostname they should authenticate with
|
// by providing them the hostname they should authenticate with
|
||||||
QByteArray authenticationRequestPacket = byteArrayWithPopluatedHeader(PacketTypeDomainServerAuthRequest);
|
QByteArray authenticationRequestPacket = byteArrayWithPopluatedHeader(PacketTypeDomainServerAuthRequest);
|
||||||
|
|
||||||
QDataStream authPacketStream(&authenticationRequestPacket, QIODevice::Append);
|
QDataStream authPacketStream(&authenticationRequestPacket, QIODevice::Append);
|
||||||
authPacketStream << _nodeAuthenticationHostname;
|
authPacketStream << _nodeAuthenticationURL;
|
||||||
|
|
||||||
qDebug() << "Asking node at" << senderSockAddr << "to authenticate.";
|
qDebug() << "Asking node at" << senderSockAddr << "to authenticate.";
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ private:
|
||||||
|
|
||||||
bool _hasCompletedRestartHold;
|
bool _hasCompletedRestartHold;
|
||||||
|
|
||||||
QUrl _nodeAuthenticationHostname;
|
QUrl _nodeAuthenticationURL;
|
||||||
private slots:
|
private slots:
|
||||||
void readAvailableDatagrams();
|
void readAvailableDatagrams();
|
||||||
void addStaticAssignmentsBackToQueueAfterRestart();
|
void addStaticAssignmentsBackToQueueAfterRestart();
|
||||||
|
|
|
@ -207,6 +207,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
||||||
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), &_voxels, SLOT(nodeKilled(SharedNodePointer)));
|
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), &_voxels, SLOT(nodeKilled(SharedNodePointer)));
|
||||||
connect(nodeList, &NodeList::uuidChanged, this, &Application::updateWindowTitle);
|
connect(nodeList, &NodeList::uuidChanged, this, &Application::updateWindowTitle);
|
||||||
|
|
||||||
|
connect(&AccountManager::getInstance(), SIGNAL(authenticationRequiredForRootURL(const QUrl&)),
|
||||||
|
Menu::getInstance(), SLOT(showLoginForRootURL(const QUrl&)));
|
||||||
|
|
||||||
// read the ApplicationInfo.ini file for Name/Version/Domain information
|
// read the ApplicationInfo.ini file for Name/Version/Domain information
|
||||||
QSettings applicationInfo("resources/info/ApplicationInfo.ini", QSettings::IniFormat);
|
QSettings applicationInfo("resources/info/ApplicationInfo.ini", QSettings::IniFormat);
|
||||||
|
|
||||||
|
@ -4216,6 +4219,5 @@ void Application::takeSnapshot() {
|
||||||
player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
||||||
player->play();
|
player->play();
|
||||||
|
|
||||||
Snapshot::saveSnapshot(_glWidget, AccountManager::getUsername(), _myAvatar->getPosition());
|
Snapshot::saveSnapshot(_glWidget, AccountManager::getInstance().getUsername(), _myAvatar->getPosition());
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ Menu::Menu() :
|
||||||
MenuOption::Login,
|
MenuOption::Login,
|
||||||
0,
|
0,
|
||||||
this,
|
this,
|
||||||
SLOT(login())));
|
SLOT(loginForCurrentDomain())));
|
||||||
|
|
||||||
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
addDisabledActionAndSeparator(fileMenu, "Scripts");
|
||||||
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadDialog()));
|
addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadDialog()));
|
||||||
|
@ -737,7 +737,11 @@ void sendFakeEnterEvent() {
|
||||||
const int QLINE_MINIMUM_WIDTH = 400;
|
const int QLINE_MINIMUM_WIDTH = 400;
|
||||||
const float DIALOG_RATIO_OF_WINDOW = 0.30f;
|
const float DIALOG_RATIO_OF_WINDOW = 0.30f;
|
||||||
|
|
||||||
void Menu::login() {
|
void Menu::loginForCurrentDomain() {
|
||||||
|
showLoginForRootURL(NodeList::getInstance()->getDomainInfo().getRootAuthenticationURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Menu::showLoginForRootURL(const QUrl& rootURL) {
|
||||||
QInputDialog loginDialog(Application::getInstance()->getWindow());
|
QInputDialog loginDialog(Application::getInstance()->getWindow());
|
||||||
loginDialog.setWindowTitle("Login");
|
loginDialog.setWindowTitle("Login");
|
||||||
loginDialog.setLabelText("Username:");
|
loginDialog.setLabelText("Username:");
|
||||||
|
|
|
@ -76,7 +76,6 @@ public:
|
||||||
int getMaxVoxels() const { return _maxVoxels; }
|
int getMaxVoxels() const { return _maxVoxels; }
|
||||||
QAction* getUseVoxelShader() const { return _useVoxelShader; }
|
QAction* getUseVoxelShader() const { return _useVoxelShader; }
|
||||||
|
|
||||||
|
|
||||||
void handleViewFrustumOffsetKeyModifier(int key);
|
void handleViewFrustumOffsetKeyModifier(int key);
|
||||||
|
|
||||||
// User Tweakable LOD Items
|
// User Tweakable LOD Items
|
||||||
|
@ -102,6 +101,8 @@ public:
|
||||||
void goToDomain(const QString newDomain);
|
void goToDomain(const QString newDomain);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void loginForCurrentDomain();
|
||||||
|
void showLoginForRootURL(const QUrl& rootURL);
|
||||||
void bandwidthDetails();
|
void bandwidthDetails();
|
||||||
void voxelStatsDetails();
|
void voxelStatsDetails();
|
||||||
void lodTools();
|
void lodTools();
|
||||||
|
@ -114,7 +115,6 @@ public slots:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void aboutApp();
|
void aboutApp();
|
||||||
void login();
|
|
||||||
void editPreferences();
|
void editPreferences();
|
||||||
void goToDomain();
|
void goToDomain();
|
||||||
void goToLocation();
|
void goToLocation();
|
||||||
|
|
|
@ -7,21 +7,34 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <QtCore/QDataStream>
|
#include <QtCore/QDataStream>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
|
||||||
#include "PacketHeaders.h"
|
#include "PacketHeaders.h"
|
||||||
|
|
||||||
#include "AccountManager.h"
|
#include "AccountManager.h"
|
||||||
|
|
||||||
QString AccountManager::_username = "";
|
AccountManager& AccountManager::getInstance() {
|
||||||
|
static AccountManager sharedInstance;
|
||||||
|
return sharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
void AccountManager::processDomainServerAuthRequest(const QByteArray& packet) {
|
AccountManager::AccountManager() :
|
||||||
QDataStream authPacketStream(packet);
|
_username(),
|
||||||
authPacketStream.skipRawData(numBytesForPacketHeader(packet));
|
_accessTokens(),
|
||||||
|
_networkAccessManager(NULL)
|
||||||
|
{
|
||||||
|
|
||||||
// grab the hostname this domain-server wants us to authenticate with
|
}
|
||||||
QString authenticationHostname;
|
|
||||||
authPacketStream >> authenticationHostname;
|
bool AccountManager::hasValidAccessTokenForRootURL(const QUrl &rootURL) {
|
||||||
|
OAuthAccessToken accessToken = _accessTokens.value(rootURL);
|
||||||
// check if we already have an access token associated with that hostname
|
|
||||||
|
|
||||||
|
if (accessToken.token.isEmpty() || accessToken.isExpired()) {
|
||||||
|
// emit a signal so somebody can call back to us and request an access token given a username and password
|
||||||
|
qDebug() << "An access token is required for requests to" << qPrintable(rootURL.toString());
|
||||||
|
emit authenticationRequiredForRootURL(rootURL);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -10,15 +10,33 @@
|
||||||
#define __hifi__AccountManager__
|
#define __hifi__AccountManager__
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtNetwork/QNetworkAccessManager>
|
||||||
|
|
||||||
class AccountManager {
|
#include "OAuthAccessToken.h"
|
||||||
|
|
||||||
|
class AccountManager : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static void processDomainServerAuthRequest(const QByteArray& packet);
|
static AccountManager& getInstance();
|
||||||
|
|
||||||
static const QString& getUsername() { return _username; }
|
bool hasValidAccessTokenForRootURL(const QUrl& rootURL);
|
||||||
static void setUsername(const QString& username) { _username = username; }
|
|
||||||
|
const QString& getUsername() const { return _username; }
|
||||||
|
void setUsername(const QString& username) { _username = username; }
|
||||||
|
|
||||||
|
void setNetworkAccessManager(QNetworkAccessManager* networkAccessManager) { _networkAccessManager = networkAccessManager; }
|
||||||
|
signals:
|
||||||
|
void authenticationRequiredForRootURL(const QUrl& rootURL);
|
||||||
private:
|
private:
|
||||||
static QString _username;
|
AccountManager();
|
||||||
|
AccountManager(AccountManager const& other); // not implemented
|
||||||
|
void operator=(AccountManager const& other); // not implemented
|
||||||
|
|
||||||
|
QString _username;
|
||||||
|
QMap<QUrl, OAuthAccessToken> _accessTokens;
|
||||||
|
QNetworkAccessManager* _networkAccessManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__AccountManager__) */
|
#endif /* defined(__hifi__AccountManager__) */
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
DomainInfo::DomainInfo() :
|
DomainInfo::DomainInfo() :
|
||||||
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
_sockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||||
_requiresAuthentication(false),
|
|
||||||
_connectionSecret(),
|
_connectionSecret(),
|
||||||
_registrationToken()
|
_registrationToken(),
|
||||||
|
_rootAuthenticationURL()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QUuid>
|
#include <QtCore/QUuid>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
#include <QtNetwork/QHostInfo>
|
#include <QtNetwork/QHostInfo>
|
||||||
|
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
|
@ -34,14 +35,15 @@ public:
|
||||||
|
|
||||||
unsigned short getPort() const { return _sockAddr.getPort(); }
|
unsigned short getPort() const { return _sockAddr.getPort(); }
|
||||||
|
|
||||||
bool requiresAuthentication() const { return _requiresAuthentication; }
|
|
||||||
void setRequiresAuthentication(bool requiresAuthentication) { _requiresAuthentication = requiresAuthentication; }
|
|
||||||
|
|
||||||
const QUuid& getConnectionSecret() const { return _connectionSecret; }
|
const QUuid& getConnectionSecret() const { return _connectionSecret; }
|
||||||
void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; }
|
void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; }
|
||||||
|
|
||||||
const QString& getRegistrationToken() const { return _registrationToken; }
|
const QString& getRegistrationToken() const { return _registrationToken; }
|
||||||
void setRegistrationToken(const QString& registrationToken);
|
void setRegistrationToken(const QString& registrationToken);
|
||||||
|
|
||||||
|
const QUrl& getRootAuthenticationURL() const { return _rootAuthenticationURL; }
|
||||||
|
void setRootAuthenticationURL(const QUrl& rootAuthenticationURL) { _rootAuthenticationURL = rootAuthenticationURL; }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void completedHostnameLookup(const QHostInfo& hostInfo);
|
void completedHostnameLookup(const QHostInfo& hostInfo);
|
||||||
signals:
|
signals:
|
||||||
|
@ -49,9 +51,9 @@ signals:
|
||||||
private:
|
private:
|
||||||
QString _hostname;
|
QString _hostname;
|
||||||
HifiSockAddr _sockAddr;
|
HifiSockAddr _sockAddr;
|
||||||
bool _requiresAuthentication;
|
|
||||||
QUuid _connectionSecret;
|
QUuid _connectionSecret;
|
||||||
QString _registrationToken;
|
QString _registrationToken;
|
||||||
|
QUrl _rootAuthenticationURL;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__DomainInfo__) */
|
#endif /* defined(__hifi__DomainInfo__) */
|
||||||
|
|
|
@ -12,8 +12,10 @@
|
||||||
|
|
||||||
#include <QtCore/QDataStream>
|
#include <QtCore/QDataStream>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
#include <QtNetwork/QHostInfo>
|
#include <QtNetwork/QHostInfo>
|
||||||
|
|
||||||
|
#include "AccountManager.h"
|
||||||
#include "Assignment.h"
|
#include "Assignment.h"
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
@ -197,7 +199,7 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr
|
||||||
}
|
}
|
||||||
case PacketTypeDomainServerAuthRequest: {
|
case PacketTypeDomainServerAuthRequest: {
|
||||||
// the domain-server has asked us to auth via a data-server
|
// the domain-server has asked us to auth via a data-server
|
||||||
|
processDomainServerAuthRequest(packet);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -471,7 +473,7 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
// send a STUN request to figure it out
|
// send a STUN request to figure it out
|
||||||
sendSTUNRequest();
|
sendSTUNRequest();
|
||||||
} else if (!_domainInfo.getIP().isNull()
|
} else if (!_domainInfo.getIP().isNull()
|
||||||
&& (!_domainInfo.requiresAuthentication()
|
&& (_domainInfo.getRootAuthenticationURL().isEmpty()
|
||||||
|| !_sessionUUID.isNull()
|
|| !_sessionUUID.isNull()
|
||||||
|| !_domainInfo.getRegistrationToken().isEmpty()) ) {
|
|| !_domainInfo.getRegistrationToken().isEmpty()) ) {
|
||||||
// construct the DS check in packet
|
// construct the DS check in packet
|
||||||
|
@ -562,6 +564,21 @@ int NodeList::processDomainServerList(const QByteArray& packet) {
|
||||||
return readNodes;
|
return readNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NodeList::processDomainServerAuthRequest(const QByteArray& packet) {
|
||||||
|
QDataStream authPacketStream(packet);
|
||||||
|
authPacketStream.skipRawData(numBytesForPacketHeader(packet));
|
||||||
|
|
||||||
|
// grab the hostname this domain-server wants us to authenticate with
|
||||||
|
QUrl authenticationRootURL;
|
||||||
|
authPacketStream >> authenticationRootURL;
|
||||||
|
|
||||||
|
_domainInfo.setRootAuthenticationURL(authenticationRootURL);
|
||||||
|
|
||||||
|
if (AccountManager::getInstance().hasValidAccessTokenForRootURL(authenticationRootURL)) {
|
||||||
|
// request a domain-server registration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NodeList::sendAssignment(Assignment& assignment) {
|
void NodeList::sendAssignment(Assignment& assignment) {
|
||||||
|
|
||||||
PacketType assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand
|
PacketType assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand
|
||||||
|
|
|
@ -148,6 +148,8 @@ private:
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
void processDomainServerAuthRequest(const QByteArray& packet);
|
||||||
|
|
||||||
NodeHash _nodeHash;
|
NodeHash _nodeHash;
|
||||||
QMutex _nodeHashMutex;
|
QMutex _nodeHashMutex;
|
||||||
QUdpSocket _nodeSocket;
|
QUdpSocket _nodeSocket;
|
||||||
|
|
40
libraries/shared/src/OAuthAccessToken.cpp
Normal file
40
libraries/shared/src/OAuthAccessToken.cpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// OAuthAccessToken.cpp
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2/18/2014.
|
||||||
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "OAuthAccessToken.h"
|
||||||
|
|
||||||
|
OAuthAccessToken::OAuthAccessToken() :
|
||||||
|
token(),
|
||||||
|
refreshToken(),
|
||||||
|
expiryTimestamp(),
|
||||||
|
tokenType()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
OAuthAccessToken::OAuthAccessToken(const OAuthAccessToken& otherToken) {
|
||||||
|
token = otherToken.token;
|
||||||
|
refreshToken = otherToken.refreshToken;
|
||||||
|
expiryTimestamp = otherToken.expiryTimestamp;
|
||||||
|
tokenType = otherToken.tokenType;
|
||||||
|
}
|
||||||
|
|
||||||
|
OAuthAccessToken& OAuthAccessToken::operator=(const OAuthAccessToken& otherToken) {
|
||||||
|
OAuthAccessToken temp(otherToken);
|
||||||
|
swap(temp);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OAuthAccessToken::swap(OAuthAccessToken& otherToken) {
|
||||||
|
using std::swap;
|
||||||
|
|
||||||
|
swap(token, otherToken.token);
|
||||||
|
swap(refreshToken, otherToken.refreshToken);
|
||||||
|
swap(expiryTimestamp, otherToken.expiryTimestamp);
|
||||||
|
swap(tokenType, otherToken.tokenType);
|
||||||
|
}
|
32
libraries/shared/src/OAuthAccessToken.h
Normal file
32
libraries/shared/src/OAuthAccessToken.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// OAuthAccessToken.h
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2/18/2014.
|
||||||
|
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __hifi__OAuthAccessToken__
|
||||||
|
#define __hifi__OAuthAccessToken__
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
|
|
||||||
|
class OAuthAccessToken : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OAuthAccessToken();
|
||||||
|
OAuthAccessToken(const OAuthAccessToken& otherToken);
|
||||||
|
OAuthAccessToken& operator=(const OAuthAccessToken& otherToken);
|
||||||
|
|
||||||
|
bool isExpired() { return expiryTimestamp <= QDateTime::currentMSecsSinceEpoch(); }
|
||||||
|
|
||||||
|
QString token;
|
||||||
|
QString refreshToken;
|
||||||
|
quint64 expiryTimestamp;
|
||||||
|
QString tokenType;
|
||||||
|
private:
|
||||||
|
void swap(OAuthAccessToken& otherToken);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__hifi__OAuthAccessToken__) */
|
Loading…
Reference in a new issue