diff --git a/app/main.py b/app/main.py index 5959b03..6a0cc3a 100644 --- a/app/main.py +++ b/app/main.py @@ -218,26 +218,33 @@ async def _process_callback_query(cq: dict): if approve_match: days = int(approve_match.group(1)) - password = _generate_password() username = pending.email + expires = _dtc.datetime.now(_dtc.timezone.utc) + _dtc.timedelta(days=days) + parts = pending.name.strip().split(None, 1) - if db.scalar(select(User).where(User.username == username)): - import secrets as _sec - username = pending.email.split("@")[0] + "_" + _sec.token_hex(3) + existing_user = db.scalar(select(User).where(User.username == username)) + is_renewal = existing_user is not None - expires = _dtc.datetime.now(_dtc.timezone.utc) + _dtc.timedelta(days=days) - parts = pending.name.strip().split(None, 1) - new_user = User( - username=username, - password_hash=hash_password(password), - expires_at=expires, - active=True, - is_admin=False, - first_name=parts[0] if parts else "", - last_name=parts[1] if len(parts) > 1 else "", - ) - db.add(new_user) - db.flush() + if is_renewal: + password = None + existing_user.expires_at = expires + existing_user.active = True + target_user = existing_user + db.flush() + else: + password = _generate_password() + new_user = User( + username=username, + password_hash=hash_password(password), + expires_at=expires, + active=True, + is_admin=False, + first_name=parts[0] if parts else "", + last_name=parts[1] if len(parts) > 1 else "", + ) + db.add(new_user) + db.flush() + target_user = new_user if products: from sqlalchemy import func as _func2 @@ -247,8 +254,13 @@ async def _process_callback_query(cq: dict): Service.active == True, ) ).all() + existing_svc_ids = ( + {a.service_id for a in db.scalars(select(UserServiceAccess).where(UserServiceAccess.user_id == target_user.id)).all()} + if is_renewal else set() + ) for svc in matched: - db.add(UserServiceAccess(user_id=new_user.id, service_id=svc.id)) + if svc.id not in existing_svc_ids: + db.add(UserServiceAccess(user_id=target_user.id, service_id=svc.id)) db.commit() @@ -261,6 +273,16 @@ async def _process_callback_query(cq: dict): ) day_word = "день" if days == 1 else ("дня" if days < 5 else "дней") + email_action = "продлён" if is_renewal else "предоставлен" + email_subject = ("Продление доступа к Инфраструктурному полигону MONT" + if is_renewal else + "Доступ к Инфраструктурному полигону MONT") + email_subhead = "Ваш доступ продлён" if is_renewal else "Ваш запрос одобрен" + cred_row = ( + f'