Spaces:
Running
Running
File size: 3,929 Bytes
3e8a166 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# 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
|