feat: add cmshopee authorization shadow routes

This commit is contained in:
QiuSW
2026-07-21 10:13:26 +08:00
parent 1af47d043e
commit b1fa2f13b9
8 changed files with 177 additions and 1 deletions
+24
View File
@@ -5,6 +5,10 @@ from .views import (
AnalyzeImagesView,
BalanceView,
ClientLatestReleaseView,
CmshopeeAnalyzeImagesView,
CmshopeeGenerateImageTaskDetailView,
CmshopeeGenerateImageTaskSubmitView,
CmshopeeGenerateTitleView,
DeviceHeartbeatView,
DeviceRegistrationView,
GenerateImageTaskDetailView,
@@ -48,18 +52,38 @@ urlpatterns = [
name="api-client-release-latest",
),
path("v1/generate/title", GenerateTitleView.as_view(), name="api-generate-title"),
path(
"v1/cmshopee/generate/title",
CmshopeeGenerateTitleView.as_view(),
name="api-cmshopee-generate-title",
),
path("v1/analyze/images", AnalyzeImagesView.as_view(), name="api-analyze-images"),
path(
"v1/cmshopee/analyze/images",
CmshopeeAnalyzeImagesView.as_view(),
name="api-cmshopee-analyze-images",
),
path("v1/generate/image", GenerateImageView.as_view(), name="api-generate-image"),
path(
"v1/generate/image/tasks",
GenerateImageTaskSubmitView.as_view(),
name="api-generate-image-task-submit",
),
path(
"v1/cmshopee/generate/image/tasks",
CmshopeeGenerateImageTaskSubmitView.as_view(),
name="api-cmshopee-generate-image-task-submit",
),
path(
"v1/generate/image/tasks/<uuid:task_id>",
GenerateImageTaskDetailView.as_view(),
name="api-generate-image-task-detail",
),
path(
"v1/cmshopee/generate/image/tasks/<uuid:task_id>",
CmshopeeGenerateImageTaskDetailView.as_view(),
name="api-cmshopee-generate-image-task-detail",
),
path("v1/recharge/create", RechargeCreateView.as_view(), name="api-recharge-create"),
path("v1/recharge/status", RechargeStatusView.as_view(), name="api-recharge-status"),
path(
+53
View File
@@ -1,6 +1,7 @@
import logging
from django.http import HttpResponse
from django.conf import settings
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
@@ -70,6 +71,7 @@ from apps.licensing.services import (
DeviceRegistrationError,
DeviceSessionValidationError,
create_migration_request,
evaluate_device_authorization,
record_device_heartbeat,
register_device,
resolve_optional_device_session,
@@ -77,6 +79,7 @@ from apps.licensing.services import (
from apps.licensing.models import MigrationRequest
logger = logging.getLogger(__name__)
authorization_logger = logging.getLogger("cmhub.licensing.authorization")
class ExternalApiView(APIView):
@@ -379,6 +382,56 @@ class GenerateImageTaskDetailView(ExternalApiView):
return Response(task_detail_response(task), status=status.HTTP_200_OK)
class CmshopeeShadowAuthorizationMixin:
product_code = "cmshopee"
def optional_client_device(self, request):
device = super().optional_client_device(request)
decision = evaluate_device_authorization(
user=request.user,
product_code=self.product_code,
device=device,
raw_credential_token=request.headers.get("X-Device-Credential", ""),
)
event = {
"event": "cmshopee_authorization_shadow",
"product_code": self.product_code,
"user_id": request.user.id,
"client_device_id": getattr(device, "id", None),
"credential_id": decision.credential_id,
"would_reject": decision.would_reject,
"would_reject_code": decision.code,
"shadow_mode": settings.CMSHOPEE_AUTHORIZATION_SHADOW_MODE,
}
authorization_logger.info(
"%s %s",
event["event"],
event,
extra={"cmshopee_authorization": event},
)
request.cmshopee_authorization = decision
return device
class CmshopeeGenerateTitleView(CmshopeeShadowAuthorizationMixin, GenerateTitleView):
pass
class CmshopeeAnalyzeImagesView(CmshopeeShadowAuthorizationMixin, AnalyzeImagesView):
pass
class CmshopeeGenerateImageTaskSubmitView(
CmshopeeShadowAuthorizationMixin,
GenerateImageTaskSubmitView,
):
pass
class CmshopeeGenerateImageTaskDetailView(GenerateImageTaskDetailView):
pass
class BalanceView(ExternalApiView):
def get(self, request):
balance = get_balance_snapshot(request.user)