deepsite / management /backends.py
coerxso's picture
Upload 73 files
3e8a166 verified
raw
history blame
3.93 kB
# 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