проверка активности клиета и изменение своего профиля
This commit is contained in:
Binary file not shown.
+20
-3
@@ -8,8 +8,10 @@ router = APIRouter()
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/", name="userInfo", summary="Получение информации о пользователе")
|
@router.get("/", name="userInfo", summary="Получение информации о пользователе")
|
||||||
async def get_user():
|
async def get_user(request_data: dict = Depends(requestDict)):
|
||||||
return
|
userId = int(request_data.get("query").get("userId"))
|
||||||
|
logger.info(f"Получение информации о пользователе {userId}")
|
||||||
|
return await UserHandler.get(userId)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/", summary="Правка данных пользователя")
|
@router.post("/", summary="Правка данных пользователя")
|
||||||
@@ -17,13 +19,14 @@ async def manage_user(request_data: dict = Depends(requestDict)):
|
|||||||
response = {"status": "error"}
|
response = {"status": "error"}
|
||||||
userData = request_data.get("body").get("userData", {})
|
userData = request_data.get("body").get("userData", {})
|
||||||
action = request_data.get("body").get("action")
|
action = request_data.get("body").get("action")
|
||||||
userId = request_data.get("body").get("userId")
|
userId = int(request_data.get("body").get("userId"))
|
||||||
match action:
|
match action:
|
||||||
case "create":
|
case "create":
|
||||||
result = await UserHandler.add(userData, userId)
|
result = await UserHandler.add(userData, userId)
|
||||||
if result:
|
if result:
|
||||||
response["status"] = "ok"
|
response["status"] = "ok"
|
||||||
case "update":
|
case "update":
|
||||||
|
logger.info(f"Обновление данных пользователя {userId}")
|
||||||
result = await UserHandler.edit(userData, user_id=userId)
|
result = await UserHandler.edit(userData, user_id=userId)
|
||||||
if "error" not in result:
|
if "error" not in result:
|
||||||
response["status"] = "ok"
|
response["status"] = "ok"
|
||||||
@@ -75,6 +78,20 @@ async def authenticationPage(request: Request):
|
|||||||
return await render(request)
|
return await render(request)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/check", summary="Проверка авторизации")
|
||||||
|
async def check_authentication(request_data: dict = Depends(requestDict)):
|
||||||
|
try:
|
||||||
|
userId = int(request_data.get("body").get("userId"))
|
||||||
|
logger.info(f"Проверка авторизации пользователя {userId}")
|
||||||
|
result = await UserHandler.checkActive(userId)
|
||||||
|
if result:
|
||||||
|
return {"status": "ok"}
|
||||||
|
else:
|
||||||
|
return {"status": "error"}
|
||||||
|
except:
|
||||||
|
return {"status": "error"}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/login")
|
@router.post("/login")
|
||||||
async def authentication(
|
async def authentication(
|
||||||
request_data: dict = Depends(requestDict),
|
request_data: dict = Depends(requestDict),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ function hideLoader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function apiRequest(url, payload = {}, method = 'POST') {
|
export async function apiRequest(url, payload = {}, method = 'POST') {
|
||||||
method = method.toUpperCase();
|
method = typeof method === 'string' ? method.toUpperCase() : 'POST';
|
||||||
|
|
||||||
let finalUrl = url;
|
let finalUrl = url;
|
||||||
let options = {
|
let options = {
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ export async function setCookie(name, value, days = 180) {
|
|||||||
const expires = new Date(Date.now() + days * 864e5).toUTCString();
|
const expires = new Date(Date.now() + days * 864e5).toUTCString();
|
||||||
const encodedName = encodeURIComponent(name);
|
const encodedName = encodeURIComponent(name);
|
||||||
|
|
||||||
|
document.cookie = `${encodedName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/;`;
|
||||||
|
document.cookie = `${encodedName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; Secure;`;
|
||||||
|
|
||||||
// ---------- 1. Пытаемся установить безопасную куку ----------
|
// ---------- 1. Пытаемся установить безопасную куку ----------
|
||||||
let secureCookie = `${encodedName}=${cookieValue}; expires=${expires}; path=/; Secure; SameSite=Lax`;
|
let secureCookie = `${encodedName}=${cookieValue}; expires=${expires}; path=/; Secure; SameSite=Lax`;
|
||||||
document.cookie = secureCookie;
|
document.cookie = secureCookie;
|
||||||
@@ -45,6 +48,7 @@ export async function setCookie(name, value, days = 180) {
|
|||||||
return false; // безопасную куку установить не удалось
|
return false; // безопасную куку установить не удалось
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function getCookie(name) {
|
export async function getCookie(name) {
|
||||||
const cookies = document.cookie ? document.cookie.split('; ') : [];
|
const cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,19 @@ const predefinedSpecs = {
|
|||||||
async function getCookieData() {
|
async function getCookieData() {
|
||||||
accessData = await getCookie('toolbox_access');
|
accessData = await getCookie('toolbox_access');
|
||||||
userData = await getCookie('toolbox_user');
|
userData = await getCookie('toolbox_user');
|
||||||
|
await checkActiveUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkActiveUser() {
|
||||||
|
const activeCookie = loadFromStorage('active');
|
||||||
|
if (!activeCookie || !activeCookie.active || !activeCookie.datetime || Date.now() - activeCookie.datetime > 12 * 60 * 60 * 1000) {
|
||||||
|
const checkActive = await apiRequest('/user/check', { userId: userData.id });
|
||||||
|
if (checkActive.status === 'ok') {
|
||||||
|
saveToStorage('active', { active: true, datetime: Date.now() });
|
||||||
|
} else {
|
||||||
|
window.clientManager?.initLogout();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function openTab(event, tabId) {
|
async function openTab(event, tabId) {
|
||||||
@@ -7209,6 +7222,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
|
|
||||||
if (!accessData || !userData) {
|
if (!accessData || !userData) {
|
||||||
console.warn('Access data or user data not found');
|
console.warn('Access data or user data not found');
|
||||||
|
console.log(accessData, userData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+227
-38
@@ -1,4 +1,5 @@
|
|||||||
import { getCookie, deleteCookie } from '/static/js/cookies.js';
|
import { apiRequest } from './api.js';
|
||||||
|
import { getCookie, deleteCookie, setCookie } from './cookies.js';
|
||||||
|
|
||||||
class ClientManager {
|
class ClientManager {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -13,11 +14,9 @@ class ClientManager {
|
|||||||
this.userData = await getCookie('toolbox_user');
|
this.userData = await getCookie('toolbox_user');
|
||||||
this.accessData = await getCookie('toolbox_access');
|
this.accessData = await getCookie('toolbox_access');
|
||||||
|
|
||||||
|
|
||||||
if (!this.userData || !this.accessData) {
|
if (!this.userData || !this.accessData) {
|
||||||
console.warn('User data or access data not found in cookie');
|
console.warn('User data or access data not found in cookie');
|
||||||
this.clearUserCookie();
|
this.initLogout();
|
||||||
window.location.href = '/user/login';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Вставляем данные пользователя в DOM
|
// Вставляем данные пользователя в DOM
|
||||||
@@ -35,8 +34,7 @@ class ClientManager {
|
|||||||
|
|
||||||
renderUserInfo() {
|
renderUserInfo() {
|
||||||
if (!this.userData) {
|
if (!this.userData) {
|
||||||
// Если нет данных, показываем заглушку
|
this.initLogout();
|
||||||
this.renderFallbackUser();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,37 +62,6 @@ class ClientManager {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFallbackUser() {
|
|
||||||
const userCard = document.querySelector('.client-card');
|
|
||||||
if (userCard) {
|
|
||||||
userCard.innerHTML = `
|
|
||||||
<div class="d-flex align-items-center gap-3">
|
|
||||||
<div class="position-relative">
|
|
||||||
<img src="images/users/default.png"
|
|
||||||
alt="Гость"
|
|
||||||
class="client-avatar">
|
|
||||||
<span class="position-absolute bottom-0 end-0 bg-warning border border-2 border-white rounded-circle p-1"></span>
|
|
||||||
</div>
|
|
||||||
<div class="me-3">
|
|
||||||
<h6 class="client-name mb-1">Гость</h6>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<span class="badge bg-warning bg-opacity-10 text-warning fs-7 px-2 py-1 me-2">
|
|
||||||
<i class="bi bi-exclamation-triangle me-1"></i>
|
|
||||||
Не авторизован
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<a href="/login" class="btn btn-primary btn-sm">
|
|
||||||
<i class="bi bi-box-arrow-in-right me-1"></i>
|
|
||||||
Войти
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initLogoutHandler() {
|
initLogoutHandler() {
|
||||||
const logoutBtn = document.getElementById('clientLogoutBtn');
|
const logoutBtn = document.getElementById('clientLogoutBtn');
|
||||||
if (logoutBtn) {
|
if (logoutBtn) {
|
||||||
@@ -105,12 +72,18 @@ class ClientManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initLogout() {
|
||||||
|
const logoutBtn = document.getElementById('clientLogoutBtn');
|
||||||
|
if (logoutBtn) {
|
||||||
|
this.handleLogout(logoutBtn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleLogout(button) {
|
handleLogout(button) {
|
||||||
// Анимация нажатия
|
// Анимация нажатия
|
||||||
button.style.transform = 'scale(0.95)';
|
button.style.transform = 'scale(0.95)';
|
||||||
|
|
||||||
// Добавляем иконку загрузки
|
// Добавляем иконку загрузки
|
||||||
const originalContent = button.innerHTML;
|
|
||||||
button.innerHTML = `
|
button.innerHTML = `
|
||||||
<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
|
<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>
|
||||||
Выход...
|
Выход...
|
||||||
@@ -162,6 +135,220 @@ class ClientManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userProfile() {
|
||||||
|
const avatarBtn = document.getElementById('userProfile');
|
||||||
|
|
||||||
|
async function openEditUserModal(user = null) {
|
||||||
|
const isNew = !user;
|
||||||
|
const modalId = `profile-edit-user-modal`;
|
||||||
|
|
||||||
|
// Удаляем старую модалку, если есть
|
||||||
|
const existingModal = document.getElementById(modalId);
|
||||||
|
if (existingModal) {
|
||||||
|
existingModal.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
const modalHTML = `
|
||||||
|
<div class="modal fade" id="${modalId}" tabindex="-1" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">${isNew ? 'Добавить пользователя' : 'Редактировать пользователя'}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="${modalId}-form">
|
||||||
|
<div class="text-center mb-3">
|
||||||
|
<img src="${user?.photo || 'static/images/users/default.png'}"
|
||||||
|
alt="Фото пользователя"
|
||||||
|
class="rounded-circle border object-fit-cover"
|
||||||
|
width="100" height="100"
|
||||||
|
id="${modalId}-photo-preview"
|
||||||
|
onerror="this.src='static/images/users/default.png'">
|
||||||
|
<div class="mt-2">
|
||||||
|
<input type="file"
|
||||||
|
class="form-control form-control-sm"
|
||||||
|
id="${modalId}-photo-input"
|
||||||
|
accept="image/*"
|
||||||
|
style="display: none;">
|
||||||
|
<div class="btn-group btn-group-sm" role="group">
|
||||||
|
<button type="button" class="btn btn-outline-primary" id="${modalId}-change-photo-btn">
|
||||||
|
<i class="bi bi-upload"></i> Изменить
|
||||||
|
</button>
|
||||||
|
${user?.photo && !user.photo.includes('default.png') ? `
|
||||||
|
<button type="button" class="btn btn-outline-danger" id="${modalId}-remove-photo-btn">
|
||||||
|
<i class="bi bi-trash"></i> Удалить
|
||||||
|
</button>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="${modalId}-login" class="form-label">Логин *</label>
|
||||||
|
<input type="text" class="form-control" id="${modalId}-login"
|
||||||
|
value="${user?.login || ''}" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="${modalId}-username" class="form-label">Имя пользователя *</label>
|
||||||
|
<input type="text" class="form-control" id="${modalId}-username"
|
||||||
|
value="${user?.username || ''}" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="${modalId}-password" class="form-label">${isNew ? 'Пароль *' : 'Новый пароль'}</label>
|
||||||
|
<input type="password" class="form-control" id="${modalId}-password"
|
||||||
|
${isNew ? 'required' : ''}
|
||||||
|
placeholder="${isNew ? '' : 'Оставьте пустым, если не нужно менять'}">
|
||||||
|
${!isNew ? '<div class="form-text">Оставьте пустым, если не нужно менять пароль</div>' : ''}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
<div id="${modalId}-error-message" class="alert alert-danger mb-3" role="alert" hidden></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="${modalId}-save-btn">Сохранить</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.insertAdjacentHTML('beforeend', modalHTML);
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById(modalId));
|
||||||
|
let photoFile = null;
|
||||||
|
let removePhoto = false;
|
||||||
|
|
||||||
|
// Обработчики для фото
|
||||||
|
const changePhotoBtn = document.getElementById(`${modalId}-change-photo-btn`);
|
||||||
|
const photoInput = document.getElementById(`${modalId}-photo-input`);
|
||||||
|
const photoPreview = document.getElementById(`${modalId}-photo-preview`);
|
||||||
|
|
||||||
|
changePhotoBtn.addEventListener('click', () => {
|
||||||
|
photoInput.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
photoInput.addEventListener('change', (e) => {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
if (file.type.startsWith('image/')) {
|
||||||
|
photoFile = file;
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (e) => {
|
||||||
|
photoPreview.src = e.target.result;
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
removePhoto = false;
|
||||||
|
} else {
|
||||||
|
showConfirmationModal('Ошибка', 'Пожалуйста, выберите файл изображения', () => { });
|
||||||
|
photoInput.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (document.getElementById(`${modalId}-remove-photo-btn`)) {
|
||||||
|
document.getElementById(`${modalId}-remove-photo-btn`).addEventListener('click', () => {
|
||||||
|
photoPreview.src = 'static/images/users/default.png';
|
||||||
|
photoFile = null;
|
||||||
|
removePhoto = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработчик сохранения
|
||||||
|
document.getElementById(`${modalId}-save-btn`).addEventListener('click', async () => {
|
||||||
|
const form = document.getElementById(`${modalId}-form`);
|
||||||
|
if (!form.checkValidity()) {
|
||||||
|
form.reportValidity();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formUserData = {
|
||||||
|
login: document.getElementById(`${modalId}-login`).value.trim(),
|
||||||
|
username: document.getElementById(`${modalId}-username`).value.trim(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Добавляем пароль, если он указан
|
||||||
|
const password = document.getElementById(`${modalId}-password`).value;
|
||||||
|
if (password || isNew) {
|
||||||
|
formUserData.password = password || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Определяем действие
|
||||||
|
let action = isNew ? 'create' : 'update';
|
||||||
|
|
||||||
|
// Обработка фото
|
||||||
|
if (photoFile) {
|
||||||
|
if (photoFile.size > 5 * 1024 * 1024) {
|
||||||
|
showInfo('Фото больше 5 МБ, оно не подходит', 'warning');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formUserData.photo = await new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = () => resolve(reader.result);
|
||||||
|
reader.onerror = () => reject(new Error('Ошибка чтения файла'));
|
||||||
|
|
||||||
|
reader.readAsDataURL(photoFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if (removePhoto) {
|
||||||
|
formUserData.photo = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let changedUserData = {};
|
||||||
|
if (isNew) {
|
||||||
|
changedUserData = formUserData;
|
||||||
|
} else {
|
||||||
|
changedUserData = Object.keys(formUserData).reduce((acc, key) => {
|
||||||
|
if (formUserData[key] !== user[key]) {
|
||||||
|
acc[key] = formUserData[key];
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(changedUserData).length === 0) {
|
||||||
|
showInfo('Нет изменений', 'info');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем данные
|
||||||
|
if (!isNew) {
|
||||||
|
changedUserData.id = user.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await apiRequest('/user/', { action, userData: changedUserData, userId: user.id });
|
||||||
|
|
||||||
|
if (result && result.status === 'ok') {
|
||||||
|
const newUserData = await apiRequest('/user/', { userId: user.id }, 'get');
|
||||||
|
await setCookie('toolbox_user', JSON.stringify(newUserData));
|
||||||
|
const checkData = await getCookie('toolbox_user');
|
||||||
|
if (window.clientManager) {
|
||||||
|
window.clientManager.userData = newUserData;
|
||||||
|
window.clientManager.renderUserInfo();
|
||||||
|
}
|
||||||
|
if (modal) { modal.hide(); }
|
||||||
|
} else {
|
||||||
|
const errorMessageDiv = document.getElementById(`${modalId}-error-message`);
|
||||||
|
errorMessageDiv.textContent = result.message;
|
||||||
|
errorMessageDiv.hidden = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.show();
|
||||||
|
|
||||||
|
// Удаляем модалку после скрытия
|
||||||
|
modal._element.addEventListener('hidden.bs.modal', () => {
|
||||||
|
modal._element.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
avatarBtn.addEventListener('click', async () => {
|
||||||
|
await openEditUserModal(this.userData);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Инициализация при загрузке документа
|
// Инициализация при загрузке документа
|
||||||
@@ -174,6 +361,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
elements.forEach((el, index) => {
|
elements.forEach((el, index) => {
|
||||||
el.style.animationDelay = `${index * 0.1}s`;
|
el.style.animationDelay = `${index * 0.1}s`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.clientManager.userProfile();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Экспорт для использования в других модулях
|
// Экспорт для использования в других модулях
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<div class="client-card d-inline-block">
|
<div class="client-card d-inline-block">
|
||||||
<div class="d-flex align-items-center gap-3">
|
<div class="d-flex align-items-center gap-3">
|
||||||
<!-- Аватар с индикатором активности -->
|
<!-- Аватар с индикатором активности -->
|
||||||
<div class="position-relative clickable">
|
<div class="position-relative clickable" id="userProfile">
|
||||||
<img src="" alt="Загрузка..." class="client-avatar">
|
<img src="" alt="Загрузка..." class="client-avatar">
|
||||||
<span
|
<span
|
||||||
class="position-absolute bottom-0 end-0 bg-success border border-2 border-white rounded-circle p-1"></span>
|
class="position-absolute bottom-0 end-0 bg-success border border-2 border-white rounded-circle p-1"></span>
|
||||||
|
|||||||
Binary file not shown.
+31
-1
@@ -109,6 +109,20 @@ class UserHandler:
|
|||||||
else:
|
else:
|
||||||
userData["photo"] = "static/images/users/default.png"
|
userData["photo"] = "static/images/users/default.png"
|
||||||
deleteImage(user.photo)
|
deleteImage(user.photo)
|
||||||
|
if "login" in userData:
|
||||||
|
uniqueLogin = await CRUD.read(
|
||||||
|
select(User).where(User.login == userData["login"])
|
||||||
|
)
|
||||||
|
if uniqueLogin and uniqueLogin.id != user.id:
|
||||||
|
logger.error("Пользователь с таким логином уже существует")
|
||||||
|
return {"error": "Пользователь с таким логином уже существует"}
|
||||||
|
if "username" in userData:
|
||||||
|
uniqueUserName = await CRUD.read(
|
||||||
|
select(User).where(User.username == userData["username"])
|
||||||
|
)
|
||||||
|
if uniqueUserName and uniqueUserName.id != user.id:
|
||||||
|
logger.error("Пользователь с таким именем уже существует")
|
||||||
|
return {"error": "Пользователь с таким именем уже существует"}
|
||||||
try:
|
try:
|
||||||
userData.pop("id")
|
userData.pop("id")
|
||||||
editedUser = await user.edit(**userData)
|
editedUser = await user.edit(**userData)
|
||||||
@@ -156,7 +170,9 @@ class UserHandler:
|
|||||||
if not user:
|
if not user:
|
||||||
logger.error("Пользователь с таким id не найден")
|
logger.error("Пользователь с таким id не найден")
|
||||||
return {}
|
return {}
|
||||||
return user.toDict()
|
userdata = user.toDict()
|
||||||
|
userdata.pop("hashed_password")
|
||||||
|
return userdata
|
||||||
|
|
||||||
async def delete(id: int, user_id: int = None) -> dict:
|
async def delete(id: int, user_id: int = None) -> dict:
|
||||||
userRecordsCount = await StocksRecordsHandler.getUserRecords(id)
|
userRecordsCount = await StocksRecordsHandler.getUserRecords(id)
|
||||||
@@ -202,12 +218,26 @@ class UserHandler:
|
|||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
async def checkActive(id: int) -> bool:
|
||||||
|
query = select(User).where(User.id == id)
|
||||||
|
user = await CRUD.read(query)
|
||||||
|
if not user:
|
||||||
|
logger.error("Пользователь с таким id не найден")
|
||||||
|
return False
|
||||||
|
return user.is_active
|
||||||
|
|
||||||
async def auth(login: str, password: str) -> dict:
|
async def auth(login: str, password: str) -> dict:
|
||||||
query = select(User).where(User.login == login)
|
query = select(User).where(User.login == login)
|
||||||
user = await CRUD.read(query)
|
user = await CRUD.read(query)
|
||||||
if not user:
|
if not user:
|
||||||
logger.error(f"Пользователь с логином {login} не найден")
|
logger.error(f"Пользователь с логином {login} не найден")
|
||||||
return {}
|
return {}
|
||||||
|
if not user.is_active:
|
||||||
|
logger.error(f"Пользователь {user.username} не активен")
|
||||||
|
await ServiceRecordsHandler.add(
|
||||||
|
user.id, {"Пользователь не активен": user.username}
|
||||||
|
)
|
||||||
|
return {}
|
||||||
if not pwd_verify(password, user.hashed_password):
|
if not pwd_verify(password, user.hashed_password):
|
||||||
logger.error(f"Неверный пароль пользователя {user.username}")
|
logger.error(f"Неверный пароль пользователя {user.username}")
|
||||||
await ServiceRecordsHandler.add(
|
await ServiceRecordsHandler.add(
|
||||||
|
|||||||
Reference in New Issue
Block a user