1
1
package sfe
2
2
3
3
import (
4
+ "context"
4
5
"encoding/json"
5
6
"errors"
6
7
"fmt"
@@ -269,56 +270,39 @@ func makeInitialComment(organization, useCase, tier string) string {
269
270
)
270
271
}
271
272
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
+ }
288
290
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 ) {
293
291
return client .CreateTicket (
294
292
requesterEmail ,
295
- makeSubject (rl .CertificatesPerDomain , organization ),
293
+ // The stripped form of the rateLimitField value must be used here.
294
+ makeSubject (limit , organization ),
296
295
makeInitialComment (organization , useCase , tier ),
297
296
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 ,
299
301
ReviewStatusFieldName : reviewStatusDefault ,
300
302
OrganizationFieldName : organization ,
301
- TierFieldName : tier ,
302
303
RegisteredDomainFieldName : registeredDomain ,
303
304
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 ,
322
306
},
323
307
)
324
308
}
@@ -489,12 +473,13 @@ func (sfe *SelfServiceFrontEndImpl) makeOverrideRequestFormHandler(formHTML temp
489
473
func (sfe * SelfServiceFrontEndImpl ) overrideRequestHandler (w http.ResponseWriter , formHTML template.HTML , rateLimit , displayRateLimit string ) {
490
474
setOverrideRequestFormHeaders (w )
491
475
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 ,
498
483
})
499
484
}
500
485
@@ -542,10 +527,16 @@ func (sfe *SelfServiceFrontEndImpl) validateOverrideFieldHandler(w http.Response
542
527
}
543
528
}
544
529
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 )
549
540
}
550
541
551
542
type overrideRequest struct {
@@ -555,9 +546,11 @@ type overrideRequest struct {
555
546
556
547
// submitOverrideRequestHandler handles the submission of override requests. It
557
548
// 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.
561
554
//
562
555
// The JavaScript frontend is configured to validate the form fields twice: once
563
556
// when the requester inputs data, and once more just before submitting the
@@ -566,7 +559,6 @@ type overrideRequest struct {
566
559
// submitting (malformed) requests directly to this endpoint.
567
560
func (sfe * SelfServiceFrontEndImpl ) submitOverrideRequestHandler (w http.ResponseWriter , r * http.Request ) {
568
561
var refundLimits func ()
569
- var submissionSuccess bool
570
562
if sfe .limiter != nil && sfe .txnBuilder != nil {
571
563
requesterIP , err := web .ExtractRequesterIP (r )
572
564
if err != nil {
@@ -608,8 +600,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
608
600
}
609
601
}
610
602
}
603
+ var created bool
604
+ var accepted bool
611
605
defer func () {
612
- if ! submissionSuccess && refundLimits != nil {
606
+ if ! created && ! accepted && refundLimits != nil {
613
607
refundLimits ()
614
608
}
615
609
}()
@@ -635,7 +629,7 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
635
629
return val , nil
636
630
}
637
631
638
- var baseFields = make (map [string ]string )
632
+ var validFields = make (map [string ]string )
639
633
for _ , name := range []string {
640
634
// Note: not all of these fields will be included in the Zendesk ticket,
641
635
// but they are all required for the submission to be considered valid.
@@ -653,7 +647,24 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
653
647
http .Error (w , err .Error (), http .StatusBadRequest )
654
648
return
655
649
}
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
657
668
}
658
669
659
670
switch req .RateLimit {
@@ -663,22 +674,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
663
674
http .Error (w , err .Error (), http .StatusBadRequest )
664
675
return
665
676
}
677
+ validFields [AccountURIFieldName ] = accountURI
666
678
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 )
682
681
}
683
682
684
683
case rl .CertificatesPerDomainPerAccount .String ():
@@ -687,22 +686,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
687
686
http .Error (w , err .Error (), http .StatusBadRequest )
688
687
return
689
688
}
689
+ validFields [AccountURIFieldName ] = accountURI
690
690
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 )
706
693
}
707
694
708
695
case rl .CertificatesPerDomain .String () + perDNSNameSuffix :
@@ -711,23 +698,10 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
711
698
http .Error (w , err .Error (), http .StatusBadRequest )
712
699
return
713
700
}
701
+ validFields [RegisteredDomainFieldName ] = registeredDomain
714
702
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 )
731
705
}
732
706
733
707
case rl .CertificatesPerDomain .String () + perIPSuffix :
@@ -736,32 +710,19 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
736
710
http .Error (w , err .Error (), http .StatusBadRequest )
737
711
return
738
712
}
713
+ validFields [IPAddressFieldName ] = ipAddress
739
714
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 )
756
717
}
757
718
758
719
default :
759
720
http .Error (w , "unknown rate limit" , http .StatusBadRequest )
760
721
return
761
722
}
762
723
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 ]}})
765
726
if err != nil {
766
727
sfe .log .Errf ("failed to send contact to email service: %s" , err )
767
728
}
@@ -770,6 +731,33 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
770
731
// TODO(#8362): If FundraisingFieldName value is true, use the Salesforce
771
732
// API to create a new Lead record with the provided information.
772
733
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 )
775
763
}
0 commit comments