From e53ef9baa9c0cbc0eb90b719da84ff33b003126c Mon Sep 17 00:00:00 2001 From: Shafqat Farhan Date: Thu, 18 Sep 2025 06:39:23 +0500 Subject: [PATCH 1/2] feat: Make endpoints unavailable --- ecommerce/coupons/views.py | 14 ++++++++++++ ecommerce/extensions/basket/views.py | 27 +++++++++++++++++++++++- ecommerce/extensions/iap/api/v1/views.py | 12 +++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/ecommerce/coupons/views.py b/ecommerce/coupons/views.py index 848654f939b..cf739612ce0 100644 --- a/ecommerce/coupons/views.py +++ b/ecommerce/coupons/views.py @@ -3,6 +3,7 @@ import logging import unicodecsv as csv +import waffle from django.contrib import messages from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied @@ -16,6 +17,7 @@ from django.views.generic import TemplateView, View from edx_rest_framework_extensions.permissions import LoginRedirectIfUnauthenticated from oscar.core.loading import get_class, get_model +from rest_framework import status from rest_framework.views import APIView from ecommerce.core.url_utils import absolute_redirect, get_ecommerce_url, get_lms_course_about_url @@ -158,6 +160,18 @@ def get(self, request): # pylint: disable=too-many-statements then applies the voucher and if the basket total is FREE places the order and enrolls the user in the course. """ + logger.info( + f"[CouponRedeemView] Request for user: {request.user.username}, " + f"referer: {request.META.get('HTTP_REFERER')}, " + f"client IP: {request.META.get('REMOTE_ADDR')}, " + f"and params: {request.get_full_path()}" + ) + + if waffle.flag_is_active(request, 'disable_ecommerce_service'): + return HttpResponse( + 'Service unavailable', status=status.HTTP_503_SERVICE_UNAVAILABLE + ) + template_name = 'coupons/_offer_error.html' code = request.GET.get('code') sku = request.GET.get('sku') diff --git a/ecommerce/extensions/basket/views.py b/ecommerce/extensions/basket/views.py index dbfec7e75fc..4a5f3e52e75 100644 --- a/ecommerce/extensions/basket/views.py +++ b/ecommerce/extensions/basket/views.py @@ -10,7 +10,7 @@ import dateutil.parser import waffle -from django.http import HttpResponseBadRequest, HttpResponseRedirect +from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseRedirect from django.shortcuts import render from django.urls import reverse from django.utils.html import escape @@ -24,6 +24,7 @@ from oscar.core.prices import Price from requests.exceptions import ConnectionError as ReqConnectionError from requests.exceptions import RequestException, Timeout +from rest_framework import status from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView @@ -417,6 +418,18 @@ class BasketAddItemsView(BasketLogicMixin, APIView): permission_classes = (LoginRedirectIfUnauthenticated,) def get(self, request): + logger.info( + f"[BasketAddItemsView] Request for user: {request.user.username}, " + f"referer: {request.META.get('HTTP_REFERER')}, " + f"client IP: {request.META.get('REMOTE_ADDR')}, " + f"and params: {request.get_full_path()}" + ) + + if waffle.flag_is_active(request, 'disable_ecommerce_service'): + return HttpResponse( + 'Service unavailable', status=status.HTTP_503_SERVICE_UNAVAILABLE + ) + # Send time when this view is called - https://openedx.atlassian.net/browse/REV-984 properties = {'emitted_at': time.time()} track_segment_event(request.site, request.user, 'Basket Add Items View Called', properties) @@ -818,6 +831,18 @@ class PaymentApiView(PaymentApiLogicMixin, APIView): permission_classes = (IsAuthenticated,) def get(self, request): # pylint: disable=unused-argument + logger.info( + f"[PaymentApiView] Request for user: {request.user.username}, " + f"referer: {request.META.get('HTTP_REFERER')}, " + f"client IP: {request.META.get('REMOTE_ADDR')}, " + f"and params: {request.get_full_path()}" + ) + + if waffle.flag_is_active(request, 'disable_ecommerce_service'): + return JsonResponse( + {'error': 'Service unavailable'}, status=status.HTTP_503_SERVICE_UNAVAILABLE + ) + basket = request.basket try: diff --git a/ecommerce/extensions/iap/api/v1/views.py b/ecommerce/extensions/iap/api/v1/views.py index 87033d4a4a6..c8cd4b33293 100644 --- a/ecommerce/extensions/iap/api/v1/views.py +++ b/ecommerce/extensions/iap/api/v1/views.py @@ -111,6 +111,18 @@ class MobileBasketAddItemsView(BasketLogicMixin, APIView): permission_classes = (LoginRedirectIfUnauthenticated,) def get(self, request): + logger.info( + f"[MobileBasketAddItemsView] Request for user: {request.user.username}, " + f"referer: {request.META.get('HTTP_REFERER')}, " + f"client IP: {request.META.get('REMOTE_ADDR')}, " + f"and params: {request.get_full_path()}" + ) + + if waffle.flag_is_active(request, 'disable_ecommerce_service'): + return JsonResponse( + {'error': 'Service unavailable'}, status=status.HTTP_503_SERVICE_UNAVAILABLE + ) + # Send time when this view is called - https://openedx.atlassian.net/browse/REV-984 track_segment_event(request.site, request.user, SEGMENT_MOBILE_BASKET_ADD, {'emitted_at': time.time()}) From ccc37a9ad5ca222b2bea120e2cb6a7b0413cd8dd Mon Sep 17 00:00:00 2001 From: Shafqat Farhan Date: Thu, 18 Sep 2025 07:25:58 +0500 Subject: [PATCH 2/2] fix: Fixed pylint errors --- ecommerce/extensions/basket/views.py | 7 ++++--- pylintrc | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ecommerce/extensions/basket/views.py b/ecommerce/extensions/basket/views.py index 4a5f3e52e75..66cfe363055 100644 --- a/ecommerce/extensions/basket/views.py +++ b/ecommerce/extensions/basket/views.py @@ -24,7 +24,7 @@ from oscar.core.prices import Price from requests.exceptions import ConnectionError as ReqConnectionError from requests.exceptions import RequestException, Timeout -from rest_framework import status +from rest_framework import status as response_status_codes from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView @@ -427,7 +427,7 @@ def get(self, request): if waffle.flag_is_active(request, 'disable_ecommerce_service'): return HttpResponse( - 'Service unavailable', status=status.HTTP_503_SERVICE_UNAVAILABLE + 'Service unavailable', status=response_status_codes.HTTP_503_SERVICE_UNAVAILABLE ) # Send time when this view is called - https://openedx.atlassian.net/browse/REV-984 @@ -840,7 +840,8 @@ def get(self, request): # pylint: disable=unused-argument if waffle.flag_is_active(request, 'disable_ecommerce_service'): return JsonResponse( - {'error': 'Service unavailable'}, status=status.HTTP_503_SERVICE_UNAVAILABLE + {'error': 'Service unavailable'}, + status=response_status_codes.HTTP_503_SERVICE_UNAVAILABLE ) basket = request.basket diff --git a/pylintrc b/pylintrc index 7206c5f1f05..cb29ca34409 100644 --- a/pylintrc +++ b/pylintrc @@ -86,7 +86,7 @@ disable= # the pylint import errors, since they conflict at times. wrong-import-order, ungrouped-imports, - + logging-fstring-interpolation, [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs