11package sfe
22
33import (
4+ "context"
45 "encoding/json"
56 "errors"
67 "fmt"
@@ -269,56 +270,39 @@ func makeInitialComment(organization, useCase, tier string) string {
269270 )
270271}
271272
272- // createNewOrdersPerAccountOverrideTicket creates a new Zendesk ticket for a
273- // NewOrdersPerAccount override request. All fields are required.
274- func createNewOrdersPerAccountOverrideTicket (client * zendesk.Client , requesterEmail , useCase , organization , tier , accountID string ) (int64 , error ) {
275- return client .CreateTicket (
276- requesterEmail ,
277- makeSubject (rl .NewOrdersPerAccount , organization ),
278- makeInitialComment (organization , useCase , tier ),
279- map [string ]string {
280- RateLimitFieldName : rl .NewOrdersPerAccount .String (),
281- ReviewStatusFieldName : reviewStatusDefault ,
282- OrganizationFieldName : organization ,
283- TierFieldName : tier ,
284- AccountURIFieldName : accountID ,
285- },
286- )
287- }
273+ // createOverrideRequestZendeskTicket creates a new Zendesk ticket for manual
274+ // review of a rate limit override request. It returns the ID of the created
275+ // ticket or an error.
276+ func createOverrideRequestZendeskTicket (client * zendesk.Client , rateLimit , requesterEmail , useCase , organization , tier , accountURI , registeredDomain , ipAddress string ) (int64 , error ) {
277+ // Some rateLimitField values include suffixes to indicate whether an
278+ // accountURI, registeredDomain, or ipAddress is expected.
279+ limitStr := strings .TrimSuffix (strings .TrimSuffix (rateLimit , perDNSNameSuffix ), perIPSuffix )
280+ limit , ok := rl .StringToName [limitStr ]
281+ if ! ok {
282+ // This should never happen, it indicates a bug in our validation.
283+ return 0 , errors .New ("invalid rate limit prevented ticket creation" )
284+ }
285+
286+ if registeredDomain == "" && ipAddress == "" && accountURI == "" {
287+ // This should never happen, it indicates a bug in our validation.
288+ return 0 , errors .New ("one of accountURI, registeredDomain, or ipAddress must be provided" )
289+ }
288290
289- // createCertificatesPerDomainOverrideTicket creates a new Zendesk ticket for a
290- // CertificatesPerDomain override request. Only registeredDomain or ipAddress
291- // should be provided, not both. All other fields are required.
292- func createCertificatesPerDomainOverrideTicket (client * zendesk.Client , requesterEmail , useCase , organization , tier , registeredDomain , ipAddress string ) (int64 , error ) {
293291 return client .CreateTicket (
294292 requesterEmail ,
295- makeSubject (rl .CertificatesPerDomain , organization ),
293+ // The stripped form of the rateLimitField value must be used here.
294+ makeSubject (limit , organization ),
296295 makeInitialComment (organization , useCase , tier ),
297296 map [string ]string {
298- RateLimitFieldName : rl .CertificatesPerDomain .String (),
297+ // The original rateLimitField value must be used here, the
298+ // overridesimporter depends on the suffixes for validation.
299+ RateLimitFieldName : rateLimit ,
300+ TierFieldName : tier ,
299301 ReviewStatusFieldName : reviewStatusDefault ,
300302 OrganizationFieldName : organization ,
301- TierFieldName : tier ,
302303 RegisteredDomainFieldName : registeredDomain ,
303304 IPAddressFieldName : ipAddress ,
304- },
305- )
306- }
307-
308- // createCertificatesPerDomainPerAccountOverrideTicket creates a new Zendesk
309- // ticket for a CertificatesPerDomainPerAccount override request. All fields are
310- // required.
311- func createCertificatesPerDomainPerAccountOverrideTicket (client * zendesk.Client , requesterEmail , useCase , organization , tier , accountID string ) (int64 , error ) {
312- return client .CreateTicket (
313- requesterEmail ,
314- makeSubject (rl .CertificatesPerDomainPerAccount , organization ),
315- makeInitialComment (organization , useCase , tier ),
316- map [string ]string {
317- RateLimitFieldName : rl .CertificatesPerDomainPerAccount .String (),
318- ReviewStatusFieldName : reviewStatusDefault ,
319- OrganizationFieldName : organization ,
320- TierFieldName : tier ,
321- AccountURIFieldName : accountID ,
305+ AccountURIFieldName : accountURI ,
322306 },
323307 )
324308}
@@ -489,12 +473,13 @@ func (sfe *SelfServiceFrontEndImpl) makeOverrideRequestFormHandler(formHTML temp
489473func (sfe * SelfServiceFrontEndImpl ) overrideRequestHandler (w http.ResponseWriter , formHTML template.HTML , rateLimit , displayRateLimit string ) {
490474 setOverrideRequestFormHeaders (w )
491475 sfe .renderTemplate (w , "overrideForm.html" , map [string ]any {
492- "FormHTML" : formHTML ,
493- "RateLimit" : rateLimit ,
494- "DisplayRateLimit" : displayRateLimit ,
495- "ValidateFieldPath" : overridesValidateField ,
496- "SubmitRequestPath" : overridesSubmitRequest ,
497- "SubmitSuccessPath" : overridesSubmitSuccess ,
476+ "FormHTML" : formHTML ,
477+ "RateLimit" : rateLimit ,
478+ "DisplayRateLimit" : displayRateLimit ,
479+ "ValidateFieldPath" : overridesValidateField ,
480+ "SubmitRequestPath" : overridesSubmitRequest ,
481+ "CreatedSuccessPath" : overridesCreatedSuccess ,
482+ "AcceptedSuccessPath" : overridesAcceptedSuccess ,
498483 })
499484}
500485
@@ -542,10 +527,16 @@ func (sfe *SelfServiceFrontEndImpl) validateOverrideFieldHandler(w http.Response
542527 }
543528}
544529
545- // overrideSuccessHandler renders the success page after a successful override
546- // request submission.
547- func (sfe * SelfServiceFrontEndImpl ) overrideSuccessHandler (w http.ResponseWriter , r * http.Request ) {
548- sfe .renderTemplate (w , "overrideSuccess.html" , nil )
530+ // overrideCreatedSuccessHandler renders the success page after a successful
531+ // override request submission which was automatically approved.
532+ func (sfe * SelfServiceFrontEndImpl ) overrideCreatedSuccessHandler (w http.ResponseWriter , r * http.Request ) {
533+ sfe .renderTemplate (w , "overrideCreatedSuccess.html" , nil )
534+ }
535+
536+ // overrideAcceptedSuccessHandler renders the success page after a successful
537+ // override request submission which created a Zendesk ticket for manual review.
538+ func (sfe * SelfServiceFrontEndImpl ) overrideAcceptedSuccessHandler (w http.ResponseWriter , r * http.Request ) {
539+ sfe .renderTemplate (w , "overrideAcceptedSuccess.html" , nil )
549540}
550541
551542type overrideRequest struct {
@@ -555,9 +546,11 @@ type overrideRequest struct {
555546
556547// submitOverrideRequestHandler handles the submission of override requests. It
557548// expects a POST request with a JSON payload (overrideRequest). It validates
558- // each of the form fields and creates a Zendesk ticket based on the specified
559- // rate limit. It returns a 200 OK response on success, or an error response if
560- // the request is invalid or if ticket creation fails.
549+ // each of the form fields and either:
550+ //
551+ // a. auto-approves the override request and returns 201 Created, or
552+ // b. creates a Zendesk ticket for manual review, and returns 202 Accepted, or
553+ // c. encounters an error and returns an appropriate 4xx or 5xx status code.
561554//
562555// The JavaScript frontend is configured to validate the form fields twice: once
563556// when the requester inputs data, and once more just before submitting the
@@ -566,7 +559,6 @@ type overrideRequest struct {
566559// submitting (malformed) requests directly to this endpoint.
567560func (sfe * SelfServiceFrontEndImpl ) submitOverrideRequestHandler (w http.ResponseWriter , r * http.Request ) {
568561 var refundLimits func ()
569- var submissionSuccess bool
570562 if sfe .limiter != nil && sfe .txnBuilder != nil {
571563 requesterIP , err := web .ExtractRequesterIP (r )
572564 if err != nil {
@@ -608,8 +600,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
608600 }
609601 }
610602 }
603+ var created bool
604+ var accepted bool
611605 defer func () {
612- if ! submissionSuccess && refundLimits != nil {
606+ if ! created && ! accepted && refundLimits != nil {
613607 refundLimits ()
614608 }
615609 }()
@@ -635,7 +629,7 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
635629 return val , nil
636630 }
637631
638- var baseFields = make (map [string ]string )
632+ var validFields = make (map [string ]string )
639633 for _ , name := range []string {
640634 // Note: not all of these fields will be included in the Zendesk ticket,
641635 // but they are all required for the submission to be considered valid.
@@ -653,7 +647,24 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
653647 http .Error (w , err .Error (), http .StatusBadRequest )
654648 return
655649 }
656- baseFields [name ] = val
650+ validFields [name ] = val
651+ }
652+
653+ autoApproveOverride := func (ctx context.Context , rateLimitFieldValue string , fields map [string ]string ) bool {
654+ if ! sfe .autoApproveOverrides {
655+ return false
656+ }
657+ req , _ , err := makeAddOverrideRequest (rateLimitFieldValue , fields )
658+ if err != nil {
659+ sfe .log .Errf ("failed to create automatically approved override request: %s" , err )
660+ return false
661+ }
662+ resp , err := sfe .ra .AddRateLimitOverride (ctx , req )
663+ if err != nil {
664+ sfe .log .Errf ("failed to create automatically approved override request: %s" , err )
665+ return false
666+ }
667+ return resp .Enabled
657668 }
658669
659670 switch req .RateLimit {
@@ -663,22 +674,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
663674 http .Error (w , err .Error (), http .StatusBadRequest )
664675 return
665676 }
677+ validFields [AccountURIFieldName ] = accountURI
666678
667- // TODO(#8360): Skip ticket creation and insert an override for
668- // overrides matching the first N tiers of this limit.
669-
670- _ , err = createNewOrdersPerAccountOverrideTicket (
671- sfe .zendeskClient ,
672- baseFields [emailAddressFieldName ],
673- baseFields [useCaseFieldName ],
674- baseFields [OrganizationFieldName ],
675- baseFields [TierFieldName ],
676- accountURI ,
677- )
678- if err != nil {
679- sfe .log .Errf ("failed to create override request ticket: %s" , err )
680- http .Error (w , "failed to create override request ticket" , http .StatusInternalServerError )
681- return
679+ if validFields [TierFieldName ] == newOrdersPerAccountTierOptions [0 ] {
680+ created = autoApproveOverride (r .Context (), req .RateLimit , validFields )
682681 }
683682
684683 case rl .CertificatesPerDomainPerAccount .String ():
@@ -687,22 +686,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
687686 http .Error (w , err .Error (), http .StatusBadRequest )
688687 return
689688 }
689+ validFields [AccountURIFieldName ] = accountURI
690690
691- // TODO(#8360): Skip ticket creation and insert an override for
692- // overrides matching the first N tiers of this limit.
693-
694- _ , err = createCertificatesPerDomainPerAccountOverrideTicket (
695- sfe .zendeskClient ,
696- baseFields [emailAddressFieldName ],
697- baseFields [useCaseFieldName ],
698- baseFields [OrganizationFieldName ],
699- baseFields [TierFieldName ],
700- accountURI ,
701- )
702- if err != nil {
703- sfe .log .Errf ("failed to create override request ticket: %s" , err )
704- http .Error (w , "failed to create override request ticket" , http .StatusInternalServerError )
705- return
691+ if validFields [TierFieldName ] == certificatesPerDomainPerAccountTierOptions [0 ] {
692+ created = autoApproveOverride (r .Context (), req .RateLimit , validFields )
706693 }
707694
708695 case rl .CertificatesPerDomain .String () + perDNSNameSuffix :
@@ -711,23 +698,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
711698 http .Error (w , err .Error (), http .StatusBadRequest )
712699 return
713700 }
701+ validFields [RegisteredDomainFieldName ] = registeredDomain
714702
715- // TODO(#8360): Skip ticket creation and insert an override for
716- // overrides matching the first N tiers of this limit.
717-
718- _ , err = createCertificatesPerDomainOverrideTicket (
719- sfe .zendeskClient ,
720- baseFields [emailAddressFieldName ],
721- baseFields [useCaseFieldName ],
722- baseFields [OrganizationFieldName ],
723- baseFields [TierFieldName ],
724- registeredDomain ,
725- "" ,
726- )
727- if err != nil {
728- sfe .log .Errf ("failed to create override request ticket: %s" , err )
729- http .Error (w , "failed to create override request ticket" , http .StatusInternalServerError )
730- return
703+ if validFields [TierFieldName ] == certificatesPerDomainTierOptions [0 ] {
704+ created = autoApproveOverride (r .Context (), req .RateLimit , validFields )
731705 }
732706
733707 case rl .CertificatesPerDomain .String () + perIPSuffix :
@@ -736,32 +710,19 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
736710 http .Error (w , err .Error (), http .StatusBadRequest )
737711 return
738712 }
713+ validFields [IPAddressFieldName ] = ipAddress
739714
740- // TODO(#8360): Skip ticket creation and insert an override for
741- // overrides matching the first N tiers of this limit.
742-
743- _ , err = createCertificatesPerDomainOverrideTicket (
744- sfe .zendeskClient ,
745- baseFields [emailAddressFieldName ],
746- baseFields [useCaseFieldName ],
747- baseFields [OrganizationFieldName ],
748- baseFields [TierFieldName ],
749- "" ,
750- ipAddress ,
751- )
752- if err != nil {
753- sfe .log .Errf ("failed to create override request ticket: %s" , err )
754- http .Error (w , "failed to create override request ticket" , http .StatusInternalServerError )
755- return
715+ if validFields [TierFieldName ] == certificatesPerDomainTierOptions [0 ] {
716+ created = autoApproveOverride (r .Context (), req .RateLimit , validFields )
756717 }
757718
758719 default :
759720 http .Error (w , "unknown rate limit" , http .StatusBadRequest )
760721 return
761722 }
762723
763- if sfe .ee != nil && baseFields [fundraisingFieldName ] == fundraisingYesOption {
764- _ , err := sfe .ee .SendContacts (r .Context (), & emailpb.SendContactsRequest {Emails : []string {baseFields [emailAddressFieldName ]}})
724+ if sfe .ee != nil && validFields [fundraisingFieldName ] == fundraisingYesOption {
725+ _ , err := sfe .ee .SendContacts (r .Context (), & emailpb.SendContactsRequest {Emails : []string {validFields [emailAddressFieldName ]}})
765726 if err != nil {
766727 sfe .log .Errf ("failed to send contact to email service: %s" , err )
767728 }
@@ -770,6 +731,33 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
770731 // TODO(#8362): If FundraisingFieldName value is true, use the Salesforce
771732 // API to create a new Lead record with the provided information.
772733
773- submissionSuccess = true
774- w .WriteHeader (http .StatusOK )
734+ if created {
735+ sfe .log .Infof ("automatically approved override request for %s" , validFields [OrganizationFieldName ])
736+ w .WriteHeader (http .StatusCreated )
737+ return
738+ }
739+
740+ ticketID , err := createOverrideRequestZendeskTicket (
741+ sfe .zendeskClient ,
742+ req .RateLimit ,
743+ validFields [emailAddressFieldName ],
744+ validFields [useCaseFieldName ],
745+ validFields [OrganizationFieldName ],
746+ validFields [TierFieldName ],
747+
748+ // Only one of these will be non-empty, depending on the
749+ // rateLimitField value.
750+ validFields [AccountURIFieldName ],
751+ validFields [RegisteredDomainFieldName ],
752+ validFields [IPAddressFieldName ],
753+ )
754+ if err != nil {
755+ sfe .log .Errf ("failed to create override request Zendesk ticket: %s" , err )
756+ http .Error (w , "failed to create support ticket" , http .StatusInternalServerError )
757+ return
758+ }
759+
760+ accepted = true
761+ sfe .log .Infof ("created override request Zendesk ticket %d" , ticketID )
762+ w .WriteHeader (http .StatusAccepted )
775763}
0 commit comments