diff --git a/api2-groups.js b/api2-groups.js index 90a898e..81f96a0 100644 --- a/api2-groups.js +++ b/api2-groups.js @@ -44,29 +44,29 @@ module.exports = function(app, db) { } // Таблица с идентификаторами пользователей - db.run(` - CREATE TABLE IF NOT EXISTS idusers ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - user_id INTEGER NOT NULL, - service_type TEXT NOT NULL, -- 'sberbank', 'yandex', 'ldap', 'other' - external_id TEXT NOT NULL, - login TEXT, -- Логин LDAP (если есть) - ldap_group TEXT, -- Группа LDAP (если есть) - group_id INTEGER, -- Ссылка на группу в idgroups - metadata TEXT, -- Дополнительные данные в JSON - is_active BOOLEAN DEFAULT true, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE, - FOREIGN KEY (group_id) REFERENCES idgroups (id) ON DELETE SET NULL, - UNIQUE(user_id, service_type, external_id) - ) - `, (err) => { - if (err) { - console.error('❌ Ошибка создания таблицы idusers:', err.message); - reject(err); - return; - } +db.run(` + CREATE TABLE IF NOT EXISTS idusers ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL, + service_type TEXT NOT NULL, -- 'sberbank', 'yandex', 'ldap', 'other' + external_id TEXT, -- СДЕЛАЛИ НЕОБЯЗАТЕЛЬНЫМ + login TEXT, -- Логин LDAP (если есть) + ldap_group TEXT, -- Группа LDAP (если есть) + group_id INTEGER, -- Ссылка на группу в idgroups + metadata TEXT, -- Дополнительные данные в JSON + is_active BOOLEAN DEFAULT true, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE, + FOREIGN KEY (group_id) REFERENCES idgroups (id) ON DELETE SET NULL, + UNIQUE(user_id, service_type, external_id) -- Теперь external_id может быть NULL + ) +`, (err) => { + if (err) { + console.error('❌ Ошибка создания таблицы idusers:', err.message); + reject(err); + return; + } // Создаем индексы db.run('CREATE INDEX IF NOT EXISTS idx_idusers_user_id ON idusers(user_id)', (err) => { @@ -510,46 +510,135 @@ module.exports = function(app, db) { }); // POST /api2/idusers - Создать новый идентификатор пользователя (только админ) - router.post('/api2/idusers', requireAuth, requireAdmin, (req, res) => { - const { - user_id, - service_type, - external_id, - login, - ldap_group, - group_id, - metadata, - is_active - } = req.body; - - // Валидация обязательных полей - if (!user_id || !service_type || !external_id) { - return res.status(400).json({ - error: 'Обязательные поля: user_id, service_type, external_id' - }); +router.post('/api2/idusers', requireAuth, requireAdmin, (req, res) => { + const { + user_id, + service_type, + external_id, + login, + ldap_group, + group_id, + metadata, + is_active + } = req.body; + + // Валидация обязательных полей - СДЕЛАЕМ external_id НЕОБЯЗАТЕЛЬНЫМ + if (!user_id || !service_type) { + return res.status(400).json({ + error: 'Обязательные поля: user_id, service_type' + }); + } + + const validServiceTypes = ['sberbank', 'yandex', 'ldap', 'other']; + if (!validServiceTypes.includes(service_type)) { + return res.status(400).json({ + error: `Недопустимый тип сервиса. Допустимые значения: ${validServiceTypes.join(', ')}` + }); + } + + // Проверяем существование пользователя + db.get('SELECT id FROM users WHERE id = ?', [user_id], (err, user) => { + if (err) { + console.error('❌ Ошибка проверки пользователя:', err); + return res.status(500).json({ error: 'Ошибка проверки пользователя' }); } - const validServiceTypes = ['sberbank', 'yandex', 'ldap', 'other']; - if (!validServiceTypes.includes(service_type)) { - return res.status(400).json({ - error: `Недопустимый тип сервиса. Допустимые значения: ${validServiceTypes.join(', ')}` - }); + if (!user) { + return res.status(404).json({ error: 'Пользователь не найден' }); } - // Проверяем существование пользователя - db.get('SELECT id FROM users WHERE id = ?', [user_id], (err, user) => { - if (err) { - console.error('❌ Ошибка проверки пользователя:', err); - return res.status(500).json({ error: 'Ошибка проверки пользователя' }); - } + // Если указана группа, проверяем ее существование + if (group_id) { + db.get('SELECT id, service_type FROM idgroups WHERE id = ?', [group_id], (err, group) => { + if (err) { + console.error('❌ Ошибка проверки группы:', err); + return res.status(500).json({ error: 'Ошибка проверки группы' }); + } + + if (!group) { + return res.status(404).json({ error: 'Указанная группа не найдена' }); + } + + // УБИРАЕМ проверку соответствия типа сервиса + // Теперь группы независимы от сервиса + createIdUser(); + }); + } else { + // Создаем идентификатор без группы + createIdUser(); + } + + function createIdUser() { + const metadataJson = metadata ? JSON.stringify(metadata) : null; - if (!user) { - return res.status(404).json({ error: 'Пользователь не найден' }); - } + // Генерируем уникальный external_id если он не предоставлен + const finalExternalId = external_id || `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; - // Если указана группа, проверяем ее существование + db.run( + `INSERT INTO idusers + (user_id, service_type, external_id, login, ldap_group, group_id, metadata, is_active) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, + [ + user_id, + service_type, + finalExternalId, + login || null, + ldap_group || null, + group_id || null, + metadataJson, + is_active !== undefined ? (is_active ? 1 : 0) : 1 + ], + function(err) { + if (err) { + if (err.code === 'SQLITE_CONSTRAINT') { + return res.status(409).json({ + error: 'Идентификатор с такими параметрами уже существует для этого пользователя' + }); + } + console.error('❌ Ошибка создания идентификатора:', err); + return res.status(500).json({ error: 'Ошибка создания идентификатора' }); + } + + res.status(201).json({ + success: true, + id: this.lastID, + message: 'Идентификатор успешно создан' + }); + } + ); + } + }); +}); + + // PUT /api2/idusers/:id - Обновить идентификатор пользователя (только админ) +router.put('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => { + const { id } = req.params; + const { + user_id, + service_type, + external_id, + login, + ldap_group, + group_id, + metadata, + is_active + } = req.body; + + // Проверяем существование идентификатора + db.get('SELECT * FROM idusers WHERE id = ?', [id], (err, existing) => { + if (err) { + console.error('❌ Ошибка проверки идентификатора:', err); + return res.status(500).json({ error: 'Ошибка проверки идентификатора' }); + } + + if (!existing) { + return res.status(404).json({ error: 'Идентификатор не найден' }); + } + + // Если указана группа и она меняется, проверяем существование новой группы + if (group_id !== undefined && group_id !== existing.group_id) { if (group_id) { - db.get('SELECT id, service_type FROM idgroups WHERE id = ?', [group_id], (err, group) => { + db.get('SELECT id FROM idgroups WHERE id = ?', [group_id], (err, group) => { if (err) { console.error('❌ Ошибка проверки группы:', err); return res.status(500).json({ error: 'Ошибка проверки группы' }); @@ -559,85 +648,18 @@ module.exports = function(app, db) { return res.status(404).json({ error: 'Указанная группа не найдена' }); } - // Проверяем соответствие типа сервиса - if (group.service_type !== service_type) { - return res.status(400).json({ - error: `Тип сервиса группы (${group.service_type}) не соответствует типу сервиса идентификатора (${service_type})` - }); - } - - // Создаем идентификатор - createIdUser(); + // УБИРАЕМ проверку соответствия типа сервиса + // Теперь группы независимы от сервиса + updateIdUser(); }); } else { - // Создаем идентификатор без группы - createIdUser(); + updateIdUser(); } - - function createIdUser() { - const metadataJson = metadata ? JSON.stringify(metadata) : null; - - db.run( - `INSERT INTO idusers - (user_id, service_type, external_id, login, ldap_group, group_id, metadata, is_active) - VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, - [ - user_id, - service_type, - external_id, - login || null, - ldap_group || null, - group_id || null, - metadataJson, - is_active !== undefined ? (is_active ? 1 : 0) : 1 - ], - function(err) { - if (err) { - if (err.code === 'SQLITE_CONSTRAINT') { - return res.status(409).json({ - error: 'Идентификатор с такими параметрами уже существует для этого пользователя' - }); - } - console.error('❌ Ошибка создания идентификатора:', err); - return res.status(500).json({ error: 'Ошибка создания идентификатора' }); - } - - res.status(201).json({ - success: true, - id: this.lastID, - message: 'Идентификатор успешно создан' - }); - } - ); - } - }); - }); - - // PUT /api2/idusers/:id - Обновить идентификатор пользователя (только админ) - router.put('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => { - const { id } = req.params; - const { - user_id, - service_type, - external_id, - login, - ldap_group, - group_id, - metadata, - is_active - } = req.body; + } else { + updateIdUser(); + } - // Проверяем существование идентификатора - db.get('SELECT * FROM idusers WHERE id = ?', [id], (err, existing) => { - if (err) { - console.error('❌ Ошибка проверки идентификатора:', err); - return res.status(500).json({ error: 'Ошибка проверки идентификатора' }); - } - - if (!existing) { - return res.status(404).json({ error: 'Идентификатор не найден' }); - } - + function updateIdUser() { // Собираем поля для обновления const updates = []; const params = []; @@ -660,7 +682,9 @@ module.exports = function(app, db) { if (external_id !== undefined) { updates.push('external_id = ?'); - params.push(external_id); + // Генерируем временный external_id если он пустой + const finalExternalId = external_id || `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; + params.push(finalExternalId); } if (login !== undefined) { @@ -711,11 +735,12 @@ module.exports = function(app, db) { res.json({ success: true, changes: this.changes, - message: 'Идентификатор успешно обновлен' + message: 'Идентификатор успешно обновлен' }); }); - }); + } }); +}); // DELETE /api2/idusers/:id - Удалить идентификатор пользователя (только админ) router.delete('/api2/idusers/:id', requireAuth, requireAdmin, (req, res) => { diff --git a/public/doc.html b/public/doc.html index 7713874..f17ad3e 100644 --- a/public/doc.html +++ b/public/doc.html @@ -3,351 +3,959 @@ - Управление внешними идентификаторами - + Панель управления - Группы и идентификаторы +
-
-
-
-

Группы 2.0

-

Управление идентификаторами пользователей в сторонних системах

-
-