@@ -2,6 +2,7 @@ package sfe
22
33import (
44 "encoding/json"
5+ "errors"
56 "fmt"
67 "html/template"
78 "net/http"
@@ -10,11 +11,13 @@ import (
1011 "strconv"
1112 "strings"
1213
14+ berrors "github.com/letsencrypt/boulder/errors"
1315 "github.com/letsencrypt/boulder/iana"
1416 "github.com/letsencrypt/boulder/policy"
1517 rl "github.com/letsencrypt/boulder/ratelimits"
1618 "github.com/letsencrypt/boulder/sfe/forms"
1719 "github.com/letsencrypt/boulder/sfe/zendesk"
20+ "github.com/letsencrypt/boulder/web"
1821)
1922
2023const (
@@ -556,7 +559,54 @@ type overrideRequest struct {
556559// either the form logic is flawed or the requester has bypassed the form and
557560// submitting (malformed) requests directly to this endpoint.
558561func (sfe * SelfServiceFrontEndImpl ) submitOverrideRequestHandler (w http.ResponseWriter , r * http.Request ) {
559- // TODO(#8359): Check per-IP rate limits for this endpoint.
562+ var refundLimits func ()
563+ var submissionSuccess bool
564+ if sfe .limiter != nil && sfe .txnBuilder != nil {
565+ requesterIP , err := web .ExtractRequesterIP (r )
566+ if err != nil {
567+ sfe .log .Errf ("determining requester IP address: %s" , err )
568+ http .Error (w , "failed to determine the IP address of the requester" , http .StatusInternalServerError )
569+ return
570+ }
571+
572+ txns , err := sfe .txnBuilder .LimitOverrideRequestsPerIPAddressTransaction (requesterIP )
573+ if err != nil {
574+ sfe .log .Errf ("building transaction for override request form limits: %s" , err )
575+ http .Error (w , "failed to build transaction for override request form limits" , http .StatusInternalServerError )
576+ return
577+ }
578+
579+ d , err := sfe .limiter .Spend (r .Context (), txns )
580+ if err != nil {
581+ sfe .log .Errf ("spending transaction for override request form limits: %s" , err )
582+ http .Error (w , "failed to spend transaction for override request form limits" , http .StatusInternalServerError )
583+ return
584+ }
585+
586+ err = d .Result (sfe .clk .Now ())
587+ if err != nil {
588+ var bErr * berrors.BoulderError
589+ if errors .As (err , & bErr ) && bErr .Type == berrors .RateLimit {
590+ http .Error (w , bErr .Detail , http .StatusTooManyRequests )
591+ return
592+ }
593+ sfe .log .Errf ("determining result of override request form limits transaction: %s" , err )
594+ http .Error (w , "failed to determine result of override request form limits transaction" , http .StatusInternalServerError )
595+ return
596+ }
597+
598+ refundLimits = func () {
599+ _ , err := sfe .limiter .Refund (r .Context (), txns )
600+ if err != nil {
601+ sfe .log .Errf ("refunding transaction for override request form limits: %s" , err )
602+ }
603+ }
604+ }
605+ defer func () {
606+ if ! submissionSuccess && refundLimits != nil {
607+ refundLimits ()
608+ }
609+ }()
560610
561611 var req overrideRequest
562612 err := json .NewDecoder (http .MaxBytesReader (w , r .Body , submitOverrideRequestBodyLimit )).Decode (& req )
@@ -710,5 +760,6 @@ func (sfe *SelfServiceFrontEndImpl) submitOverrideRequestHandler(w http.Response
710760 // TODO(#8362): If FundraisingFieldName value is true, use the Salesforce
711761 // API to create a new Lead record with the provided information.
712762
763+ submissionSuccess = true
713764 w .WriteHeader (http .StatusOK )
714765}
0 commit comments