Update core documentation and fix inline warnings

This commit is contained in:
Simon Stürz 2018-07-25 18:39:41 +02:00 committed by Michael Zanetti
parent 50bd22cedd
commit dcd410457d
26 changed files with 212 additions and 68 deletions

View File

@ -28,7 +28,7 @@
\endlist \endlist
\section1 CreateMethod \b "User" - SetupMethod \b "JustAdd - synchronous" \section2 CreateMethod \b "User" - SetupMethod \b "JustAdd - synchronous"
This is the simplest setup what a device can have. This is the simplest setup what a device can have.
@ -50,7 +50,7 @@
\endlist \endlist
\endlist \endlist
\section1 CreateMethod \b "User" - SetupMethod \b "JustAdd" - asynchronous \section2 CreateMethod \b "User" - SetupMethod \b "JustAdd" - asynchronous
\image setup-async-resized.png \image setup-async-resized.png
@ -64,7 +64,7 @@
\endlist \endlist
\endlist \endlist
\section1 CreateMethod \b "auto" - SetupMethod \b "justAdd" \section2 CreateMethod \b "auto" - SetupMethod \b "justAdd"
\image setup-auto-resized.png \image setup-auto-resized.png
@ -83,7 +83,7 @@
\endlist \endlist
\section1 CreateMethod \b "Discovery" - SetupMethod \b "JustAdd" \section2 CreateMethod \b "Discovery" - SetupMethod \b "JustAdd"
\image setup-discovery-resized.png \image setup-discovery-resized.png
@ -102,7 +102,7 @@
\endlist \endlist
\endlist \endlist
\section1 CreateMethod \b "Discovery" - SetupMethod \b "PushButton" \section2 CreateMethod \b "Discovery" - SetupMethod \b "PushButton"
\image setup-discovery-pairing-resized.png \image setup-discovery-pairing-resized.png
@ -127,7 +127,7 @@
\endlist \endlist
\endlist \endlist
\section1 CreateMethod \b "Discovery" - SetupMethod \b "EnterPin" \section2 CreateMethod \b "Discovery" - SetupMethod \b "EnterPin"
\image setup-discovery-pairing-resized.png \image setup-discovery-pairing-resized.png
@ -153,7 +153,7 @@
\endlist \endlist
\section1 CreateMethod \b "Discovery" - SetupMethod \b "DisplayPin" \section2 CreateMethod \b "Discovery" - SetupMethod \b "DisplayPin"
\image setup-discovery-display-pin-resized.png \image setup-discovery-display-pin-resized.png

View File

@ -11,11 +11,12 @@
can do with the \l{Device}. can do with the \l{Device}.
\section1 Devices \section1 Devices
A device in nymea can represent a real device, a gateway or even a service like weather. When you want to represent you own device / service in nymea, you should try to abstract that device and think in terms like: A device in nymea can represent a real device, a gateway or even a service like weather. When you want to represent you own device / service in nymea,
you should try to abstract that device and think in terms like:
\list \list
\li \l{ParamType}{ParamTypes} \unicode{0x2192} A \l{Device} can have \l{Param}{Params}, which will be needed to set up the device \li \l{ParamType}{ParamTypes} \unicode{0x2192} A \l{Device} can have \l{Param}{Params}, which will be needed to set up the device
(like IP addresses or device configurations) and give information for the user like name or location. The \l{ParamType} represents (like IP addresses or device identification) and give information needed for setup and load a device. The \l{ParamType} represents
the description of an actual \l{Param}. the description of an actual \l{Param}.
\li \l{StateType}{StateTypes} \unicode{0x2192} A \l{Device} can have \l{State}{States}, which basically represent a value of a \l{Device} \li \l{StateType}{StateTypes} \unicode{0x2192} A \l{Device} can have \l{State}{States}, which basically represent a value of a \l{Device}
like \e {current temperature} or \e ON/OFF. The \l{StateType} represents the description of an actual \l{State}. like \e {current temperature} or \e ON/OFF. The \l{StateType} represents the description of an actual \l{State}.

View File

@ -12,11 +12,11 @@
To make nymead load the plugin from the plugins build directory, run nymead with an environment variable exported To make nymead load the plugin from the plugins build directory, run nymead with an environment variable exported
\code \code
$ NYMEA_PLUGINS_DIR=/path/to/plugin/ nymead $ NYMEA_PLUGINS_PATH=/path/to/plugin/ nymead -n
\endcode \endcode
In order to easier debug things, it is advised to enable debug output for the device manager and your plugin. E.g. In order to easier debug things, it is advised to enable debug output for the device manager and your plugin. E.g.
\code \code
$ NYMEA_PLUGINS_DIR=/path/to/plugin nymead -d DeviceManager,YourPlugin $ NYMEA_PLUGINS_PATH=/path/to/plugin nymead -n -d DeviceManager -d YourPlugin
\endcode \endcode
*/ */

View File

@ -132,7 +132,7 @@
namespace nymeaserver { namespace nymeaserver {
/*! Constructs the log engine with the given parameters. /*! Constructs the log engine with the given parameters.
\a The Qt Database backend to be used. Depending on the installed Qt modules this can be any of QDB2 QIBASE QMYSQL QOCI QODBC QPSQL QSQLITE QSQLITE2 QTDS. The Qt Database backend to be used. Depending on the installed Qt modules this can be any of QDB2 QIBASE QMYSQL QOCI QODBC QPSQL QSQLITE QSQLITE2 QTDS.
\a dbName is the name of the database. In case of SQLITE this should contain a file path. The Driver will create the file if required. In case of using a \a dbName is the name of the database. In case of SQLITE this should contain a file path. The Driver will create the file if required. In case of using a
database server like MYSQL, the database must exist on the host given by \a hostname and be accessible with the given \a username and \a password. database server like MYSQL, the database must exist on the host given by \a hostname and be accessible with the given \a username and \a password.
*/ */

View File

@ -88,6 +88,15 @@
This signal is emitted when the configuration of \a rule changed. This signal is emitted when the configuration of \a rule changed.
*/ */
/*! \fn void nymeaserver::NymeaCore::initialized();
This signal is emitted when the core is initialized.
*/
/*! \fn void nymeaserver::NymeaCore::pluginConfigChanged(const PluginId &id, const ParamList &config);
This signal is emitted when the plugin \a config of the plugin with the given \a id changed.
*/
/*! \fn void ruleActiveChanged(const Rule &rule); /*! \fn void ruleActiveChanged(const Rule &rule);
This signal is emitted when a \a rule changed the active state. This signal is emitted when a \a rule changed the active state.
A \l{Rule} is active, when all \l{State}{States} match with the \l{StateDescriptor} conditions. A \l{Rule} is active, when all \l{State}{States} match with the \l{StateDescriptor} conditions.
@ -111,7 +120,7 @@
namespace nymeaserver { namespace nymeaserver {
NymeaCore* NymeaCore::s_instance = 0; NymeaCore* NymeaCore::s_instance = nullptr;
/*! Returns a pointer to the single \l{NymeaCore} instance. */ /*! Returns a pointer to the single \l{NymeaCore} instance. */
NymeaCore *NymeaCore::instance() NymeaCore *NymeaCore::instance()
@ -154,7 +163,7 @@ void NymeaCore::destroy()
delete s_instance; delete s_instance;
} }
s_instance = 0; s_instance = nullptr;
} }
/*! Removes a configured \l{Device} with the given \a deviceId and \a removePolicyList. */ /*! Removes a configured \l{Device} with the given \a deviceId and \a removePolicyList. */
@ -471,16 +480,19 @@ NetworkManager *NymeaCore::networkManager() const
return m_networkManager; return m_networkManager;
} }
/*! Returns a pointer to the \l{UserManager} instance owned by NymeaCore. */
UserManager *NymeaCore::userManager() const UserManager *NymeaCore::userManager() const
{ {
return m_userManager; return m_userManager;
} }
/*! Returns a pointer to the CloudManager instance owned by NymeaCore. */
CloudManager *NymeaCore::cloudManager() const CloudManager *NymeaCore::cloudManager() const
{ {
return m_cloudManager; return m_cloudManager;
} }
/*! Returns a pointer to the \l{DebugServerHandler} instance owned by NymeaCore. */
DebugServerHandler *NymeaCore::debugServerHandler() const DebugServerHandler *NymeaCore::debugServerHandler() const
{ {
return m_debugServerHandler; return m_debugServerHandler;

View File

@ -111,7 +111,7 @@ signals:
void ruleConfigurationChanged(const Rule &rule); void ruleConfigurationChanged(const Rule &rule);
private: private:
explicit NymeaCore(QObject *parent = 0); explicit NymeaCore(QObject *parent = nullptr);
static NymeaCore *s_instance; static NymeaCore *s_instance;
NymeaConfiguration *m_configuration; NymeaConfiguration *m_configuration;

View File

@ -88,11 +88,13 @@ bool Rule::active() const
return m_active; return m_active;
} }
/*! Returns true if the rule is active regarding the StateEvaluator evaluation. */
bool Rule::statesActive() const bool Rule::statesActive() const
{ {
return m_statesActive; return m_statesActive;
} }
/*! Returns true if the rule is active regarding the TimeDescriptor evaluation. */
bool Rule::timeActive() const bool Rule::timeActive() const
{ {
if (m_timeDescriptor.calendarItems().isEmpty()) if (m_timeDescriptor.calendarItems().isEmpty())

View File

@ -87,6 +87,8 @@
the \l{Action}{Actions} without the \l{Event} value. the \l{Action}{Actions} without the \l{Event} value.
\value RuleErrorNoExitActions \value RuleErrorNoExitActions
This rule does not have any ExitActions which means they cannot be executed. This rule does not have any ExitActions which means they cannot be executed.
\value RuleErrorInterfaceNotFound
There is no interface for the given string.
*/ */
/*! \enum nymeaserver::RuleEngine::RemovePolicy /*! \enum nymeaserver::RuleEngine::RemovePolicy

View File

@ -44,7 +44,7 @@
namespace nymeaserver { namespace nymeaserver {
/*! Constructs a \l{ServerManager} with the given \a parent. */ /*! Constructs a \l{ServerManager} with the given \a configuration and \a parent. */
ServerManager::ServerManager(NymeaConfiguration *configuration, QObject *parent) : ServerManager::ServerManager(NymeaConfiguration *configuration, QObject *parent) :
QObject(parent), QObject(parent),
m_sslConfiguration(QSslConfiguration()) m_sslConfiguration(QSslConfiguration())
@ -141,11 +141,13 @@ RestServer *ServerManager::restServer() const
return m_restServer; return m_restServer;
} }
/*! Returns the pointer to the created \l{BluetoothServer} in this \l{ServerManager}. */
BluetoothServer *ServerManager::bluetoothServer() const BluetoothServer *ServerManager::bluetoothServer() const
{ {
return m_bluetoothServer; return m_bluetoothServer;
} }
/*! Returns the pointer to the created MockTcpServer in this \l{ServerManager}. */
MockTcpServer *ServerManager::mockTcpServer() const MockTcpServer *ServerManager::mockTcpServer() const
{ {
return m_mockTcpServer; return m_mockTcpServer;
@ -259,6 +261,7 @@ bool ServerManager::loadCertificate(const QString &certificateKeyFileName, const
return true; return true;
} }
/*! Set the server name for all servers to the given \a serverName. */
void ServerManager::setServerName(const QString &serverName) void ServerManager::setServerName(const QString &serverName)
{ {
qCDebug(dcConnection()) << "Server name changed" << serverName; qCDebug(dcConnection()) << "Server name changed" << serverName;

View File

@ -194,6 +194,7 @@ void StateEvaluator::removeDevice(const DeviceId &deviceId)
} }
} }
/*! Returns a list of \l{DeviceId}{DeviceIds} of this StateEvaluator. */
QList<DeviceId> StateEvaluator::containedDevices() const QList<DeviceId> StateEvaluator::containedDevices() const
{ {
QList<DeviceId> ret; QList<DeviceId> ret;

View File

@ -19,6 +19,37 @@
* * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class nymeaserver::SslServer
\brief This class represents the SSL server for nymead.
\ingroup server
\inmodule core
\inherits TcpServer
The SSL server allows clients to connect to the JSON-RPC API over an encrypted SSL/TLS connection.
\sa WebSocketServer, TransportInterface, TcpServer
*/
/*! \fn nymeaserver::SslServer::SslServer(bool sslEnabled, const QSslConfiguration &config, QObject *parent = nullptr)
Constructs a \l{SslServer} with the given \a sslEnabled, \a config and \a parent.
*/
/*! \fn void nymeaserver::SslServer::clientConnected(QSslSocket *socket);
This signal is emitted when a new SSL \a socket connected.
*/
/*! \fn void nymeaserver::SslServer::clientDisconnected(QSslSocket *socket);
This signal is emitted when a \a socket disconnected.
*/
/*! \fn void nymeaserver::SslServer::dataAvailable(QSslSocket *socket, const QByteArray &data);
This signal is emitted when \a data from \a socket is available.
*/
/*! /*!
\class nymeaserver::TcpServer \class nymeaserver::TcpServer
\brief This class represents the tcp server for nymead. \brief This class represents the tcp server for nymead.
@ -40,13 +71,13 @@
namespace nymeaserver { namespace nymeaserver {
/*! Constructs a \l{TcpServer} with the given \a host, \a port and \a parent. /*! Constructs a \l{TcpServer} with the given \a configuration, \a sslConfiguration and \a parent.
* *
* \sa ServerManager * \sa ServerManager
*/ */
TcpServer::TcpServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent) : TcpServer::TcpServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent) :
TransportInterface(configuration, parent), TransportInterface(configuration, parent),
m_server(NULL), m_server(nullptr),
m_sslConfig(sslConfiguration) m_sslConfig(sslConfiguration)
{ {
m_avahiService = new QtAvahiService(this); m_avahiService = new QtAvahiService(this);
@ -60,6 +91,7 @@ TcpServer::~TcpServer()
stopServer(); stopServer();
} }
/*! Returns the URL of this server. */
QUrl TcpServer::serverUrl() const QUrl TcpServer::serverUrl() const
{ {
return QUrl(QString("%1://%2:%3").arg((configuration().sslEnabled ? "nymeas" : "nymea")).arg(configuration().address.toString()).arg(configuration().port)); return QUrl(QString("%1://%2:%3").arg((configuration().sslEnabled ? "nymeas" : "nymea")).arg(configuration().address.toString()).arg(configuration().port));
@ -76,7 +108,7 @@ void TcpServer::sendData(const QList<QUuid> &clients, const QByteArray &data)
/*! Sending \a data to the client with the given \a clientId.*/ /*! Sending \a data to the client with the given \a clientId.*/
void TcpServer::sendData(const QUuid &clientId, const QByteArray &data) void TcpServer::sendData(const QUuid &clientId, const QByteArray &data)
{ {
QTcpSocket *client = 0; QTcpSocket *client = nullptr;
client = m_clientList.value(clientId); client = m_clientList.value(clientId);
if (client) { if (client) {
client->write(data + '\n'); client->write(data + '\n');
@ -138,13 +170,13 @@ void TcpServer::resetAvahiService()
txt.insert("uuid", NymeaCore::instance()->configuration()->serverUuid().toString()); txt.insert("uuid", NymeaCore::instance()->configuration()->serverUuid().toString());
txt.insert("name", NymeaCore::instance()->configuration()->serverName()); txt.insert("name", NymeaCore::instance()->configuration()->serverName());
txt.insert("sslEnabled", configuration().sslEnabled ? "true" : "false"); txt.insert("sslEnabled", configuration().sslEnabled ? "true" : "false");
if (!m_avahiService->registerService(QString("nymea-tcp-%1").arg(configuration().id), configuration().address, configuration().port, "_jsonrpc._tcp", txt)) { if (!m_avahiService->registerService(QString("nymea-tcp-%1").arg(configuration().id), configuration().address, static_cast<quint16>(configuration().port), "_jsonrpc._tcp", txt)) {
qCWarning(dcTcpServer()) << "Could not register avahi service for" << configuration(); qCWarning(dcTcpServer()) << "Could not register avahi service for" << configuration();
} }
} }
/*! Returns true if this \l{TcpServer} could be reconfigured with the given \a address and \a port. */ /*! Returns true if this \l{TcpServer} could be reconfigured with the given \a config. */
void TcpServer::reconfigureServer(const ServerConfiguration &config) void TcpServer::reconfigureServer(const ServerConfiguration &config)
{ {
if (configuration().address == config.address && if (configuration().address == config.address &&
@ -159,6 +191,7 @@ void TcpServer::reconfigureServer(const ServerConfiguration &config)
startServer(); startServer();
} }
/*! Sets the name of this server to the given \a serverName. */
void TcpServer::setServerName(const QString &serverName) void TcpServer::setServerName(const QString &serverName)
{ {
m_serverName = serverName; m_serverName = serverName;
@ -172,10 +205,10 @@ void TcpServer::setServerName(const QString &serverName)
bool TcpServer::startServer() bool TcpServer::startServer()
{ {
m_server = new SslServer(configuration().sslEnabled, m_sslConfig); m_server = new SslServer(configuration().sslEnabled, m_sslConfig);
if(!m_server->listen(configuration().address, configuration().port)) { if(!m_server->listen(configuration().address, static_cast<quint16>(configuration().port))) {
qCWarning(dcConnection) << "Tcp server error: can not listen on" << configuration().address.toString() << configuration().port; qCWarning(dcConnection) << "Tcp server error: can not listen on" << configuration().address.toString() << configuration().port;
delete m_server; delete m_server;
m_server = NULL; m_server = nullptr;
return false; return false;
} }
@ -203,10 +236,11 @@ bool TcpServer::stopServer()
m_server->close(); m_server->close();
m_server->deleteLater(); m_server->deleteLater();
m_server = NULL; m_server = nullptr;
return true; return true;
} }
/*! This method will be called if a new \a socketDescriptor is about to connect to this SslSocket. */
void SslServer::incomingConnection(qintptr socketDescriptor) void SslServer::incomingConnection(qintptr socketDescriptor)
{ {
QSslSocket *sslSocket = new QSslSocket(this); QSslSocket *sslSocket = new QSslSocket(this);

View File

@ -72,8 +72,8 @@ class TcpServer : public TransportInterface
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TcpServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent = 0); explicit TcpServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent = nullptr);
~TcpServer(); ~TcpServer() override;
QUrl serverUrl() const; QUrl serverUrl() const;

View File

@ -82,7 +82,7 @@ bool TimeDescriptor::isEmpty() const
/*! Returns true if this \l{TimeDescriptor} is valid for the given \a dateTime. A \l{TimeDescriptor} is /*! Returns true if this \l{TimeDescriptor} is valid for the given \a dateTime. A \l{TimeDescriptor} is
valid if the \l{TimeEventItem}{TimeEventItems} or \l{CalendarItem}{CalendarItems} match valid if the \l{TimeEventItem}{TimeEventItems} or \l{CalendarItem}{CalendarItems} match
the given \a dateTime. the given \a dateTime since the \a lastEvaluationTime.
*/ */
bool TimeDescriptor::evaluate(const QDateTime &lastEvaluationTime, const QDateTime &dateTime) const bool TimeDescriptor::evaluate(const QDateTime &lastEvaluationTime, const QDateTime &dateTime) const
{ {

View File

@ -91,7 +91,7 @@ bool TimeEventItem::isValid() const
return (!m_dateTime.isNull() != !m_time.isNull()); return (!m_dateTime.isNull() != !m_time.isNull());
} }
/*! Returns true, if the given \a dateTime matches this \l{TimeEventItem}. */ /*! Returns true, if the given \a dateTime matches this \l{TimeEventItem} since the last \a lastEvaluationTime. */
bool TimeEventItem::evaluate(const QDateTime &lastEvaluationTime, const QDateTime &dateTime) const bool TimeEventItem::evaluate(const QDateTime &lastEvaluationTime, const QDateTime &dateTime) const
{ {
// Check time matches // Check time matches

View File

@ -107,6 +107,10 @@ QList<QByteArray> TimeManager::availableTimeZones() const
return QTimeZone::availableTimeZoneIds(); return QTimeZone::availableTimeZoneIds();
} }
/*! Stop the time.
*
* \note This method should only be used in tests.
*/
void TimeManager::stopTimer() void TimeManager::stopTimer()
{ {
qCWarning(dcTimeManager()) << "TimeManager timer stopped. You should only see this in tests."; qCWarning(dcTimeManager()) << "TimeManager timer stopped. You should only see this in tests.";
@ -114,6 +118,10 @@ void TimeManager::stopTimer()
m_nymeaTimer->stop(); m_nymeaTimer->stop();
} }
/*! Set the current time of this TimeManager to the given \a dateTime.
*
* \note This method should only be used in tests.
*/
void TimeManager::setTime(const QDateTime &dateTime) void TimeManager::setTime(const QDateTime &dateTime)
{ {
qCWarning(dcTimeManager()) << "TimeManager time changed" << dateTime.toString("dd.MM.yyyy hh:mm:ss") << "You should only see this in tests."; qCWarning(dcTimeManager()) << "TimeManager time changed" << dateTime.toString("dd.MM.yyyy hh:mm:ss") << "You should only see this in tests.";

View File

@ -18,10 +18,23 @@
* * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class nymeaserver::TokenInfo
\brief This class holds information about an authentication token.
\ingroup user
\inmodule core
The TokenInfo class holds information about a token used for authentication in the \l{nymeaserver::UserManager}{UserManager}.
\sa TokenInfo, PushButtonDBusService
*/
#include "tokeninfo.h" #include "tokeninfo.h"
namespace nymeaserver { namespace nymeaserver {
/*! Constructs a new token info with the given \a id, \a username, \a creationTime and \a deviceName. */
TokenInfo::TokenInfo(const QUuid &id, const QString &username, const QDateTime &creationTime, const QString &deviceName): TokenInfo::TokenInfo(const QUuid &id, const QString &username, const QDateTime &creationTime, const QString &deviceName):
m_id(id), m_id(id),
m_username(username), m_username(username),
@ -31,21 +44,25 @@ TokenInfo::TokenInfo(const QUuid &id, const QString &username, const QDateTime &
} }
/*! Returns the id of this TokenInfo. */
QUuid TokenInfo::id() const QUuid TokenInfo::id() const
{ {
return m_id; return m_id;
} }
/*! Returns the userename of this TokenInfo. */
QString TokenInfo::username() const QString TokenInfo::username() const
{ {
return m_username; return m_username;
} }
/*! Returns the creation time of this TokenInfo. */
QDateTime TokenInfo::creationTime() const QDateTime TokenInfo::creationTime() const
{ {
return m_creationTime; return m_creationTime;
} }
/*! Returns the device name of this TokenInfo. */
QString TokenInfo::deviceName() const QString TokenInfo::deviceName() const
{ {
return m_deviceName; return m_deviceName;

View File

@ -54,20 +54,18 @@
\sa WebSocketServer::stopServer(), TcpServer::stopServer() \sa WebSocketServer::stopServer(), TcpServer::stopServer()
*/ */
/*! \fn void nymeaserver::TransportInterface::sendData(const QUuid &clientId, const QVariantMap &data); /*! \fn void nymeaserver::TransportInterface::sendData(const QUuid &clientId, const QByteArray &data);
Pure virtual method for sending \a data to the client with the id \a clientId over the corresponding \l{TransportInterface}. Pure virtual method for sending \a data to the client with the id \a clientId over the corresponding \l{TransportInterface}.
*/ */
/*! \fn void nymeaserver::TransportInterface::sendData(const QList<QUuid> &clients, const QVariantMap &data); /*! \fn void nymeaserver::TransportInterface::sendData(const QList<QUuid> &clients, const QByteArray &data);
Pure virtual method for sending \a data to \a clients over the corresponding \l{TransportInterface}. Pure virtual method for sending \a data to \a clients over the corresponding \l{TransportInterface}.
*/ */
/*! \fn void nymeaserver::TransportInterface::dataAvailable(const QUuid &clientId, const QString &targetNamespace, const QString &method, const QVariantMap &message); /*! \fn void nymeaserver::TransportInterface::dataAvailable(const QUuid &clientId, const QByteArray &data);
This signal is emitted when valid data from the client with the given \a clientId are available. This signal is emitted when valid \a data from the client with the given \a clientId are available.
Data are valid if the corresponding \l{TransportInterface} has parsed successfully the given
\a targetNamespace, \a method and \a message.
\sa WebSocketServer, TcpServer \sa WebSocketServer, TcpServer, BluetoothServer
*/ */
#include "transportinterface.h" #include "transportinterface.h"
@ -77,13 +75,14 @@
namespace nymeaserver { namespace nymeaserver {
/*! Constructs a \l{TransportInterface} with the given \a parent. */ /*! Constructs a \l{TransportInterface} with the given \a config and \a parent. */
TransportInterface::TransportInterface(const ServerConfiguration &config, QObject *parent) : TransportInterface::TransportInterface(const ServerConfiguration &config, QObject *parent) :
QObject(parent), QObject(parent),
m_config(config) m_config(config)
{ {
} }
/*! Set the ServerConfiguration of this TransportInterface to the given \a config. */
void TransportInterface::setConfiguration(const ServerConfiguration &config) void TransportInterface::setConfiguration(const ServerConfiguration &config)
{ {
m_config = config; m_config = config;
@ -95,6 +94,7 @@ ServerConfiguration TransportInterface::configuration() const
return m_config; return m_config;
} }
/*! Set the name of this TransportInterface to the given \a serverName. */
void TransportInterface::setServerName(const QString &serverName) void TransportInterface::setServerName(const QString &serverName)
{ {
m_serverName = serverName; m_serverName = serverName;

View File

@ -34,7 +34,7 @@ class TransportInterface : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TransportInterface(const ServerConfiguration &config, QObject *parent = 0); explicit TransportInterface(const ServerConfiguration &config, QObject *parent = nullptr);
virtual ~TransportInterface() = 0; virtual ~TransportInterface() = 0;
virtual void sendData(const QUuid &clientId, const QByteArray &data) = 0; virtual void sendData(const QUuid &clientId, const QByteArray &data) = 0;

View File

@ -18,6 +18,46 @@
* * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class nymeaserver::UserManager
\brief This class represents the manager for the users in nymead.
\ingroup user
\inmodule core
The user manager is responsible for managing the user database, tokens and authentication. The user manager
creates a user database where all relevant information will be stored.
\sa TokenInfo, PushButtonDBusService
*/
/*! \enum nymeaserver::UserManager::UserError
This enum represents the possible errors the \l{UserManager} can have.
\value UserErrorNoError
No error occured. Everything is ok.4
\value UserErrorBackendError
Something went wrong in the manager. This is probably caused by a database error.
\value UserErrorInvalidUserId
The given user name is not valid.
\value UserErrorDuplicateUserId
The given user name already exits. Please use a different user name.
\value UserErrorBadPassword
The given password is to weak. Please use a stronger password.
\value UserErrorTokenNotFound
The given token is unknown to the UserManager.
\value UserErrorPermissionDenied
The permission is denied. Either invalid username, password or token.
*/
/*! \fn void nymeaserver::UserManager::pushButtonAuthFinished(int transactionId, bool success, const QByteArray &token);
This signal is emitted when the push authentication for the given \a transactionId is finished.
If \a success is true, the resulting \a token contains a non empty string.
\sa requestPushButtonAuth
*/
#include "usermanager.h" #include "usermanager.h"
#include "nymeasettings.h" #include "nymeasettings.h"
#include "loggingcategories.h" #include "loggingcategories.h"
@ -35,7 +75,7 @@
namespace nymeaserver { namespace nymeaserver {
/** Constructs a new UserManager with the given \a dbName and \a parent. */ /*! Constructs a new UserManager with the given \a dbName and \a parent. */
UserManager::UserManager(const QString &dbName, QObject *parent): UserManager::UserManager(const QString &dbName, QObject *parent):
QObject(parent) QObject(parent)
{ {
@ -64,7 +104,7 @@ UserManager::UserManager(const QString &dbName, QObject *parent):
m_pushButtonTransaction = qMakePair<int, QString>(-1, QString()); m_pushButtonTransaction = qMakePair<int, QString>(-1, QString());
} }
/** Will return true if the database is working fine but doesn't have any information on users whatsoever. /*! Will return true if the database is working fine but doesn't have any information on users whatsoever.
* That is, neither a user nor an anonimous token. * That is, neither a user nor an anonimous token.
* This may be used to determine whether a first-time setup is required. * This may be used to determine whether a first-time setup is required.
*/ */
@ -81,6 +121,7 @@ bool UserManager::initRequired() const
return users().isEmpty() && !result.first(); return users().isEmpty() && !result.first();
} }
/*! Returns the list of user names for this UserManager. */
QStringList UserManager::users() const QStringList UserManager::users() const
{ {
QString userQuery("SELECT username FROM users;"); QString userQuery("SELECT username FROM users;");
@ -92,6 +133,7 @@ QStringList UserManager::users() const
return ret; return ret;
} }
/*! Creates a new user with the given \a username and \a password. Returns the \l UserError to inform about the result. */
UserManager::UserError UserManager::createUser(const QString &username, const QString &password) UserManager::UserError UserManager::createUser(const QString &username, const QString &password)
{ {
if (!validateUsername(username)) { if (!validateUsername(username)) {
@ -126,7 +168,9 @@ UserManager::UserError UserManager::createUser(const QString &username, const QS
return UserErrorNoError; return UserErrorNoError;
} }
/** Remove the given user and all of its tokens. If the username is empty, all anonymous tokens (e.g. issued by pushbutton auth) will be cleared. */ /*! Remove the user with the given \a username and all of its tokens. If the \a username is empty, all anonymous
tokens (e.g. issued by pushbutton auth) will be cleared.
*/
UserManager::UserError UserManager::removeUser(const QString &username) UserManager::UserError UserManager::removeUser(const QString &username)
{ {
if (!username.isEmpty()) { if (!username.isEmpty()) {
@ -146,11 +190,15 @@ UserManager::UserError UserManager::removeUser(const QString &username)
return UserErrorNoError; return UserErrorNoError;
} }
/*! Returns true if the push button authentication is available for this system. */
bool UserManager::pushButtonAuthAvailable() const bool UserManager::pushButtonAuthAvailable() const
{ {
return m_pushButtonDBusService->agentAvailable(); return m_pushButtonDBusService->agentAvailable();
} }
/*! Authenticated the given \a username with the given \a password for the \a deviceName. If the authentication was
successfull, the token will be returned, otherwise the return value will be an empty byte array.
*/
QByteArray UserManager::authenticate(const QString &username, const QString &password, const QString &deviceName) QByteArray UserManager::authenticate(const QString &username, const QString &password, const QString &deviceName)
{ {
if (!validateUsername(username)) { if (!validateUsername(username)) {
@ -188,6 +236,7 @@ QByteArray UserManager::authenticate(const QString &username, const QString &pas
return token; return token;
} }
/*! Start the push button authentication for the device with the given \a deviceName. Returns the transaction id as refference to the request. */
int UserManager::requestPushButtonAuth(const QString &deviceName) int UserManager::requestPushButtonAuth(const QString &deviceName)
{ {
if (m_pushButtonTransaction.first != -1) { if (m_pushButtonTransaction.first != -1) {
@ -201,6 +250,10 @@ int UserManager::requestPushButtonAuth(const QString &deviceName)
return transactionId; return transactionId;
} }
/*! Cancel the push button authentication with the given \a transactionId.
\sa requestPushButtonAuth
*/
void UserManager::cancelPushButtonAuth(int transactionId) void UserManager::cancelPushButtonAuth(int transactionId)
{ {
if (m_pushButtonTransaction.first == -1) { if (m_pushButtonTransaction.first == -1) {
@ -217,6 +270,7 @@ void UserManager::cancelPushButtonAuth(int transactionId)
} }
/*! Returns the username for the given \a token. If the token is invalid, an empty string will be returned. */
QString UserManager::userForToken(const QByteArray &token) const QString UserManager::userForToken(const QByteArray &token) const
{ {
if (!validateToken(token)) { if (!validateToken(token)) {
@ -238,6 +292,10 @@ QString UserManager::userForToken(const QByteArray &token) const
return result.value("username").toString(); return result.value("username").toString();
} }
/*! Returns a list of tokens for the given \a username.
\sa TokenInfo
*/
QList<TokenInfo> UserManager::tokens(const QString &username) const QList<TokenInfo> UserManager::tokens(const QString &username) const
{ {
QList<TokenInfo> ret; QList<TokenInfo> ret;
@ -260,6 +318,7 @@ QList<TokenInfo> UserManager::tokens(const QString &username) const
return ret; return ret;
} }
/*! Removes the token with the given \a tokenId. Returns \l{UserError} to inform about the result. */
UserManager::UserError UserManager::removeToken(const QUuid &tokenId) UserManager::UserError UserManager::removeToken(const QUuid &tokenId)
{ {
QString removeTokenQuery = QString("DELETE FROM tokens WHERE id = \"%1\";") QString removeTokenQuery = QString("DELETE FROM tokens WHERE id = \"%1\";")
@ -278,6 +337,7 @@ UserManager::UserError UserManager::removeToken(const QUuid &tokenId)
return UserErrorNoError; return UserErrorNoError;
} }
/*! Returns true, if the given \a token is valid. */
bool UserManager::verifyToken(const QByteArray &token) bool UserManager::verifyToken(const QByteArray &token)
{ {
if (!validateToken(token)) { if (!validateToken(token)) {

View File

@ -45,7 +45,7 @@ public:
UserErrorPermissionDenied UserErrorPermissionDenied
}; };
explicit UserManager(const QString &dbName, QObject *parent = 0); explicit UserManager(const QString &dbName, QObject *parent = nullptr);
bool initRequired() const; bool initRequired() const;
QStringList users() const; QStringList users() const;

View File

@ -93,16 +93,14 @@
namespace nymeaserver { namespace nymeaserver {
/*! Constructs a \l{WebServer} with the given \a host, \a port, \a publicFolder and \a parent. /*! Constructs a \l{WebServer} with the given \a configuration, \a sslConfiguration and \a parent.
* *
* \sa ServerManager * \sa ServerManager, WebServerConfiguration
*/ */
WebServer::WebServer(const WebServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent) : WebServer::WebServer(const WebServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent) :
QTcpServer(parent), QTcpServer(parent),
m_avahiService(nullptr),
m_configuration(configuration), m_configuration(configuration),
m_sslConfiguration(sslConfiguration), m_sslConfiguration(sslConfiguration)
m_enabled(false)
{ {
if (QCoreApplication::instance()->organizationName() == "nymea-test") { if (QCoreApplication::instance()->organizationName() == "nymea-test") {
m_configuration.publicFolder = QCoreApplication::applicationDirPath(); m_configuration.publicFolder = QCoreApplication::applicationDirPath();
@ -121,6 +119,7 @@ WebServer::~WebServer()
this->close(); this->close();
} }
/*! Returns the server URL of this WebServer. */
QUrl WebServer::serverUrl() const QUrl WebServer::serverUrl() const
{ {
return QUrl(QString("%1://%2:%3").arg((m_configuration.sslEnabled ? "https" : "http")).arg(m_configuration.address.toString()).arg(m_configuration.port)); return QUrl(QString("%1://%2:%3").arg((m_configuration.sslEnabled ? "https" : "http")).arg(m_configuration.address.toString()).arg(m_configuration.port));
@ -544,12 +543,15 @@ void WebServer::resetAvahiService()
txt.insert("name", NymeaCore::instance()->configuration()->serverName()); txt.insert("name", NymeaCore::instance()->configuration()->serverName());
txt.insert("sslEnabled", m_configuration.sslEnabled ? "true" : "false"); txt.insert("sslEnabled", m_configuration.sslEnabled ? "true" : "false");
if (!m_avahiService->registerService(QString("nymea-http-%1").arg(m_configuration.id), m_configuration.address, m_configuration.port, "_http._tcp", txt)) { if (!m_avahiService->registerService(QString("nymea-http-%1").arg(m_configuration.id), m_configuration.address, static_cast<quint16>(m_configuration.port), "_http._tcp", txt)) {
qCWarning(dcTcpServer()) << "Could not register avahi service for" << m_configuration; qCWarning(dcTcpServer()) << "Could not register avahi service for" << m_configuration;
} }
} }
/*! Returns true if this \l{WebServer} could be reconfigured with the given \a address and \a port. */ /*! Set the configuration of this \l{WebServer} to the given \a config.
*
* \sa WebServerConfiguration
*/
void WebServer::reconfigureServer(const WebServerConfiguration &config) void WebServer::reconfigureServer(const WebServerConfiguration &config)
{ {
if (m_configuration.address == config.address && if (m_configuration.address == config.address &&
@ -565,6 +567,7 @@ void WebServer::reconfigureServer(const WebServerConfiguration &config)
startServer(); startServer();
} }
/*! Sets the server name to the given \a serverName. */
void WebServer::setServerName(const QString &serverName) void WebServer::setServerName(const QString &serverName)
{ {
m_serverName = serverName; m_serverName = serverName;
@ -574,7 +577,7 @@ void WebServer::setServerName(const QString &serverName)
/*! Returns true if this \l{WebServer} started successfully. */ /*! Returns true if this \l{WebServer} started successfully. */
bool WebServer::startServer() bool WebServer::startServer()
{ {
if (!listen(m_configuration.address, m_configuration.port)) { if (!listen(m_configuration.address, static_cast<quint16>(m_configuration.port))) {
qCWarning(dcWebServer()) << "Webserver could not listen on" << serverUrl().toString() << errorString(); qCWarning(dcWebServer()) << "Webserver could not listen on" << serverUrl().toString() << errorString();
m_enabled = false; m_enabled = false;
return false; return false;

View File

@ -50,7 +50,7 @@ class WebServerClient : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
WebServerClient(const QHostAddress &address, QObject *parent = 0); WebServerClient(const QHostAddress &address, QObject *parent = nullptr);
QHostAddress address() const; QHostAddress address() const;
@ -74,8 +74,8 @@ class WebServer : public QTcpServer
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit WebServer(const WebServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent = 0); explicit WebServer(const WebServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent = nullptr);
~WebServer(); ~WebServer() override;
QUrl serverUrl() const; QUrl serverUrl() const;
@ -86,12 +86,12 @@ private:
QList<WebServerClient *> m_webServerClients; QList<WebServerClient *> m_webServerClients;
QHash<QSslSocket *, HttpRequest> m_incompleteRequests; QHash<QSslSocket *, HttpRequest> m_incompleteRequests;
QtAvahiService *m_avahiService; QtAvahiService *m_avahiService = nullptr;
QString m_serverName; QString m_serverName;
WebServerConfiguration m_configuration; WebServerConfiguration m_configuration;
QSslConfiguration m_sslConfiguration; QSslConfiguration m_sslConfiguration;
bool m_enabled; bool m_enabled = false;
bool verifyFile(QSslSocket *socket, const QString &fileName); bool verifyFile(QSslSocket *socket, const QString &fileName);
QString fileName(const QString &query); QString fileName(const QString &query);

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> * * Copyright (C) 2015 - 2018 Simon Stürz <simon.stuerz@guh.io> *
* * * *
* This file is part of nymea. * * This file is part of nymea. *
* * * *
@ -56,13 +56,12 @@
namespace nymeaserver { namespace nymeaserver {
/*! Constructs a \l{WebSocketServer} with the given \a address, \a port \a sslEnabled and \a parent. /*! Constructs a \l{WebSocketServer} with the given \a configuration, \a sslConfiguration and \a parent.
* *
* \sa ServerManager * \sa ServerManager, ServerConfiguration
*/ */
WebSocketServer::WebSocketServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent) : WebSocketServer::WebSocketServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent) :
TransportInterface(configuration, parent), TransportInterface(configuration, parent),
m_server(0),
m_sslConfiguration(sslConfiguration), m_sslConfiguration(sslConfiguration),
m_enabled(false) m_enabled(false)
{ {
@ -77,6 +76,7 @@ WebSocketServer::~WebSocketServer()
stopServer(); stopServer();
} }
/*! Returns the url of this server. */
QUrl WebSocketServer::serverUrl() const QUrl WebSocketServer::serverUrl() const
{ {
return QUrl(QString("%1://%2:%3").arg((configuration().sslEnabled ? "wss" : "ws")).arg(configuration().address.toString()).arg(configuration().port)); return QUrl(QString("%1://%2:%3").arg((configuration().sslEnabled ? "wss" : "ws")).arg(configuration().address.toString()).arg(configuration().port));
@ -88,7 +88,7 @@ QUrl WebSocketServer::serverUrl() const
*/ */
void WebSocketServer::sendData(const QUuid &clientId, const QByteArray &data) void WebSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
{ {
QWebSocket *client = 0; QWebSocket *client = nullptr;
client = m_clientList.value(clientId); client = m_clientList.value(clientId);
if (client) { if (client) {
qCDebug(dcWebSocketServerTraffic()) << "Sending data to client" << data; qCDebug(dcWebSocketServerTraffic()) << "Sending data to client" << data;
@ -201,12 +201,12 @@ void WebSocketServer::resetAvahiService()
return; return;
m_avahiService->resetService(); m_avahiService->resetService();
if (!m_avahiService->registerService(QString("nymea-ws-%1").arg(configuration().id), configuration().address, configuration().port, "_ws._tcp", createTxtRecord())) { if (!m_avahiService->registerService(QString("nymea-ws-%1").arg(configuration().id), configuration().address, static_cast<quint16>(configuration().port), "_ws._tcp", createTxtRecord())) {
qCWarning(dcWebServer()) << "Could not register avahi service for" << configuration(); qCWarning(dcWebServer()) << "Could not register avahi service for" << configuration();
} }
} }
/*! Returns true if this \l{WebSocketServer} could be reconfigured with the given \a address and \a port. */ /*! Returns true if this \l{WebSocketServer} could be reconfigured with the given \a config. */
void WebSocketServer::reconfigureServer(const ServerConfiguration &config) void WebSocketServer::reconfigureServer(const ServerConfiguration &config)
{ {
if (configuration() == config && m_server->isListening()) { if (configuration() == config && m_server->isListening()) {
@ -224,6 +224,7 @@ void WebSocketServer::reconfigureServer(const ServerConfiguration &config)
startServer(); startServer();
} }
/*! Sets the server name to the given \a serverName. */
void WebSocketServer::setServerName(const QString &serverName) void WebSocketServer::setServerName(const QString &serverName)
{ {
m_serverName = serverName; m_serverName = serverName;
@ -245,7 +246,7 @@ bool WebSocketServer::startServer()
connect (m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onClientConnected); connect (m_server, &QWebSocketServer::newConnection, this, &WebSocketServer::onClientConnected);
connect (m_server, &QWebSocketServer::acceptError, this, &WebSocketServer::onServerError); connect (m_server, &QWebSocketServer::acceptError, this, &WebSocketServer::onServerError);
if (!m_server->listen(configuration().address, configuration().port)) { if (!m_server->listen(configuration().address, static_cast<quint16>(configuration().port))) {
qCWarning(dcConnection) << "Websocket server" << m_server->serverName() << "could not listen on" << serverUrl().toString(); qCWarning(dcConnection) << "Websocket server" << m_server->serverName() << "could not listen on" << serverUrl().toString();
return false; return false;
} }

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.io> * * Copyright (C) 2015 - 2018 Simon Stürz <simon.stuerz@guh.io> *
* * * *
* This file is part of nymea. * * This file is part of nymea. *
* * * *
@ -42,8 +42,8 @@ class WebSocketServer : public TransportInterface
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit WebSocketServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent = 0); explicit WebSocketServer(const ServerConfiguration &configuration, const QSslConfiguration &sslConfiguration, QObject *parent = nullptr);
~WebSocketServer(); ~WebSocketServer() override;
QUrl serverUrl() const; QUrl serverUrl() const;
@ -51,9 +51,9 @@ public:
void sendData(const QList<QUuid> &clients, const QByteArray &data) override; void sendData(const QList<QUuid> &clients, const QByteArray &data) override;
private: private:
QWebSocketServer *m_server; QWebSocketServer *m_server = nullptr;
QHash<QUuid, QWebSocket *> m_clientList; QHash<QUuid, QWebSocket *> m_clientList;
QtAvahiService *m_avahiService; QtAvahiService *m_avahiService = nullptr;
QSslConfiguration m_sslConfiguration; QSslConfiguration m_sslConfiguration;
bool m_enabled; bool m_enabled;

View File

@ -193,7 +193,7 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QDir> #include <QDir>
/*! Constructs the DeviceManager with the given \a locale and \a parent. There should only be one DeviceManager in the system created by \l{nymeaserver::NymeaCore}. /*! Constructs the DeviceManager with the given \a{hardwareManager}, \a locale and \a parent. There should only be one DeviceManager in the system created by \l{nymeaserver::NymeaCore}.
* Use \c nymeaserver::NymeaCore::instance()->deviceManager() instead to access the DeviceManager. */ * Use \c nymeaserver::NymeaCore::instance()->deviceManager() instead to access the DeviceManager. */
DeviceManager::DeviceManager(HardwareManager *hardwareManager, const QLocale &locale, QObject *parent) : DeviceManager::DeviceManager(HardwareManager *hardwareManager, const QLocale &locale, QObject *parent) :
QObject(parent), QObject(parent),