/* * This file is part of Remote Support Desktop * https://gitlab.das-netzwerkteam.de/RemoteWebApp/rwa.support.desktopapp * Copyright 2020, 2021 Daniel Teichmann * Copyright 2020, 2021 Mike Gabriel * SPDX-License-Identifier: GPL-2.0-or-later * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "session.h" Session::Session(DBusAPI *dbus_api, RWAHost *host) : QObject() { Q_ASSERT(host != nullptr); Q_ASSERT(dbus_api != nullptr); _dbus_api = dbus_api; _host = host; setPin("-----"); setSessionID("-----"); setURL(tr("Not available yet")); setStatus("unknown"); started = false; } Session::~Session() { qDebug().noquote() << QString("Session #'%0' on host '%1' will be deconstructed.") .arg(getSessionID()) .arg(getHost()->alias()); stop(); disconnect(); } void Session::statusTimerEvent() { qDebug() << "Status timer event triggered"; refresh_status(); } bool Session::isSessionAliveOrRunning() { if (getStatus() == "running" || getStatus() == "active") { return true; } else { return false; } } RWAHost* Session::getHost() { return _host; } QString Session::getStatus() { return _status; } QString Session::getURL() { return _url; } QString Session::getSessionID() { return _session_id; } QString Session::getPin() { return _pin; } void Session::setURL(QString url) { _url = url; emit urlChanged(url); } void Session::setSessionID(QString session_id) { _session_id = session_id; emit sessionIDChanged(session_id); } void Session::setPin(QString pin) { _pin = pin; emit pinChanged(pin); } void Session::setHost(RWAHost *host) { _host = host; emit hostChanged(host); } void Session::setStatus(QString status) { _status = status; emit statusChanged(status); } void Session::start() { _dbus_api->start_request(_host); } void Session::start_response(QJsonDocument *doc) { // Q_ASSERT lets the program crash immediatly after method call // when the session service is not started. // Don't use Q_ASSERT(doc != nullptr); instead use: if (doc == nullptr) { emit startFailed(tr("Can't connect to underlying session service! " "Is the session service started?")); return; } // Get the QJsonObject QJsonObject jObject = doc->object(); QVariantMap mainMap = jObject.toVariantMap(); // Status of request QString status = mainMap["status"].toString(); if (status != "success") { QString type = mainMap["type"].toString(); QString error_message = tr("An error occured while creating a new session!"); if (type == "multiple") { // TODO: Ask to stop other session via a message dialog. error_message = tr("The session service is configured " "to not support multiple sessions " "and there is already a session running."); } else if (type == "connection") { error_message = tr("Couldn't connect to host '%0'.") .arg(getHost()->alias()); } else if (type == "host_not_found") { error_message = tr("The RWA host '%0' couldn't be found.") .arg(getHost()->alias()); } else if (type == "permission_denid") { error_message = tr("The RWA host '%0' doesn't grant access.") .arg(getHost()->alias()); } else if (type == "unsupported_server") { error_message = tr("The RWA host '%0' is not supported.") .arg(getHost()->alias()); } setStatus("start_session_error"); qCritical().noquote() << error_message; emit startFailed(error_message); return; } bool ok; // URL of remote web app frontend QString url = mainMap["url"].toString(); this->setURL(url); // PIN long long pin = mainMap["pin"].toLongLong(&ok); // Sanity Check if(ok == false){ QString error_message = "Unable to parse into longo long out of dbus answer!"; qCritical().noquote() << error_message; emit startFailed(error_message); return; } this->setPin(QString::number(pin)); // session_id = remote support id from the rwa-server long long session_id = mainMap["session_id"].toLongLong(); // Sanity Check if(ok == false){ QString error_message = "Unable to parse into long long out of dbus answer!"; qCritical().noquote() << error_message; emit startFailed(error_message); return; } this->setSessionID(QString::number(session_id)); qDebug() << "Got session_id:" << session_id << "\nGot url:" << url << "\nGot pin:" << pin; emit pinChanged(QString::number(pin)); emit urlChanged(url); emit sessionIDChanged(QString::number(session_id)); started = true; // Ask status every 1000 millisecond QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&Session::statusTimerEvent)); timer->start(1000); qDebug() << "Successfully started a session."; this->setStatus("start_session_success"); emit startSucceeded(); } void Session::stop() { if (started) _dbus_api->stop_request(getHost(), getSessionID()); } void Session::stop_response(QJsonDocument *doc) { // Q_ASSERT lets the program crash immediatly after method call // when the session service is not started. // Don't use Q_ASSERT(doc != nullptr); instead use: if (doc == nullptr) { emit stopFailed(tr("Can't connect to underlying session service! " "Is the session service started?")); return; } QJsonObject jObject = doc->object(); QVariantMap mainMap = jObject.toVariantMap(); QString new_status = mainMap["status"].toString(); qDebug() << "stop_response() retrieved json. Status now:" << new_status; started = false; this->setStatus(new_status); emit stopSucceeded(); } void Session::status() { _dbus_api->status_request(getHost(), this->getSessionID()); } void Session::refresh_status() { _dbus_api->refresh_status_request(getHost(), this->getSessionID()); } void Session::status_response(QJsonDocument *doc) { // Q_ASSERT lets the program crash immediatly after method call, // when the session service is not started. // Don't use Q_ASSERT(doc != nullptr); instead use: if (doc == nullptr) { if (!_emitted_status_error_already) { emit statusFailed(tr("Can't connect to underlying session service! " "Is the session service started?")); _emitted_status_error_already = true; } return; } _emitted_status_error_already = false; QJsonObject jObject = doc->object(); QVariantMap mainMap = jObject.toVariantMap(); QString new_status = mainMap["status"].toString(); qDebug() << "status_response() retrieved json. Status:" << new_status; setStatus(new_status); emit statusSucceeded(); }