feat(iot): bcrypt-хэш паролей устройств и бриджа + EMQX на bcrypt (P0-3 ч.1)
- handler CreateIoTDevice: пароль устройства хранится bcrypt-хэшем (hashPassword), открытый пароль отдаётся один раз в 201. - store.EnsureBridgeDevice: пароль бриджа тоже bcrypt-хэшем. - emqx/emqx.conf: password_hash_algorithm name=bcrypt, salt_rounds=10 (подтверждено по emqx/emqx: HOCON-ключ salt_rounds; Go bcrypt.DefaultCost=10). - Добавлена зависимость golang.org/x/crypto v0.42.0.
This commit is contained in:
@@ -3,6 +3,8 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// bridgeNamespace — служебный namespace строки бриджа в iot_devices.
|
||||
@@ -17,14 +19,20 @@ const bridgeNamespace = "__bridge"
|
||||
// Нужно для PG-auth EMQX (хвост 3): EMQX зависит только от PostgreSQL,
|
||||
// монолит при старте гарантирует наличие строки бриджа.
|
||||
func (s *DeviceStore) EnsureBridgeDevice(ctx context.Context, username, password string) error {
|
||||
_, err := s.db.ExecContext(ctx, `
|
||||
// Пароль бриджа храним bcrypt-хэшем (EMQX проверяет bcrypt), как и пароли
|
||||
// устройств.
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("store: hash bridge password: %w", err)
|
||||
}
|
||||
_, err = s.db.ExecContext(ctx, `
|
||||
INSERT INTO iot_devices (namespace, name, device_id, enabled, mqtt_password, metadata, phase)
|
||||
VALUES ($1, $2, $3, true, $4, '{}'::jsonb, 'Active')
|
||||
ON CONFLICT (namespace, name) DO UPDATE
|
||||
SET device_id = EXCLUDED.device_id,
|
||||
enabled = true,
|
||||
mqtt_password = EXCLUDED.mqtt_password`,
|
||||
bridgeNamespace, "iot-bridge", username, password)
|
||||
bridgeNamespace, "iot-bridge", username, string(hash))
|
||||
if err != nil {
|
||||
return fmt.Errorf("store: ensure bridge device: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user