deepsite / management /views.py
coerxso's picture
Upload 73 files
3e8a166 verified
raw
history blame
14.3 kB
# management/views.py
# -*- coding: utf-8 -*-
from django.utils import timezone
from rest_framework import generics, viewsets, status
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.views import APIView
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.tokens import RefreshToken
import datetime
from .models import (
CustomUser, Panel, MarzbanAdmin, License, SecurityToken, Plan, Subscription,
Payment, EndUser, PaymentMethod, PaymentSetting, PaymentDetail, TelegramUser
)
from .serializers import (
PanelSerializer, LicenseSerializer, MarzbanAdminSerializer, CustomUserSerializer,
SecurityTokenSerializer, PlanSerializer, SubscriptionSerializer,
ReceiptUploadSerializer, PaymentMethodSerializer, PaymentDetailSerializer,
EndUserPaymentDetailSerializer, AdminLevel3SubscriptionSerializer,
PurchaseSubscriptionForUserSerializer,
)
from .tasks import (
send_telegram_message, send_payment_receipt_to_admin,
send_payment_confirmation_to_user,
)
# --- Authentication Views ---
class CustomTokenObtainPairView(TokenObtainPairView):
def post(self, request, *args, **kwargs):
response = super().post(request, *args, **kwargs)
if response.status_code == 200:
user = CustomUser.objects.get(username=request.data['username'])
response.data['user_role'] = user.role
return response
class LogoutAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
try:
refresh_token = request.data["refresh_token"]
token = RefreshToken(refresh_token)
token.blacklist()
return Response({"message": "Successfully logged out."}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": "Invalid token or other error."}, status=status.HTTP_400_BAD_REQUEST)
# --- ADDED: Missing ViewSets ---
class PanelViewSet(viewsets.ModelViewSet):
serializer_class = PanelSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
return Panel.objects.filter(owner=self.request.user)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class LicenseViewSet(viewsets.ModelViewSet):
serializer_class = LicenseSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
user = self.request.user
if user.is_super_admin():
return License.objects.all()
return License.objects.filter(owner=user)
class MarzbanAdminViewSet(viewsets.ModelViewSet):
serializer_class = MarzbanAdminSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
try:
panel = Panel.objects.get(owner=self.request.user)
return MarzbanAdmin.objects.filter(panel=panel)
except Panel.DoesNotExist:
return MarzbanAdmin.objects.none()
class PlanViewSet(viewsets.ModelViewSet):
serializer_class = PlanSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
try:
panel = Panel.objects.get(owner=self.request.user)
return Plan.objects.filter(panel=panel)
except Panel.DoesNotExist:
return Plan.objects.none()
def perform_create(self, serializer):
try:
panel = Panel.objects.get(owner=self.request.user)
serializer.save(panel=panel)
except Panel.DoesNotExist:
return Response({"error": "You do not own a panel."}, status=status.HTTP_403_FORBIDDEN)
class EndUserViewSet(viewsets.ModelViewSet):
serializer_class = SubscriptionSerializer # A better serializer can be created for EndUser
permission_classes = [IsAuthenticated]
def get_queryset(self):
if self.request.user.role == 'AdminLevel3':
try:
panel = Panel.objects.get(owner=self.request.user)
return EndUser.objects.filter(panel=panel)
except Panel.DoesNotExist:
return EndUser.objects.none()
return EndUser.objects.none()
class SubscriptionViewSet(viewsets.ModelViewSet):
serializer_class = SubscriptionSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
user = self.request.user
if user.role == 'AdminLevel3':
try:
panel = Panel.objects.get(owner=user)
return Subscription.objects.filter(panel=panel)
except Panel.DoesNotExist:
return Subscription.objects.none()
elif user.role == 'EndUser':
try:
end_user = EndUser.objects.get(username=user.username)
return Subscription.objects.filter(end_user=end_user)
except EndUser.DoesNotExist:
return Subscription.objects.none()
return Subscription.objects.none()
class PaymentViewSet(viewsets.ModelViewSet):
serializer_class = ReceiptUploadSerializer # A better serializer can be created for listing
permission_classes = [IsAuthenticated]
def get_queryset(self):
user = self.request.user
if user.is_admin_level_3():
return Payment.objects.filter(admin=user)
return Payment.objects.none()
# --- Payment System Views ---
class PaymentMethodViewSet(viewsets.ModelViewSet):
queryset = PaymentMethod.objects.all()
serializer_class = PaymentMethodSerializer
permission_classes = [IsAuthenticated]
http_method_names = ['get', 'patch', 'put']
def get_queryset(self):
if self.request.user.is_authenticated and self.request.user.is_admin_level_2():
return PaymentMethod.objects.all()
return PaymentMethod.objects.none()
class PaymentDetailAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
if not request.user.is_admin_level_3():
return Response({'error': 'Permission denied.'}, status=status.HTTP_403_FORBIDDEN)
details, _ = PaymentDetail.objects.get_or_create(admin_level_3=request.user)
serializer = PaymentDetailSerializer(details)
return Response(serializer.data)
def put(self, request):
if not request.user.is_admin_level_3():
return Response({'error': 'Permission denied.'}, status=status.HTTP_403_FORBIDDEN)
details, _ = PaymentDetail.objects.get_or_create(admin_level_3=request.user)
serializer = PaymentDetailSerializer(details, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class EndUserPaymentOptionsAPIView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
if not request.user.role == 'EndUser':
return Response({'error': 'Permission denied.'}, status=status.HTTP_403_FORBIDDEN)
try:
end_user = EndUser.objects.get(username=request.user.username)
admin_level_3_user = end_user.panel.owner
payment_settings = PaymentSetting.objects.filter(admin_level_3=admin_level_3_user, is_active=True)
serializer = EndUserPaymentDetailSerializer(payment_settings, many=True)
return Response(serializer.data)
except EndUser.DoesNotExist:
return Response({'error': 'User not found.'}, status=status.HTTP_404_NOT_FOUND)
# --- Subscription Management ---
class AdminLevel3SubscriptionViewSet(viewsets.ModelViewSet):
serializer_class = AdminLevel3SubscriptionSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
if self.request.user.is_authenticated and self.request.user.role == 'AdminLevel3':
try:
return Subscription.objects.filter(panel__owner=self.request.user)
except Panel.DoesNotExist:
return Subscription.objects.none()
return Subscription.objects.none()
def perform_create(self, serializer):
serializer.save()
# FIXED: Logic for purchasing subscription
class PurchaseSubscriptionForUserAPIView(APIView):
serializer_class = PurchaseSubscriptionForUserSerializer
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
end_user_username = data.get('end_user_username')
plan_id = data.get('plan_id')
amount = data.get('amount')
try:
# The user making the request must be an EndUser
if request.user.role != 'EndUser':
return Response({'error': 'Only EndUsers can purchase subscriptions.'}, status=status.HTTP_403_FORBIDDEN)
# Get the panel of the user making the request
requester_end_user = EndUser.objects.get(username=request.user.username)
panel = requester_end_user.panel
admin_level_3_user = panel.owner
plan = Plan.objects.get(id=plan_id, panel=panel)
# Get or create the target end user within the same panel
target_end_user, _ = EndUser.objects.get_or_create(
username=end_user_username, defaults={'panel': panel}
)
subscription = Subscription.objects.create(
end_user=target_end_user,
plan=plan,
panel=panel,
status='pending',
)
payment = Payment.objects.create(
subscription=subscription,
admin=admin_level_3_user,
amount=amount,
status='pending',
)
return Response({
"message": "Subscription request created successfully. Please upload the receipt.",
"subscription_id": subscription.id,
"payment_token": payment.payment_token
}, status=status.HTTP_201_CREATED)
except EndUser.DoesNotExist:
return Response({'error': 'Requesting user profile not found.'}, status=status.HTTP_404_NOT_FOUND)
except Plan.DoesNotExist:
return Response({'error': 'Plan not found for your panel.'}, status=status.HTTP_404_NOT_FOUND)
except Exception as e:
return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
# --- Other Views ---
# ADDED: PaymentReceiptUploadAPIView (was missing)
class PaymentReceiptUploadAPIView(APIView):
permission_classes = [IsAuthenticated]
serializer_class = ReceiptUploadSerializer
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
try:
payment = Payment.objects.get(payment_token=serializer.validated_data['payment_token'])
# Update payment with receipt details
payment.receipt_image = serializer.validated_data.get('receipt_image')
payment.receipt_text = serializer.validated_data.get('receipt_text')
payment.save()
# Trigger celery task to notify admin
send_payment_receipt_to_admin.delay(payment.id)
return Response({"message": "Receipt uploaded successfully. Please wait for admin approval."}, status=status.HTTP_200_OK)
except Payment.DoesNotExist:
return Response({"error": "Invalid payment token."}, status=status.HTTP_404_NOT_FOUND)
# ADDED: GenerateTelegramTokenAPIView (was missing)
class GenerateTelegramTokenAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
user = request.user
expiration = timezone.now() + datetime.timedelta(minutes=5)
# This assumes a direct relation between CustomUser and a Marzban Admin ID
if not user.marzban_admin_id:
return Response({'error': 'User is not linked to a Marzban admin.'}, status=status.HTTP_400_BAD_REQUEST)
token, _ = SecurityToken.objects.update_or_create(
admin_id=str(user.marzban_admin_id),
defaults={'expiration_date': expiration}
)
return Response({'token': token.token})
class VerifyTelegramTokenAPIView(APIView):
# This view is for unauthenticated users (the bot) to verify a token
permission_classes = []
def post(self, request):
token_value = request.data.get('token')
chat_id = request.data.get('chat_id')
if not token_value or not chat_id:
return Response({'error': 'Token and chat_id are required.'}, status=status.HTTP_400_BAD_REQUEST)
try:
token = SecurityToken.objects.get(token=token_value, expiration_date__gt=timezone.now())
# Logic to find the main DB CustomUser and update their telegram_chat_id
user = CustomUser.objects.get(marzban_admin_id=token.admin_id)
# Assuming AdminLevel3 has a telegram_chat_id field
if hasattr(user, 'admin_level_3'):
user.admin_level_3.telegram_chat_id = chat_id
user.admin_level_3.save()
token.delete() # One-time use token
return Response({'message': 'Telegram account linked successfully.'})
except (SecurityToken.DoesNotExist, CustomUser.DoesNotExist):
return Response({'error': 'Invalid or expired token.'}, status=status.HTTP_400_BAD_REQUEST)
class PushSubscriptionAPIView(APIView):
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
# Implementation needed
return Response({'message': 'Subscription created successfully.'})
# ADDED: TelegramWebhookView (was in urls.py but missing here)
class TelegramWebhookView(APIView):
permission_classes = []
def post(self, request, bot_token):
# Your telegram bot logic here
# print(request.data)
return Response({'status': 'ok'})