Add files via upload

This commit is contained in:
kalugin66
2025-12-03 17:54:37 +05:00
committed by GitHub
parent 66ce899d9c
commit 55a444836a
2 changed files with 147 additions and 128 deletions

210
auth.js
View File

@@ -104,121 +104,123 @@ class AuthService {
}); });
} }
async authenticateLDAP(username, password) { async authenticateLDAP(username, password) {
try { try {
const response = await fetch(process.env.LDAP_AUTH_URL, { const response = await fetch(process.env.LDAP_AUTH_URL, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ username, password }) body: JSON.stringify({ username, password })
}); });
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
} }
const data = await response.json(); const data = await response.json();
if (data.success) { if (data.success) {
return this.processLDAPUser(data); return this.processLDAPUser(data);
} else { } else {
return null;
}
} catch (error) {
console.error('LDAP authentication error:', error);
return null; return null;
} }
} catch (error) {
console.error('LDAP authentication error:', error);
return null;
} }
}
async processLDAPUser(ldapData) { async processLDAPUser(ldapData) {
const { username, full_name, groups, description } = ldapData; const { username, full_name, groups, description } = ldapData;
// Определяем роль пользователя на основе групп // Определяем роль пользователя на основе групп
const allowedGroups = process.env.ALLOWED_GROUPS ? const allowedGroups = process.env.ALLOWED_GROUPS ?
process.env.ALLOWED_GROUPS.split(',').map(g => g.trim()) : []; process.env.ALLOWED_GROUPS.split(',').map(g => g.trim()) : [];
const isAdmin = groups && groups.some(group => // ВАЖНО: Проверяем актуальные группы при каждом входе
allowedGroups.includes(group) const isAdmin = groups && groups.some(group =>
); allowedGroups.includes(group)
);
const role = isAdmin ? 'admin' : 'teacher';
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) => { return new Promise((resolve, reject) => {
if (err) { db.get("SELECT * FROM users WHERE login = ? AND auth_type = 'ldap'", [username], async (err, existingUser) => {
reject(err); if (err) {
return; reject(err);
} return;
}
const userData = { const userData = {
login: username, login: username,
name: full_name || username, name: full_name || username,
email: `${username}@school25.ru`, email: `${username}@school25.ru`,
role: role, role: role, // Всегда обновляем роль из актуальных групп
auth_type: 'ldap', auth_type: 'ldap',
groups: groups ? JSON.stringify(groups) : '[]', groups: groups ? JSON.stringify(groups) : '[]',
description: description || '', description: description || '',
last_login: new Date().toISOString() last_login: new Date().toISOString()
}; };
if (existingUser) { if (existingUser) {
// Обновляем существующего пользователя // Всегда обновляем роль, даже если пользователь уже существует
db.run( db.run(
`UPDATE users SET `UPDATE users SET
name = ?, email = ?, role = ?, groups = ?, description = ?, last_login = datetime('now'), name = ?, email = ?, role = ?, groups = ?, description = ?, last_login = datetime('now'),
updated_at = datetime('now') updated_at = datetime('now')
WHERE id = ?`, WHERE id = ?`,
[userData.name, userData.email, userData.role, userData.groups, userData.description, existingUser.id], [userData.name, userData.email, userData.role, userData.groups, userData.description, existingUser.id],
function(err) { function(err) {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
// Возвращаем полные данные пользователя console.log(`Обновлены данные LDAP пользователя ${username}. Роль: ${userData.role}, Группы: ${groups}`);
resolve({ resolve({
id: existingUser.id, id: existingUser.id,
login: userData.login, login: userData.login,
name: userData.name, name: userData.name,
email: userData.email, email: userData.email,
role: userData.role, role: userData.role,
auth_type: userData.auth_type, auth_type: userData.auth_type,
groups: userData.groups, groups: userData.groups,
description: userData.description, description: userData.description,
last_login: new Date().toISOString() last_login: new Date().toISOString()
}); });
}
} }
); }
} else { );
// Создаем нового пользователя } else {
db.run( // Создаем нового пользователя
`INSERT INTO users (login, name, email, role, auth_type, groups, description, created_at, last_login) db.run(
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))`, `INSERT INTO users (login, name, email, role, auth_type, groups, description, created_at, last_login)
[userData.login, userData.name, userData.email, userData.role, userData.auth_type, VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))`,
userData.groups, userData.description], [userData.login, userData.name, userData.email, userData.role, userData.auth_type,
function(err) { userData.groups, userData.description],
if (err) { function(err) {
reject(err); if (err) {
} else { reject(err);
resolve({ } else {
id: this.lastID, console.log(`Создан новый LDAP пользователь ${username}. Роль: ${userData.role}, Группы: ${groups}`);
login: userData.login, resolve({
name: userData.name, id: this.lastID,
email: userData.email, login: userData.login,
role: userData.role, name: userData.name,
auth_type: userData.auth_type, email: userData.email,
groups: userData.groups, role: userData.role,
description: userData.description, auth_type: userData.auth_type,
last_login: new Date().toISOString() groups: userData.groups,
}); description: userData.description,
} last_login: new Date().toISOString()
});
} }
); }
} );
}); }
}); });
} });
}
async authenticate(login, password) { async authenticate(login, password) {
// Сначала пробуем локальную авторизацию // Сначала пробуем локальную авторизацию

View File

@@ -367,35 +367,52 @@ app.post('/api/logout', (req, res) => {
}); });
}); });
// В server.js обновите маршрут /api/user
app.get('/api/user', (req, res) => { app.get('/api/user', (req, res) => {
if (req.session.user) { if (req.session.user) {
// Обновляем данные пользователя из базы на случай изменений // Для LDAP пользователей всегда проверяем актуальную роль
authService.getUserById(req.session.user.id) if (req.session.user.auth_type === 'ldap') {
.then(user => { db.get("SELECT groups FROM users WHERE id = ?", [req.session.user.id], (err, user) => {
if (user) { if (err || !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 {
// Пользователь не найден в базе - разлогиниваем
req.session.destroy(); req.session.destroy();
res.status(401).json({ error: 'Пользователь не найден' }); return res.status(401).json({ error: 'Пользователь не найден' });
} }
})
.catch(err => { // Парсим группы
console.error('Ошибка получения пользователя:', err); let groups = [];
res.status(500).json({ error: 'Ошибка сервера' }); 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 { } else {
res.status(401).json({ error: 'Не аутентифицирован' }); res.status(401).json({ error: 'Не аутентифицирован' });
} }