Spaces:
Running
Running
# management/backends.py | |
# -*- coding: utf-8 -*- | |
import asyncio | |
import logging | |
from django.contrib.auth.backends import BaseBackend | |
from django.contrib.auth import get_user_model | |
from marzban_api.marzban_client import Marzban | |
from marzban_api.exceptions import AuthenticationError, MarzbanAPIError | |
from .models import MarzbanAdmin, MarzbanUser, Panel, Role | |
CustomUser = get_user_model() | |
logger = logging.getLogger(__name__) | |
class CustomMarzbanBackend(BaseBackend): | |
""" | |
بکاند احراز هویت که admin_id و اطلاعات ادمین را از دیتابیس مرزبان پیدا میکند. | |
""" | |
def authenticate(self, request, username=None, **kwargs): | |
if not username: | |
return None | |
try: | |
# 1. پیدا کردن admin_id از دیتابیس مرزبان | |
marzban_user = MarzbanUser.objects.using('marzban_db').get(username=username) | |
admin_id = marzban_user.admin_id | |
if not admin_id: | |
logger.warning(f"User {username} has no associated admin in Marzban DB.") | |
return None | |
# 2. پیدا کردن اطلاعات ادمین از دیتابیس مرزبان | |
try: | |
admin_obj = MarzbanAdmin.objects.using('marzban_db').get(id=admin_id) | |
except MarzbanAdmin.DoesNotExist: | |
logger.error(f"Admin with ID {admin_id} not found in Marzban DB.") | |
return None | |
admin_username = admin_obj.username | |
admin_password = admin_obj.password | |
# 3. لاگین به API مرزبان با مشخصات ادمین و تایید وجود کاربر | |
async def authenticate_with_marzban(): | |
# در این مرحله، آدرس پنل باید از یک مکان مشخص (مثلاً مدل Panel) خوانده شود. | |
# برای سادگی، فعلا یک آدرس پیشفرض در نظر میگیریم. | |
panel_address = 'http://your_marzban_panel_address.com' | |
try: | |
async with Marzban(admin_username, admin_password, panel_address) as marzban_client: | |
await marzban_client.login_admin() | |
await marzban_client.get_user_info(username) | |
# 4. ایجاد یا دریافت کاربر در دیتابیس لوکال و اختصاص نقش | |
user, created = CustomUser.objects.get_or_create(username=username) | |
if created: | |
user_role, _ = Role.objects.get_or_create(name=Role.USER) | |
user.role = user_role | |
user.save() | |
return user | |
except AuthenticationError as e: | |
logger.error(f"Marzban API authentication failed for admin {admin_username}: {e}") | |
return None | |
except MarzbanAPIError as e: | |
logger.error(f"User {username} not found in Marzban via admin {admin_username}: {e}") | |
return None | |
except Exception as e: | |
logger.error(f"An unknown error occurred during Marzban API authentication: {e}") | |
return None | |
authenticated_user = asyncio.run(authenticate_with_marzban()) | |
if authenticated_user: | |
return authenticated_user | |
except MarzbanUser.DoesNotExist: | |
logger.warning(f"User {username} not found in Marzban database.") | |
return None | |
except Exception as e: | |
logger.error(f"An unknown error occurred: {e}") | |
return None | |
def get_user(self, user_id): | |
try: | |
return CustomUser.objects.get(pk=user_id) | |
except CustomUser.DoesNotExist: | |
return None | |