AirMapSharedState.cc 4.62 KB
Newer Older
1 2
/****************************************************************************
 *
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8 9
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

10
#include "AirMapSharedState.h"
Gus Grubba's avatar
Gus Grubba committed
11
#include "AirMapManager.h"
12

Gus Grubba's avatar
Gus Grubba committed
13
#include "airmap/authenticator.h"
14
#include "qjsonwebtoken.h"
Gus Grubba's avatar
Gus Grubba committed
15 16 17

using namespace airmap;

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
void
AirMapSharedState::setSettings(const Settings& settings)
{
    logout();
    _settings = settings;
}

void
AirMapSharedState::doRequestWithLogin(const Callback& callback)
{
    if (isLoggedIn()) {
        callback(_loginToken);
    } else {
        login();
        _pendingRequests.enqueue(callback);
    }
}

36 37 38 39 40
//-- TODO:
//   For now, only anonymous login collects the (anonymous) pilot ID within login()
//   For autheticated logins, we need to collect it here as opposed to spread all over
//   the place as it is the case now.

41 42 43 44 45 46 47 48
void
AirMapSharedState::login()
{
    if (isLoggedIn() || _isLoginInProgress) {
        return;
    }
    _isLoginInProgress = true;
    if (_settings.userName == "") { //use anonymous login
Gus Grubba's avatar
Gus Grubba committed
49
        qCDebug(AirMapManagerLog) << "Anonymous authentication";
50
        Authenticator::AuthenticateAnonymously::Params params;
Gus Grubba's avatar
Gus Grubba committed
51
        params.id = "Anonymous";
52 53 54 55 56 57
        _client->authenticator().authenticate_anonymously(params,
                [this](const Authenticator::AuthenticateAnonymously::Result& result) {
            if (!_isLoginInProgress) { // was logout() called in the meanwhile?
                return;
            }
            if (result) {
Gus Grubba's avatar
Gus Grubba committed
58
                qCDebug(AirMapManagerLog) << "Successfully authenticated with AirMap: id="<< result.value().id.c_str();
59
                emit authStatus(AirspaceManager::AuthStatus::Anonymous);
60
                _loginToken = QString::fromStdString(result.value().id);
61 62 63 64 65
                QJsonWebToken token = QJsonWebToken::fromTokenAndSecret(_loginToken, QString());
                QJsonDocument doc = token.getPayloadJDoc();
                QJsonObject json = doc.object();
                _pilotID = json.value("sub").toString();
                qCDebug(AirMapManagerLog) << "Anonymous pilot id:" << _pilotID;
66 67 68
                _processPendingRequests();
            } else {
                _pendingRequests.clear();
69
                emit authStatus(AirspaceManager::AuthStatus::Error);
70 71 72 73 74 75 76 77 78 79 80
                QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
                emit error("Failed to authenticate with AirMap",
                        QString::fromStdString(result.error().message()), description);
            }
        });
    } else {
        Authenticator::AuthenticateWithPassword::Params params;
        params.oauth.username = _settings.userName.toStdString();
        params.oauth.password = _settings.password.toStdString();
        params.oauth.client_id = _settings.clientID.toStdString();
        params.oauth.device_id = "QGroundControl";
Gus Grubba's avatar
Gus Grubba committed
81
        qCDebug(AirMapManagerLog) << "User authentication" << _settings.userName;
82 83 84 85 86 87
        _client->authenticator().authenticate_with_password(params,
                [this](const Authenticator::AuthenticateWithPassword::Result& result) {
            if (!_isLoginInProgress) { // was logout() called in the meanwhile?
                return;
            }
            if (result) {
Gus Grubba's avatar
Gus Grubba committed
88
                qCDebug(AirMapManagerLog) << "Successfully authenticated with AirMap: id="<< result.value().id.c_str()<<", access="
89
                        <<result.value().access.c_str();
90
                emit authStatus(AirspaceManager::AuthStatus::Authenticated);
91 92 93 94 95
                _loginToken = QString::fromStdString(result.value().id);
                _processPendingRequests();
            } else {
                _pendingRequests.clear();
                QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
96
                emit authStatus(AirspaceManager::AuthStatus::Error);
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
                emit error("Failed to authenticate with AirMap",
                        QString::fromStdString(result.error().message()), description);
            }
        });
    }
}

void
AirMapSharedState::_processPendingRequests()
{
    while (!_pendingRequests.isEmpty()) {
        _pendingRequests.dequeue()(_loginToken);
    }
}

void
AirMapSharedState::logout()
{
    _isLoginInProgress = false; // cancel if we're currently trying to login
    if (!isLoggedIn()) {
        return;
    }
119 120
    _pilotID.clear();
    _loginToken.clear();
121 122 123 124
    _pendingRequests.clear();
}