Skip to content

Commit 2c4de2a

Browse files
committed
proxy: add skip invoice creation param
1 parent 324c27d commit 2c4de2a

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

proxy/service.go

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ type Service struct {
103103
// /package_name.ServiceName/MethodName
104104
AuthWhitelistPaths []string `long:"authwhitelistpaths" description:"List of regular expressions for paths that don't require authentication'"`
105105

106+
// AuthSkipInvoiceCreationPaths is an optional list of regular
107+
// expressions that are matched against the path of the URL of a
108+
// request. If the request URL matches any of those regular
109+
// expressions, the call will not try to create an invoice for the
110+
// request, but still try to do the l402 authentication.
111+
AuthSkipInvoiceCreationPaths []string `long:"authskipinvoicecreationpaths" description:"List of regular expressions for paths that will skip invoice creation'"`
112+
106113
// compiledHostRegexp is the compiled host regex.
107114
compiledHostRegexp *regexp.Regexp
108115

@@ -112,6 +119,10 @@ type Service struct {
112119
// compiledAuthWhitelistPaths is the compiled auth whitelist paths.
113120
compiledAuthWhitelistPaths []*regexp.Regexp
114121

122+
// compiledAuthSkipInvoiceCreationPaths is the compiled auth skip
123+
// invoice creation paths.
124+
compiledAuthSkipInvoiceCreationPaths []*regexp.Regexp
125+
115126
freebieDB freebie.DB
116127
pricer pricer.Pricer
117128
}
@@ -144,6 +155,20 @@ func (s *Service) AuthRequired(r *http.Request) auth.Level {
144155
return s.Auth
145156
}
146157

158+
// SkipInvoiceCreation determines if an invoice should be created for a
159+
// given request.
160+
func (s *Service) SkipInvoiceCreation(r *http.Request) bool {
161+
for _, pathRegexp := range s.compiledAuthSkipInvoiceCreationPaths {
162+
if pathRegexp.MatchString(r.URL.Path) {
163+
log.Tracef("Req path [%s] matches skip entry "+
164+
"[%s].", r.URL.Path, pathRegexp)
165+
return true
166+
}
167+
}
168+
169+
return false
170+
}
171+
147172
// prepareServices prepares the backend service configurations to be used by the
148173
// proxy.
149174
func prepareServices(services []*Service) error {
@@ -195,7 +220,7 @@ func prepareServices(services []*Service) error {
195220
// Compile the host regex.
196221
compiledHostRegexp, err := regexp.Compile(service.HostRegexp)
197222
if err != nil {
198-
return fmt.Errorf("error compiling host regex: %v", err)
223+
return fmt.Errorf("error compiling host regex: %w", err)
199224
}
200225
service.compiledHostRegexp = compiledHostRegexp
201226

@@ -206,7 +231,7 @@ func prepareServices(services []*Service) error {
206231
)
207232
if err != nil {
208233
return fmt.Errorf("error compiling path "+
209-
"regex: %v", err)
234+
"regex: %w", err)
210235
}
211236
service.compiledPathRegexp = compiledPathRegexp
212237
}
@@ -222,13 +247,34 @@ func prepareServices(services []*Service) error {
222247
regExp, err := regexp.Compile(entry)
223248
if err != nil {
224249
return fmt.Errorf("error validating auth "+
225-
"whitelist: %v", err)
250+
"whitelist: %w", err)
226251
}
227252
service.compiledAuthWhitelistPaths = append(
228253
service.compiledAuthWhitelistPaths, regExp,
229254
)
230255
}
231256

257+
service.compiledAuthSkipInvoiceCreationPaths = make(
258+
[]*regexp.Regexp, 0, len(
259+
service.AuthSkipInvoiceCreationPaths,
260+
),
261+
)
262+
263+
// Make sure all skip invoice creation regular expression
264+
// entries actually compile so we run into an eventual panic
265+
// during startup and not only when the request happens.
266+
for _, entry := range service.AuthSkipInvoiceCreationPaths {
267+
regExp, err := regexp.Compile(entry)
268+
if err != nil {
269+
return fmt.Errorf("error validating skip "+
270+
"invoice creation whitelist: %w", err)
271+
}
272+
service.compiledAuthSkipInvoiceCreationPaths = append(
273+
service.compiledAuthSkipInvoiceCreationPaths,
274+
regExp,
275+
)
276+
}
277+
232278
// If dynamic prices are enabled then use the provided
233279
// DynamicPrice options to initialise a gRPC backed
234280
// pricer client.

sample-conf.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ services:
151151
# dynamicprice.enabled is set to true.
152152
price: 0
153153

154+
# A list of regular expressions for path that are free of charge.
155+
authwhitelistpaths:
156+
- '^/freebieservice.*$'
157+
158+
# A list of regular expressions for path that will skip invoice creation,
159+
# but still try to do the l402 authentication. This is useful for streaming
160+
# services, as they are not supported to be the initial request to receive
161+
# a L402.
162+
authskipinvoicecreationpaths:
163+
- '^/streamingservice.*$'
164+
154165
# Options to use for connection to the price serving gRPC server.
155166
dynamicprice:
156167
# Whether or not a gRPC server is available to query price data from. If

0 commit comments

Comments
 (0)