from collections import defaultdict from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.parsers import MultiPartParser from rest_framework import status from django.utils.translation import gettext as _ from pingcap_sso.api.authentication import CsrfExemptSessionAuthentication from pingcap_sso.api.base import Endpoint from pingcap_sso.forms.contact_us import ( ContactUsEmergencyForm, ContactUsCommunicationForm, ContactUsCooperationForm, OfficialContactUsForm, CommunityContactUsForm, OfficialJointSolutionMutualCertificationForm, OfficialContactUsSmsCodeForm, ) from pingcap_sso.models import TiDBRelease, SecurityCode, CaptchaStore from pingcap_sso.exceptions import RateLimitError from pingcap_sso.utils.requests import get_client_ip from pingcap_sso.exceptions import CaptchaRequiredError class TiDBReleaseListEndpoint(Endpoint): permission_classes = (AllowAny, ) # TODO: add cache def get(self, request, *args, **kwargs): releases = TiDBRelease.objects.all().values_list('major_number', 'version') _data1 = defaultdict(list) for r in releases: _data1[r[0]].append(r[1]) data = [] for k, v in _data1.items(): data.append({ 'major_number': k, 'prefix': 'v{}'.format(k), 'children': sorted(v, reverse=True) }) data = sorted(data, key=lambda d: d['major_number'], reverse=True) return Response({ 'detail': _('success'), 'data': data }) class ValidateQualificationEndpoint(Endpoint): permission_classes = (IsAuthenticated, ) def get(self, request, *args, **kwargs): user = request.user company_info_is_completed = bool(user.company_name and user.job_title_code) phone_email_is_completed = bool(user.phone and user.email) return Response({ 'detail': _('success'), 'data': { 'company_info_is_completed': company_info_is_completed, 'phone_email_is_completed': phone_email_is_completed } }) class ContactUsCreateEndpoint(Endpoint): permission_classes = (IsAuthenticated, ) form_class = None def post(self, request, *args, **kwargs): user = request.user company_info_is_completed = bool(user.company_name and user.job_title_code) phone_email_is_completed = bool(user.phone and user.email) if not (company_info_is_completed and phone_email_is_completed): return Response({ 'detail': 'precondition required', 'data': { 'company_info_is_completed': company_info_is_completed, 'phone_email_is_completed': phone_email_is_completed } }, status=status.HTTP_428_PRECONDITION_REQUIRED) form = self.form_class(data=request.data, user=request.user) if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) form.save() return Response({ 'detail': _('success') }) class EmergencyCreateEndpoint(ContactUsCreateEndpoint): form_class = ContactUsEmergencyForm class CooperationCreateEndpoint(ContactUsCreateEndpoint): form_class = ContactUsCooperationForm class CommunicationCreateEndpoint(ContactUsCreateEndpoint): form_class = ContactUsCommunicationForm block_list = [ '38.22.89.106', '38.22.89.220', '38.22.93.17', '154.21.202.71', '38.22.89.51', '154.36.174.31', '154.36.174.87', '154.36.174.51', '154.36.174.42', '154.36.174.46', '154.36.174.208', '154.36.174.88', '154.36.174.172' ] class OfficialContactUsSmsCodeEndpoint(Endpoint): permission_classes = (AllowAny, ) authentication_classes = (CsrfExemptSessionAuthentication, ) def post(self, request, *args, **kwargs): forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '') for bi in block_list: if bi in forwarded_for: return Response(status=403) form = OfficialContactUsSmsCodeForm(data=request.data) try: if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) except CaptchaRequiredError: return Response({ 'detail': _('captcha required'), 'data': CaptchaStore.generate_challenge().to_frontend() }, status=428) try: SecurityCode.send_code( form.cleaned_data['phone'], channel=SecurityCode.DELIVER_BY_PHONE, scene=SecurityCode.SCENE_OFFICIAL_CONTACT_US, ) except RateLimitError: return Response({ 'detail': _('rate limit') }, status=429) else: return Response({'detail': _('success')}) class OfficialContactUsEndpoint(Endpoint): permission_classes = (AllowAny, ) authentication_classes = (CsrfExemptSessionAuthentication, ) def post(self, request, *args, **kwargs): form = OfficialContactUsForm( data=request.data, request=request, user=request.user ) if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) form.save() return Response({ 'detail': _('success') }) class OfficialJointSolutionMutualCertificationEndpoint(Endpoint): permission_classes = (AllowAny, ) authentication_classes = (CsrfExemptSessionAuthentication, ) parser_classes = (MultiPartParser, ) def post(self, request, *args, **kwargs): form = OfficialJointSolutionMutualCertificationForm( request, request.user, data=request.data, files=request.FILES ) if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) form.save() return Response({ 'detail': _('success') }) class CommunityContactUsEndpoint(Endpoint): permission_classes = (AllowAny, ) def post(self, request, *args, **kwargs): form = CommunityContactUsForm( data=request.data, request=request, user=request.user ) if not form.is_valid(): return Response({ 'detail': _('params error'), 'errors': form.errors }, status=400) form.save() return Response({ 'detail': _('success') })