|
@@ -477,7 +477,7 @@ fw_addr varchar(60) -- "https://beacon.e-bash.ru/fw_update.php?mac="
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
-### ❌ 4. WiFi credentials в таблице устройств
|
|
|
|
|
|
|
+### ⚠️ 4. WiFi credentials - ИЗМЕНЕНИЯ
|
|
|
|
|
|
|
|
**Legacy:**
|
|
**Legacy:**
|
|
|
```sql
|
|
```sql
|
|
@@ -485,15 +485,102 @@ wf_client_ssid varchar(60) -- WiFi SSID
|
|
|
wf_client_psk varchar(60) -- WiFi пароль (plain text!)
|
|
wf_client_psk varchar(60) -- WiFi пароль (plain text!)
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-**Проблемы:**
|
|
|
|
|
-- Пароли в открытом виде
|
|
|
|
|
-- Одинаковые для всех устройств организации
|
|
|
|
|
-- При смене пароля нужно обновлять все devices
|
|
|
|
|
|
|
+**Проблемы Legacy:**
|
|
|
|
|
+- ❌ Пароли в открытом виде (plain text в БД)
|
|
|
|
|
+- ❌ Хранение в таблице `devices` (нужно обновлять каждое устройство)
|
|
|
|
|
+- ✅ НО: админ и клиент могли смотреть и менять пароли
|
|
|
|
|
|
|
|
**Новый подход:**
|
|
**Новый подход:**
|
|
|
-- WiFi credentials на уровне Organization (в `config` JSONB)
|
|
|
|
|
-- Шифрование паролей
|
|
|
|
|
-- Device получает через защищенный API endpoint
|
|
|
|
|
|
|
+
|
|
|
|
|
+**Хранение:**
|
|
|
|
|
+- WiFi credentials на уровне **Organization** (не в каждом device)
|
|
|
|
|
+- Шифрование паролей в БД (AES-256 или аналог)
|
|
|
|
|
+- Возможность расшифровки для показа админу/клиенту
|
|
|
|
|
+
|
|
|
|
|
+**UI - Просмотр и редактирование:**
|
|
|
|
|
+
|
|
|
|
|
+**В Organizations Panel (для superadmin/owner/admin):**
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+┌────────────────────────────────────────┐
|
|
|
|
|
+│ Organization: Shop LLC │
|
|
|
|
|
+│ │
|
|
|
|
|
+│ WiFi Settings: │
|
|
|
|
|
+│ │
|
|
|
|
|
+│ SSID: ___________________ │
|
|
|
|
|
+│ Shop_Guest_WiFi │
|
|
|
|
|
+│ │
|
|
|
|
|
+│ Password: ●●●●●●●●●● [👁 Show] │
|
|
|
|
|
+│ (click Show → myPassword123) │
|
|
|
|
|
+│ │
|
|
|
|
|
+│ [Save Changes] │
|
|
|
|
|
+└────────────────────────────────────────┘
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Кнопка "Show Password":**
|
|
|
|
|
+- По умолчанию: `●●●●●●●●●●` (скрыт)
|
|
|
|
|
+- Клик "Show" → показывает plain text: `myPassword123`
|
|
|
|
|
+- Клик "Hide" → снова скрывает
|
|
|
|
|
+
|
|
|
|
|
+**Права доступа:**
|
|
|
|
|
+- ✅ **Superadmin** - может смотреть и менять любые credentials
|
|
|
|
|
+- ✅ **Owner** - может смотреть и менять credentials своей организации
|
|
|
|
|
+- ✅ **Admin** - может смотреть и менять credentials своей организации
|
|
|
|
|
+- ❌ **Manager/Operator/Viewer** - НЕ могут смотреть пароли (только SSID)
|
|
|
|
|
+
|
|
|
|
|
+**API Endpoints:**
|
|
|
|
|
+
|
|
|
|
|
+```python
|
|
|
|
|
+# GET /api/v1/client/organization/wifi-credentials
|
|
|
|
|
+# Permissions: owner, admin
|
|
|
|
|
+{
|
|
|
|
|
+ "ssid": "Shop_Guest_WiFi",
|
|
|
|
|
+ "password": "myPassword123" # Расшифрованный пароль
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# PATCH /api/v1/client/organization/wifi-credentials
|
|
|
|
|
+# Permissions: owner, admin
|
|
|
|
|
+{
|
|
|
|
|
+ "ssid": "Shop_Guest_WiFi_New",
|
|
|
|
|
+ "password": "newPassword456"
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Backend шифрование:**
|
|
|
|
|
+
|
|
|
|
|
+```python
|
|
|
|
|
+from cryptography.fernet import Fernet
|
|
|
|
|
+
|
|
|
|
|
+class Organization(Base):
|
|
|
|
|
+ # ...
|
|
|
|
|
+ wifi_ssid = Column(String(100))
|
|
|
|
|
+ wifi_password_encrypted = Column(String(500)) # Зашифрованный пароль
|
|
|
|
|
+
|
|
|
|
|
+ @property
|
|
|
|
|
+ def wifi_password(self):
|
|
|
|
|
+ """Расшифровать пароль для показа админу"""
|
|
|
|
|
+ if not self.wifi_password_encrypted:
|
|
|
|
|
+ return None
|
|
|
|
|
+ return decrypt_password(self.wifi_password_encrypted)
|
|
|
|
|
+
|
|
|
|
|
+ @wifi_password.setter
|
|
|
|
|
+ def wifi_password(self, plain_password):
|
|
|
|
|
+ """Зашифровать пароль перед сохранением"""
|
|
|
|
|
+ self.wifi_password_encrypted = encrypt_password(plain_password)
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**Device получает через API:**
|
|
|
|
|
+- Device запрашивает `/api/v1/device/config?mac=...`
|
|
|
|
|
+- Backend проверяет `organization_id` устройства
|
|
|
|
|
+- Возвращает расшифрованные WiFi credentials
|
|
|
|
|
+- Device подключается к WiFi
|
|
|
|
|
+
|
|
|
|
|
+**Преимущества:**
|
|
|
|
|
+- ✅ Пароли зашифрованы в БД (безопасно)
|
|
|
|
|
+- ✅ Админ/клиент могут смотреть и менять (удобно)
|
|
|
|
|
+- ✅ Централизованное хранение на уровне Organization
|
|
|
|
|
+- ✅ При смене пароля обновляется одна запись (не все devices)
|
|
|
|
|
+- ✅ Device получает актуальные credentials через API
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
@@ -705,7 +792,7 @@ async def get_device_counts():
|
|
|
| **Статусы** | ❌ Только last seen | ✅ online/offline/error | ✅ Done |
|
|
| **Статусы** | ❌ Только last seen | ✅ online/offline/error | ✅ Done |
|
|
|
| **Simple ID** | ❌ Только MAC | ✅ #1, #2, #3 | ✅ Done |
|
|
| **Simple ID** | ❌ Только MAC | ✅ #1, #2, #3 | ✅ Done |
|
|
|
| **OpenVPN** | ✅ Было | ❌ Убрали | - |
|
|
| **OpenVPN** | ✅ Было | ❌ Убрали | - |
|
|
|
-| **WiFi creds в БД** | ✅ Plain text | ❌ API endpoint | ✅ Done |
|
|
|
|
|
|
|
+| **WiFi credentials** | ✅ Plain text в devices | ✅ Encrypted в org + UI | 🔨 TODO |
|
|
|
| **Пароли юзеров** | ❌ Plain text | ✅ Bcrypt hash | ✅ Done |
|
|
| **Пароли юзеров** | ❌ Plain text | ✅ Bcrypt hash | ✅ Done |
|
|
|
|
|
|
|
|
---
|
|
---
|
|
@@ -725,7 +812,7 @@ async def get_device_counts():
|
|
|
2. ❌ **OpenVPN** - не нужно по ТЗ
|
|
2. ❌ **OpenVPN** - не нужно по ТЗ
|
|
|
3. ❌ **Хардкод в БД** - заменили на JSONB config + API endpoints
|
|
3. ❌ **Хардкод в БД** - заменили на JSONB config + API endpoints
|
|
|
4. ❌ **Текстовые связи** - заменили на нормализованную БД
|
|
4. ❌ **Текстовые связи** - заменили на нормализованную БД
|
|
|
-5. ❌ **Plain text пароли** - заменили на bcrypt
|
|
|
|
|
|
|
+5. ❌ **Plain text user passwords** - заменили на bcrypt
|
|
|
6. ❌ **Отсутствие auth** - добавили JWT + RBAC
|
|
6. ❌ **Отсутствие auth** - добавили JWT + RBAC
|
|
|
|
|
|
|
|
### Что улучшили:
|
|
### Что улучшили:
|
|
@@ -741,6 +828,7 @@ async def get_device_counts():
|
|
|
### Next steps:
|
|
### Next steps:
|
|
|
|
|
|
|
|
1. 🔨 Реализовать универсальный поиск (HIGH priority)
|
|
1. 🔨 Реализовать универсальный поиск (HIGH priority)
|
|
|
-2. 🔨 Bulk import устройств (MEDIUM priority)
|
|
|
|
|
-3. 🔨 Фильтры по статусу (LOW priority)
|
|
|
|
|
-4. 🔨 Export to CSV/Excel (LOW priority)
|
|
|
|
|
|
|
+2. 🔨 WiFi credentials UI с шифрованием (HIGH priority)
|
|
|
|
|
+3. 🔨 Bulk import устройств (MEDIUM priority)
|
|
|
|
|
+4. 🔨 Фильтры по статусу (LOW priority)
|
|
|
|
|
+5. 🔨 Export to CSV/Excel (LOW priority)
|