Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,29 @@
# HOMEd Cloud Server

Сервер для интеграции устройств HOMEd с Умным Домом Яндекса

Параметры сервера:

http/port (8084): Порт для взаимодействия с yandex.
С учётом необходимости https ссылок имеет смысл пропускать через nginx или любой другой прокси с поддержкой https и указывать в навыке порт, где https соединение или изменить порт в настройках cloud server, а в прокси указать 8084.
В настройках навыка указать:
Backend: Endpoint URL https://домен:8084/api
URL авторизации: https://домен:8084/login
URL для получения токена: https://домен:8084/token
URL для обновления токена: https://домен:8084/refresh


server/port (8042): Порт для обмена с homed сервисом, совпадает с указанным в клиентском homed-cloud.conf

client/id и client/secret: Из навыка https://dialogs.yandex.ru/developer/smart-home - раздел "Связка аккаунтов" Client Identifier и Client Password

skill/id: можно получить из адреса навыка в диалогах https://dialogs.yandex.ru/developer/skills/<skill-id>/authorization

skill/token: https://yandex.ru/dev/dialogs/smart-home/doc/ru/reference-alerts/resources-alerts#oauth - получить токен

bot/token и bot/secret: параметры Телеграм бота, получить можно через @BotFather

user/login и user/password: Имя и пароль для входа пользователя при связывании аккаунтов, для тестирования или если не подключен бот Телеграм

rrd/path: путь к папке для формирования статистики, папка должна существовать.

24 changes: 21 additions & 3 deletions controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,28 @@ Controller::Controller(QObject *parent) : QObject(parent), m_db(QSqlDatabase::ad
m_botToken = m_settings->value("bot/token").toByteArray();
m_botSecret = m_settings->value("bot/secret").toByteArray();
m_rrdPath = m_settings->value("rrd/path").toByteArray();
m_userLogin = m_settings->value("user/login").toByteArray();
m_userPassword = m_settings->value("user/password").toByteArray();

m_aes->init(m_clientSecret, QCryptographicHash::hash(m_clientSecret, QCryptographicHash::Md5));
query.exec("SELECT chat, name, hash, clientToken, accessToken, refreshToken, tokenExpire FROM users");

bool b = query.exec("SELECT chat, name, hash, clientToken, accessToken, refreshToken, tokenExpire FROM users");
if (!b) {
b = query.exec("CREATE TABLE users (chat INTEGER PRIMARY KEY, name TEXT, hash TEXT, clientToken TEXT, accessToken TEXT, refreshToken TEXT, tokenExpire INTEGER, timestamp INTEGER);");
if (!b) {
qWarning() << "Database query error" << m_db.lastError().text();
}
}
if(!m_userLogin.isEmpty()){
bool su = query.exec(QString("SELECT chat, name, hash, clientToken, accessToken, refreshToken, tokenExpire FROM users WHERE name='%1'").arg(m_userLogin.constData()));
if(!su) {
QByteArray salt = randomData(16);
b=query.exec(QString("INSERT INTO users (name, hash, clientToken, timestamp) VALUES ('%2', '%3', '%4', %5) ON CONFLICT (name) DO UPDATE SET name = excluded.name, hash = excluded.hash, clientToken = excluded.clientToken, accessToken = NULL, refreshToken = NULL, tokenExpire = NULL, timestamp = excluded.timestamp").arg(m_userLogin.constData(), salt.toHex().append(QCryptographicHash::hash(QByteArray(salt).append(m_userPassword), QCryptographicHash::Md5).toHex()), randomData(32).toHex()).arg(QDateTime::currentSecsSinceEpoch()));
if(!b) {
qWarning() << "Database query error | insert single user" << m_db.lastError().text();
}
b = query.exec("SELECT chat, name, hash, clientToken, accessToken, refreshToken, tokenExpire FROM users");
}
}
while (query.next())
{
qint64 id = query.value(0).toLongLong();
Expand Down Expand Up @@ -158,7 +176,7 @@ void Controller::updateStats(void)

void Controller::requestReceived(Request &request)
{
if (request.url() == "/telegram")
if (!m_botSecret.isEmpty() && request.url() == "/telegram")
{
QJsonObject json = QJsonDocument::fromJson(request.body().toUtf8()).object().value("message").toObject(), chat = json.value("chat").toObject(), from = json.value("from").toObject();

Expand Down
2 changes: 1 addition & 1 deletion controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class Controller : public QObject
AES128 *m_aes;

bool m_debug;
QByteArray m_path, m_clientId, m_clientSecret, m_skillId, m_skillToken, m_botHost, m_botToken, m_botSecret, m_rrdPath;
QByteArray m_path, m_clientId, m_clientSecret, m_skillId, m_skillToken, m_botHost, m_botToken, m_botSecret, m_userLogin, m_userPassword, m_rrdPath;
quint32 m_apiCount, m_eventCount, m_clientCount, m_descriptorCount;

QMap <qint64, User> m_users;
Expand Down
8 changes: 8 additions & 0 deletions deploy/homed-cloud-server.conf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,11 @@ token=

[bot]
token=
secret=

[user]
login=
password=

[rrd]
path=