From 55a444836a5a73192d06c0760d22d1e54cd22ce9 Mon Sep 17 00:00:00 2001 From: kalugin66 <150135283+kalugin1988@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:54:37 +0500 Subject: [PATCH] Add files via upload --- auth.js | 210 +++++++++++++++++++++++++++--------------------------- server.js | 65 ++++++++++------- 2 files changed, 147 insertions(+), 128 deletions(-) diff --git a/auth.js b/auth.js index 059a893..a763db9 100644 --- a/auth.js +++ b/auth.js @@ -104,121 +104,123 @@ class AuthService { }); } - async authenticateLDAP(username, password) { - try { - const response = await fetch(process.env.LDAP_AUTH_URL, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ username, password }) - }); +async authenticateLDAP(username, password) { + try { + const response = await fetch(process.env.LDAP_AUTH_URL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ username, password }) + }); - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`); - } + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } - const data = await response.json(); - - if (data.success) { - return this.processLDAPUser(data); - } else { - return null; - } - } catch (error) { - console.error('LDAP authentication error:', error); + const data = await response.json(); + + if (data.success) { + return this.processLDAPUser(data); + } else { return null; } + } catch (error) { + console.error('LDAP authentication error:', error); + return null; } +} - async processLDAPUser(ldapData) { - const { username, full_name, groups, description } = ldapData; - - // Определяем роль пользователя на основе групп - const allowedGroups = process.env.ALLOWED_GROUPS ? - process.env.ALLOWED_GROUPS.split(',').map(g => g.trim()) : []; - - const isAdmin = groups && groups.some(group => - allowedGroups.includes(group) - ); - - const role = isAdmin ? 'admin' : 'teacher'; - - // Сохраняем/обновляем пользователя в базе - return new Promise((resolve, reject) => { - db.get("SELECT * FROM users WHERE login = ? AND auth_type = 'ldap'", [username], async (err, existingUser) => { - if (err) { - reject(err); - return; - } +async processLDAPUser(ldapData) { + const { username, full_name, groups, description } = ldapData; + + // Определяем роль пользователя на основе групп + const allowedGroups = process.env.ALLOWED_GROUPS ? + process.env.ALLOWED_GROUPS.split(',').map(g => g.trim()) : []; + + // ВАЖНО: Проверяем актуальные группы при каждом входе + const isAdmin = groups && groups.some(group => + allowedGroups.includes(group) + ); + + const role = isAdmin ? 'admin' : 'teacher'; + + // Сохраняем/обновляем пользователя в базе + return new Promise((resolve, reject) => { + db.get("SELECT * FROM users WHERE login = ? AND auth_type = 'ldap'", [username], async (err, existingUser) => { + if (err) { + reject(err); + return; + } - const userData = { - login: username, - name: full_name || username, - email: `${username}@school25.ru`, - role: role, - auth_type: 'ldap', - groups: groups ? JSON.stringify(groups) : '[]', - description: description || '', - last_login: new Date().toISOString() - }; + const userData = { + login: username, + name: full_name || username, + email: `${username}@school25.ru`, + role: role, // Всегда обновляем роль из актуальных групп + auth_type: 'ldap', + groups: groups ? JSON.stringify(groups) : '[]', + description: description || '', + last_login: new Date().toISOString() + }; - if (existingUser) { - // Обновляем существующего пользователя - db.run( - `UPDATE users SET - name = ?, email = ?, role = ?, groups = ?, description = ?, last_login = datetime('now'), - updated_at = datetime('now') - WHERE id = ?`, - [userData.name, userData.email, userData.role, userData.groups, userData.description, existingUser.id], - function(err) { - if (err) { - reject(err); - } else { - // Возвращаем полные данные пользователя - resolve({ - id: existingUser.id, - login: userData.login, - name: userData.name, - email: userData.email, - role: userData.role, - auth_type: userData.auth_type, - groups: userData.groups, - description: userData.description, - last_login: new Date().toISOString() - }); - } + if (existingUser) { + // Всегда обновляем роль, даже если пользователь уже существует + db.run( + `UPDATE users SET + name = ?, email = ?, role = ?, groups = ?, description = ?, last_login = datetime('now'), + updated_at = datetime('now') + WHERE id = ?`, + [userData.name, userData.email, userData.role, userData.groups, userData.description, existingUser.id], + function(err) { + if (err) { + reject(err); + } else { + console.log(`Обновлены данные LDAP пользователя ${username}. Роль: ${userData.role}, Группы: ${groups}`); + resolve({ + id: existingUser.id, + login: userData.login, + name: userData.name, + email: userData.email, + role: userData.role, + auth_type: userData.auth_type, + groups: userData.groups, + description: userData.description, + last_login: new Date().toISOString() + }); } - ); - } else { - // Создаем нового пользователя - db.run( - `INSERT INTO users (login, name, email, role, auth_type, groups, description, created_at, last_login) - VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))`, - [userData.login, userData.name, userData.email, userData.role, userData.auth_type, - userData.groups, userData.description], - function(err) { - if (err) { - reject(err); - } else { - resolve({ - id: this.lastID, - login: userData.login, - name: userData.name, - email: userData.email, - role: userData.role, - auth_type: userData.auth_type, - groups: userData.groups, - description: userData.description, - last_login: new Date().toISOString() - }); - } + } + ); + } else { + // Создаем нового пользователя + db.run( + `INSERT INTO users (login, name, email, role, auth_type, groups, description, created_at, last_login) + VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))`, + [userData.login, userData.name, userData.email, userData.role, userData.auth_type, + userData.groups, userData.description], + function(err) { + if (err) { + reject(err); + } else { + console.log(`Создан новый LDAP пользователь ${username}. Роль: ${userData.role}, Группы: ${groups}`); + resolve({ + id: this.lastID, + login: userData.login, + name: userData.name, + email: userData.email, + role: userData.role, + auth_type: userData.auth_type, + groups: userData.groups, + description: userData.description, + last_login: new Date().toISOString() + }); } - ); - } - }); + } + ); + } }); - } + }); +} async authenticate(login, password) { // Сначала пробуем локальную авторизацию diff --git a/server.js b/server.js index 6e9dccf..5ed5592 100644 --- a/server.js +++ b/server.js @@ -367,35 +367,52 @@ app.post('/api/logout', (req, res) => { }); }); +// В server.js обновите маршрут /api/user app.get('/api/user', (req, res) => { if (req.session.user) { - // Обновляем данные пользователя из базы на случай изменений - authService.getUserById(req.session.user.id) - .then(user => { - if (user) { - const updatedUser = { - id: user.id, - login: user.login, - name: user.name, - email: user.email, - role: user.role, - auth_type: user.auth_type, - groups: user.groups ? (typeof user.groups === 'string' ? JSON.parse(user.groups) : user.groups) : [] - }; - - // Обновляем сессию - req.session.user = updatedUser; - res.json({ user: updatedUser }); - } else { - // Пользователь не найден в базе - разлогиниваем + // Для LDAP пользователей всегда проверяем актуальную роль + if (req.session.user.auth_type === 'ldap') { + db.get("SELECT groups FROM users WHERE id = ?", [req.session.user.id], (err, user) => { + if (err || !user) { req.session.destroy(); - res.status(401).json({ error: 'Пользователь не найден' }); + return res.status(401).json({ error: 'Пользователь не найден' }); } - }) - .catch(err => { - console.error('Ошибка получения пользователя:', err); - res.status(500).json({ error: 'Ошибка сервера' }); + + // Парсим группы + let groups = []; + try { + groups = JSON.parse(user.groups || '[]'); + } catch (e) { + groups = []; + } + + // Проверяем группы + const allowedGroups = process.env.ALLOWED_GROUPS ? + process.env.ALLOWED_GROUPS.split(',').map(g => g.trim()) : []; + + const isAdmin = groups.some(group => allowedGroups.includes(group)); + const actualRole = isAdmin ? 'admin' : 'teacher'; + + // Обновляем роль если изменилась + if (req.session.user.role !== actualRole) { + console.log(`Обновлена роль пользователя ${req.session.user.login} с ${req.session.user.role} на ${actualRole}`); + + // Обновляем в базе + db.run( + "UPDATE users SET role = ?, updated_at = datetime('now') WHERE id = ?", + [actualRole, req.session.user.id] + ); + + // Обновляем в сессии + req.session.user.role = actualRole; + } + + res.json({ user: req.session.user }); }); + } else { + // Для локальных пользователей просто возвращаем данные + res.json({ user: req.session.user }); + } } else { res.status(401).json({ error: 'Не аутентифицирован' }); }